背景

  • 需要收集git仓库信息到数据库供前端展示

    • 包括:仓库信息、仓库所有者、成员列表、提交信息、活跃情况等
  • 需要定时启动、灵活触发

实现简介

  • 使用gitlab v4 restful 接口
  • 使用python-gitlab 依赖库(pyapi-gitlab 不支持gitlab 10.0+ 版本,故弃用)
  • 使用flask 提供接口,远程灵活触发
  • 使用requests 完成数据汇报与接口访问(因频率不高,性能优化相关暂不考虑)
  • 使用datetime/dateutil 完成gitlab 的时间信息向mysql datatime转化
  • 外层使用docker进行封装与部署

api使用

  • projects


class GitProjectEntry(CCInterfaceHandler):
def __init__(self, _project):
super(GitProjectEntry, self).__init__()
self.logger = logger
self.project = _project
self.attribute = self.project.attributes
self.logger.debug("parse project name : {PROJECT_NAME} with id : {PROJECT_ID}.".format(
PROJECT_NAME = self._self_attribute_get("name"),
PROJECT_ID = self.project.get_id()
)) # id, name, description, owner, web_url, last_activity_at, created_at, num_commits, member_list
self.KEY_ID = "id"
self.KEY_NAME = "name"
self.KEY_DESCRIPTION = "description" self.KEY_OWNER = "owner"
self.KEY_OWNER_WEB_URL = "owner_web_url" self.KEY_LAST_ACTIVITY_AT = "last_activity_at"
self.KEY_CREATED_AT = "created_at"
self.KEY_ACTIVE_STATUS = "status" self.KEY_NAMESPACE_PATH = "namespace_path"
self.KEY_NAMESPACE_WEB_URL = "namespace_web_url" self.KEY_MEMBER_USERNAME_LIST = "member_username_list" self.KEY_WEB_URL = "web_url"
self.KEY_HTTP_URL_TO_REPO = "http_url_to_repo"
self.logger.debug(str(self._self_init())) def _date_formatter(self, _git_date_stamp_str):
try:
return date_parser.parse(_git_date_stamp_str).strftime(database_datefmt)
except Exception,e:
self.logger.warn("date stamp convert failed. with {INNER_GIT_STAMP}".format(INNER_GIT_STAMP = _git_date_stamp_str)) def _git_status_active_judge(self, _git_last_active_at_dt):
# status 1 活跃,0不活跃
KEY_STATUS_ACTIVE = 1
KEY_STATUS_INACTIVE = 0 today=datetime.datetime.today()
month_time_delta=datetime.timedelta(days = 30, hours=1)
activity_threshold = today - month_time_delta
activity_status = KEY_STATUS_ACTIVE if(
date_parser.parse(_git_last_active_at_dt) > activity_threshold) else KEY_STATUS_INACTIVE
return activity_status def _self_init(self): self.member_list = []
self.guess_owner = None self.last_activity_at = self._date_formatter(self._self_attribute_get("last_activity_at")) self.data = { self.KEY_ID : self.project.get_id(), # self.project.id
self.KEY_NAME : self._self_attribute_get("name"), # self.project.name
self.KEY_DESCRIPTION : self._self_attribute_get("description"), self.KEY_OWNER : self._self_attribute_get("owner", {}).get("username"),
self.KEY_OWNER_WEB_URL : self._self_attribute_get("owner", {}).get("web_url"), self.KEY_LAST_ACTIVITY_AT : self.last_activity_at,
self.KEY_CREATED_AT : self._date_formatter(self._self_attribute_get("created_at")),
self.KEY_ACTIVE_STATUS : self._git_status_active_judge(self.last_activity_at), self.KEY_NAMESPACE_PATH : self._self_attribute_get("namespace", {}).get("path"),
self.KEY_NAMESPACE_WEB_URL : self._self_attribute_get("namespace", {}).get("web_url"), self.KEY_MEMBER_USERNAME_LIST : self._self_member_username_list(), self.KEY_WEB_URL : self._self_attribute_get("web_url"),
self.KEY_HTTP_URL_TO_REPO : self._self_attribute_get("description") } if(self.data.get(self.KEY_OWNER) == None):
self.data[self.KEY_OWNER] = self._self_member_top_access_user_name() if(self.data.get(self.KEY_OWNER_WEB_URL) == None):
self.data[self.KEY_OWNER_WEB_URL] = self._self_member_top_access_user_name() self.git_project_member_report(self.project.get_id(),self.member_list)
if('200' != str(self.git_project_report(self.data))):
self.logger.warn("reported git_project failed! with project_id : {PR_ID} and project_name : {PR_NAME} .\n"
"while data is {PR_DATA}".format(PR_ID = str(self.data.get(self.KEY_ID, "NULL_ID")),
PR_NAME = str(self.data.get(self.KEY_NAME, "NULL_NAME")),
PR_DATA = str(self.data)
)
)
else:
self.logger.info("reported git_project succeed! with project_id : {PR_ID} and project_name : {PR_NAME} .\n"
"while data is {PR_DATA}".format(PR_ID = str(self.data.get(self.KEY_ID, "NULL_ID")),
PR_NAME = str(self.data.get(self.KEY_NAME, "NULL_NAME")),
PR_DATA = str(self.data)
)
)
return self.data def _self_member_list(self):
if(self.member_list != None and len(self.member_list) > 0):
return self.member_list
self.member_list = self.project.members.list(all=True)
if(len(self.member_list)<1):
self.member_list = self.project.members.all(all=True)
return self.member_list def _self_member_top_access_user(self):
if(not self.guess_owner):
self.member_list = self._self_member_list()
self.sorted_member_list = sorted(self.member_list,key=lambda x : x.attributes.get("access_level",0),reverse=True)
self.guess_owner = self.sorted_member_list[0] if(len(self.sorted_member_list) > 0) else None
return self.guess_owner def _self_member_top_access_user_weburl(self):
self.guess_owner = self._self_member_top_access_user()
self.top_access_username = self.guess_owner.attributes.get("web_url", None) if(self.guess_owner) else None
return self.top_access_username def _self_member_top_access_user_name(self):
self.guess_owner = self._self_member_top_access_user()
self.top_access_username = self.guess_owner.attributes.get("username", None) if(self.guess_owner) else None
return self.top_access_username def _self_member_username_list(self):
'''
gitlab document:
Examples
List the project members: members = project.members.list()
List the project members recursively (including inherited members through ancestor groups): members = project.members.all(all=True)
Search project members matching a query string: members = project.members.list(query='bar')
Get a single project member: member = project.members.get(user_id)
Add a project member: member = project.members.create({'user_id': user.id, 'access_level':
gitlab.DEVELOPER_ACCESS})
Modify a project member (change the access level): member.access_level = gitlab.MAINTAINER_ACCESS
member.save()
Remove a member from the project team: project.members.delete(user.id)
# or
member.delete()
Share/unshare the project with a group: project.share(group.id, gitlab.DEVELOPER_ACCESS)
project.unshare(group.id)
:return:
'''
self.member_username_list = [
member.attributes.get("username") for member in self._self_member_list()
]
return self.member_username_list def _self_attribute_get(self, _key, _default_value = ""):
return self.attribute.get(_key, _default_value) def to_json(self):
self.json_string = json.dumps(self.data)
return self.json_string
  • members
    def _self_member_username_list(self):
'''
gitlab document:
Examples
List the project members: members = project.members.list()
List the project members recursively (including inherited members through ancestor groups): members = project.members.all(all=True)
Search project members matching a query string: members = project.members.list(query='bar')
Get a single project member: member = project.members.get(user_id)
Add a project member: member = project.members.create({'user_id': user.id, 'access_level':
gitlab.DEVELOPER_ACCESS})
Modify a project member (change the access level): member.access_level = gitlab.MAINTAINER_ACCESS
member.save()
Remove a member from the project team: project.members.delete(user.id)
# or
member.delete()
Share/unshare the project with a group: project.share(group.id, gitlab.DEVELOPER_ACCESS)
project.unshare(group.id)
:return:
'''
self.member_username_list = [
member.attributes.get("username") for member in self._self_member_list()
]
return self.member_username_list
  • users
In [260]: user.attributes
Out[260]:
{u'access_level': 50,
u'avatar_url': None,
u'expires_at': None,
u'id': 224,
u'name': u'mosaic',
'project_id': 18915,
u'state': u'active',
u'username': u'mosaic',
u'web_url': u'http://git.intra.mosaic.com/mosaic'}

完整代码

  • 新增http连接池
# !/usr/bin/python
# -*- coding: UTF-8 -*-
__author__ = 'enzhao'
# Created by enzhao on 2020/5/25. # -*- coding: utf-8 -*-
import gitlab
from gitlab.v4 import objects as git_const
import json
import logging
from logging.handlers import RotatingFileHandler
# fh = RotatingFileHandler(filename, maxBytes=1024, backupCount=5) import datetime
from dateutil import parser as date_parser
import time
from functools import wraps from flask import Flask
import requests from gitlab.v4.objects import Project import sys
reload(sys)
sys.setdefaultencoding("utf-8") app = Flask(__name__) RESPONSE_SUCCESS_CODE = 200
RESPONSE_FAILED_CODE = 500
RESPONSE_SUCCESS_MESSAGE = "success"
RESPONSE_RESULT_KEY = "result"
RESPONSE_CODE_KEY = "code"
RESPONSE_MESSAGE_KEY = "message"
RESPONSE_PARAMS_KEY = "params"
RESPONSE_DICT_TEMPLATE = {
RESPONSE_RESULT_KEY : {},
RESPONSE_CODE_KEY : RESPONSE_SUCCESS_CODE,
RESPONSE_MESSAGE_KEY : RESPONSE_SUCCESS_MESSAGE,
RESPONSE_PARAMS_KEY : {}
} logger_file_suffix = time.strftime('%Y-%m-%d', time.localtime( float( time.time() )))
logger_file_name = "./waic-gitlab-info-retrive.log"
logger_file_name = "".join(["./develop-python-gitlab/host-py-source/waic-gitlab-info-retrive-", logger_file_suffix, ".log"])
# logger_file_name = "./waic-gitlab-info-retrive.log" logger_time_fmt = '%Y/%m/%d %H:%M:%S %A'
datefmt='%Y-%m-%d %H:%M:%S@%A'
database_datefmt = "%Y-%m-%d %H:%M:%S"
git_datefmt = "%Y-%m-%d %H:%M:%S" CC_HOST = "http://10.73.13.163"
# CC_HOST = "http://controlcenter.ds.sina.com.cn" def get_local_ip():
local_ip = ''
try:
import socket
socket_objs = [socket.socket(socket.AF_INET, socket.SOCK_DGRAM)]
ip_from_ip_port = [(s.connect(('8.8.8.8', 53)), s.getsockname()[0], s.close()) for s in socket_objs][0][1]
ip_from_host_name = [ip for ip in socket.gethostbyname_ex(socket.gethostname())[2] if not ip.startswith('127.')][:1]
local_ip = [l for l in (ip_from_ip_port, ip_from_host_name) if l][0]
except (Exception),e:
print('get_local_ip found exception : %s' % e)
return local_ip if('' != local_ip and None != local_ip) else socket.gethostbyname(socket.gethostname()) def result_decorator(_func_obj):
@wraps(_func_obj)
def wrapTheFunction(*args, **kwargs):
receive_time = time.time()
# RESPONSE_DICT = RESPONSE_DICT_TEMPLATE.copy()
RESPONSE_DICT = {
RESPONSE_RESULT_KEY : {},
RESPONSE_CODE_KEY : RESPONSE_SUCCESS_CODE,
RESPONSE_MESSAGE_KEY : RESPONSE_SUCCESS_MESSAGE,
RESPONSE_PARAMS_KEY : {}
}
RESPONSE_DICT[RESPONSE_RESULT_KEY]["server_ip"] = get_local_ip()
RESPONSE_DICT[RESPONSE_RESULT_KEY]["time"] = time.strftime(datefmt,time.localtime())
result_dict = {}
try:
result_dict = _func_obj(*args, **kwargs)
except Exception,e:
finish_time = time.time()
RESPONSE_DICT[RESPONSE_RESULT_KEY]["duration"] = str(finish_time - receive_time) + "ms"
RESPONSE_DICT[RESPONSE_PARAMS_KEY].update(**kwargs)
RESPONSE_DICT[RESPONSE_CODE_KEY] = RESPONSE_FAILED_CODE
RESPONSE_DICT[RESPONSE_MESSAGE_KEY] = e.message
return json.dumps(RESPONSE_DICT)
RESPONSE_DICT[RESPONSE_RESULT_KEY].update(result_dict)
RESPONSE_DICT[RESPONSE_PARAMS_KEY].update(**kwargs)
finish_time = time.time()
RESPONSE_DICT[RESPONSE_RESULT_KEY]["duration"] = str(finish_time - receive_time) + "ms"
RESPONSE_DICT[RESPONSE_CODE_KEY] = RESPONSE_SUCCESS_CODE
RESPONSE_DICT[RESPONSE_MESSAGE_KEY] = RESPONSE_SUCCESS_MESSAGE
return json.dumps(RESPONSE_DICT)
return wrapTheFunction def wei_logger(_cls_name = "logger_helper",
_log_level = logging.INFO):# !/usr/bin/python
_format_str = '[%(levelname)s] : %(asctime)s %(filename)s[line:%(lineno)d] %(message)s'
logging.basicConfig(level=logging.DEBUG,
format=_format_str,
filename=logger_file_name,
datefmt=logger_time_fmt) console = logging.StreamHandler()
console.setLevel(logging.INFO)
console_formatter = logging.Formatter(_format_str)
console.setFormatter(console_formatter) rotating_file_handler = RotatingFileHandler(logger_file_name, maxBytes=1024 * 1024 * 50, backupCount=5)
rotating_file_handler.setLevel(logging.DEBUG)
rotating_file_handler.setFormatter(console_formatter) logger = logging.getLogger(_cls_name)
logger.addHandler(console)
logger.addHandler(rotating_file_handler)
logger.debug('%s logger init success!!' % _cls_name)
return logger logger = wei_logger("GitManageEntry") def get_http_session(pool_connections=1, pool_maxsize=10, max_retries=3):
'''
http连接池
pool_connections 要缓存的 urllib3 连接池的数量。
pool_maxsize 要保存在池中的最大连接数。
max_retries 每个连接的最大重试次数
'''
session =requests.session()
# 创建适配器
adapter = requests.adapters.HTTPAdapter(pool_connections=pool_connections,
pool_maxsize=pool_maxsize, max_retries=max_retries)
session.mount('http://', adapter)
session.mount('https://', adapter)
return session session = get_http_session() class CCInterfaceHandler(object):
def __init__(self):
self.cc_host = CC_HOST
self.url_sep = "/"
self.git_project_query_url = "waic/v1/data/git_project"
self.git_project_add_url = "waic/v1/data/git_project/add"
self.git_project_update_url = "waic/v1/data/git_project/update"
self.git_project_member_query_url = "waic/v1/data/git_project_member"
self.git_project_member_add_url = "waic/v1/data/git_project_member/add"
self.git_project_member_update_url = "waic/v1/data/git_project_member/update"
self.interface_git_project_query = self.url_sep.join([self.cc_host, self.git_project_query_url ])
self.interface_git_project_add = self.url_sep.join([self.cc_host, self.git_project_add_url ])
self.interface_git_project_update = self.url_sep.join([self.cc_host, self.git_project_update_url ])
self.interface_git_project_member_query = self.url_sep.join([self.cc_host, self.git_project_member_query_url])
self.interface_git_project_member_add = self.url_sep.join([self.cc_host, self.git_project_member_add_url ])
self.interface_git_project_member_update = self.url_sep.join([self.cc_host, self.git_project_member_update_url ])
self.response_format_param = {"responseFormat" : "json"}
self.role_mapping = {
git_const.ACCESS_GUEST : "guest",
git_const.ACCESS_REPORTER : "reporter",
git_const.ACCESS_DEVELOPER : "developer",
git_const.ACCESS_MASTER : "master",
git_const.ACCESS_OWNER : "owner",
} def get_value(self, _key_path = "cluster.json.weibox_path", _dict = {}):
if(_dict == None):
return ""
tmp_obj = _dict.get(_key_path)
if(tmp_obj == None):
point_idx = _key_path.find(".")
if(point_idx < 0):
return ""
tail_dict = _dict.get(_key_path[0:point_idx])
if(isinstance(tail_dict,list)):
tail_dict = tail_dict[0] if len(tail_dict)>0 else None
tmp_obj = self.get_value(_key_path[point_idx+1:], tail_dict)
return tmp_obj def _git_project_report_interface(self, _id):
self.cc_project_count = 0
try:
self.id_param = self.response_format_param.copy()
self.id_param.update({"id" : _id})
r = session.get(self.interface_git_project_query, params = self.id_param)
self.cc_project_count = self.get_value("result.totalCount",r.json())
except Exception,e:
logger.warn(str(e) + e.message)
return self.interface_git_project_update if(self.cc_project_count > 0) else self.interface_git_project_add def git_project_report(self, _project_data = {}):
self.id = _project_data.get("id")
try:
self.interface_git_project_report = self._git_project_report_interface(_id=self.id)
self.report_param = self.response_format_param.copy()
self.report_param.update(_project_data)
r = session.post(self.interface_git_project_report, self.report_param)
return self.get_value("code",r.json())
except Exception,e:
logger.warn(str(e) + e.message) def _git_project_member_query(self, _id):
try:
self.id_param = self.response_format_param.copy()
self.id_param.update({"id" : _id})
r = session.get(self.interface_git_project_member_query, params = self.id_param)
self.cc_project_member = self.get_value("result.data",r.json())
self.cc_project_member_username_set = set([
user_dict.get("user_id", "") for user_dict in self.cc_project_member
])
return self.cc_project_member_username_set
except Exception,e:
logger.warn(str(e) + e.message) def _git_project_member_report_interface(self, _project_id, _user_id):
self.cc_project_member_count = 0
try:
self.id_param = self.response_format_param.copy()
self.id_param.update({"project_id" : _project_id, "user_id" : _user_id})
r = session.get(self.interface_git_project_member_query, params = self.id_param)
self.cc_project_count = self.get_value("result.totalCount",r.json())
except Exception,e:
logger.warn(str(e) + e.message)
return self.interface_git_project_member_update if(self.cc_project_count > 0) else self.interface_git_project_member_add def git_project_member_report(self, _project_id, _project_member_data = []):
self.id = _project_id
try:
for project_user in _project_member_data:
cc_project_user_role = self.role_mapping.get(project_user.attributes.get("access_level",git_const.ACCESS_DEVELOPER))
cc_project_user_id = project_user.attributes.get("username")
cc_project_member_id = "".join([str(_project_id), "0", str(project_user.attributes.get("id"))])
self.interface_git_project_member_report = self._git_project_member_report_interface(
_project_id=_project_id, _user_id=cc_project_user_id)
self.id_param = self.response_format_param.copy()
self.id_param.update({
"id" : cc_project_member_id,
"project_id" : _project_id,
"user_id" : cc_project_user_id,
"role" : cc_project_user_role
})
r = session.post(self.interface_git_project_member_report, self.id_param) except Exception,e:
logger.warn(str(e) + e.message) class GitProjectEntry(CCInterfaceHandler):
def __init__(self, _project):
super(GitProjectEntry, self).__init__()
self.logger = logger
self.project = _project
self.attribute = self.project.attributes
self.logger.debug("parse project name : {PROJECT_NAME} with id : {PROJECT_ID}.".format(
PROJECT_NAME = self._self_attribute_get("name"),
PROJECT_ID = self.project.get_id()
)) # id, name, description, owner, web_url, last_activity_at, created_at, num_commits, member_list
self.KEY_ID = "id"
self.KEY_NAME = "name"
self.KEY_DESCRIPTION = "description" self.KEY_OWNER = "owner"
self.KEY_OWNER_WEB_URL = "owner_web_url" self.KEY_LAST_ACTIVITY_AT = "last_activity_at"
self.KEY_CREATED_AT = "created_at"
self.KEY_ACTIVE_STATUS = "status" self.KEY_NAMESPACE_PATH = "namespace_path"
self.KEY_NAMESPACE_WEB_URL = "namespace_web_url" self.KEY_MEMBER_USERNAME_LIST = "member_username_list" self.KEY_WEB_URL = "web_url"
self.KEY_HTTP_URL_TO_REPO = "http_url_to_repo"
self.logger.debug(str(self._self_init())) def _date_formatter(self, _git_date_stamp_str):
try:
return date_parser.parse(_git_date_stamp_str).strftime(database_datefmt)
except Exception,e:
self.logger.warn("date stamp convert failed. with {INNER_GIT_STAMP}".format(INNER_GIT_STAMP = _git_date_stamp_str)) def _git_status_active_judge(self, _git_last_active_at_dt):
# status 1 活跃,0不活跃
KEY_STATUS_ACTIVE = 1
KEY_STATUS_INACTIVE = 0 today=datetime.datetime.today()
month_time_delta=datetime.timedelta(days = 30, hours=1)
activity_threshold = today - month_time_delta
activity_status = KEY_STATUS_ACTIVE if(
date_parser.parse(_git_last_active_at_dt) > activity_threshold) else KEY_STATUS_INACTIVE
return activity_status def _self_init(self): self.member_list = []
self.guess_owner = None self.last_activity_at = self._date_formatter(self._self_attribute_get("last_activity_at")) self.data = { self.KEY_ID : self.project.get_id(), # self.project.id
self.KEY_NAME : self._self_attribute_get("name"), # self.project.name
self.KEY_DESCRIPTION : self._self_attribute_get("description"), self.KEY_OWNER : self._self_attribute_get("owner", {}).get("username"),
self.KEY_OWNER_WEB_URL : self._self_attribute_get("owner", {}).get("web_url"), self.KEY_LAST_ACTIVITY_AT : self.last_activity_at,
self.KEY_CREATED_AT : self._date_formatter(self._self_attribute_get("created_at")),
self.KEY_ACTIVE_STATUS : self._git_status_active_judge(self.last_activity_at), self.KEY_NAMESPACE_PATH : self._self_attribute_get("namespace", {}).get("path"),
self.KEY_NAMESPACE_WEB_URL : self._self_attribute_get("namespace", {}).get("web_url"), self.KEY_MEMBER_USERNAME_LIST : self._self_member_username_list(), self.KEY_WEB_URL : self._self_attribute_get("web_url"),
self.KEY_HTTP_URL_TO_REPO : self._self_attribute_get("description") } if(self.data.get(self.KEY_OWNER) == None):
self.data[self.KEY_OWNER] = self._self_member_top_access_user_name() if(self.data.get(self.KEY_OWNER_WEB_URL) == None):
self.data[self.KEY_OWNER_WEB_URL] = self._self_member_top_access_user_name() self.git_project_member_report(self.project.get_id(),self.member_list)
if('200' != str(self.git_project_report(self.data))):
self.logger.warn("reported git_project failed! with project_id : {PR_ID} and project_name : {PR_NAME} .\n"
"while data is {PR_DATA}".format(PR_ID = str(self.data.get(self.KEY_ID, "NULL_ID")),
PR_NAME = str(self.data.get(self.KEY_NAME, "NULL_NAME")),
PR_DATA = str(self.data)
)
)
else:
self.logger.info("reported git_project succeed! with project_id : {PR_ID} and project_name : {PR_NAME} .\n"
"while data is {PR_DATA}".format(PR_ID = str(self.data.get(self.KEY_ID, "NULL_ID")),
PR_NAME = str(self.data.get(self.KEY_NAME, "NULL_NAME")),
PR_DATA = str(self.data)
)
)
return self.data def _self_member_list(self):
if(self.member_list != None and len(self.member_list) > 0):
return self.member_list
self.member_list = self.project.members.list(all=True)
if(len(self.member_list)<1):
self.member_list = self.project.members.all(all=True)
return self.member_list def _self_member_top_access_user(self):
if(not self.guess_owner):
self.member_list = self._self_member_list()
self.sorted_member_list = sorted(self.member_list,key=lambda x : x.attributes.get("access_level",0),reverse=True)
self.guess_owner = self.sorted_member_list[0] if(len(self.sorted_member_list) > 0) else None
return self.guess_owner def _self_member_top_access_user_weburl(self):
self.guess_owner = self._self_member_top_access_user()
self.top_access_username = self.guess_owner.attributes.get("web_url", None) if(self.guess_owner) else None
return self.top_access_username def _self_member_top_access_user_name(self):
self.guess_owner = self._self_member_top_access_user()
self.top_access_username = self.guess_owner.attributes.get("username", None) if(self.guess_owner) else None
return self.top_access_username def _self_member_username_list(self):
'''
gitlab document:
Examples
List the project members: members = project.members.list()
List the project members recursively (including inherited members through ancestor groups): members = project.members.all(all=True)
Search project members matching a query string: members = project.members.list(query='bar')
Get a single project member: member = project.members.get(user_id)
Add a project member: member = project.members.create({'user_id': user.id, 'access_level':
gitlab.DEVELOPER_ACCESS})
Modify a project member (change the access level): member.access_level = gitlab.MAINTAINER_ACCESS
member.save()
Remove a member from the project team: project.members.delete(user.id)
# or
member.delete()
Share/unshare the project with a group: project.share(group.id, gitlab.DEVELOPER_ACCESS)
project.unshare(group.id)
:return:
'''
self.member_username_list = [
member.attributes.get("username") for member in self._self_member_list()
]
return self.member_username_list def _self_attribute_get(self, _key, _default_value = ""):
return self.attribute.get(_key, _default_value) def to_json(self):
self.json_string = json.dumps(self.data)
return self.json_string class GitManageEntry(object):
def __init__(self, _private_token, _fetch_all = False, _exclude_project = True, _visibility = git_const.VISIBILITY_PRIVATE):
'''
gitlab document:
The API provides several filtering parameters for the listing methods: archived: if True only archived projects will be returned
visibility: returns only projects with the specified visibility (can be public, internal or private)
search: returns project matching the given pattern
Results can also be sorted using the following parameters: order_by: sort using the given argument. Valid values are id, name, path, created_at, updated_at and last_activity_at. The default is to sort by created_at
sort: sort order (asc or desc)
# List all projects (default 20)
projects = gl.projects.list(all=True)
# Archived projects
projects = gl.projects.list(archived=1)
# Limit to projects with a defined visibility
projects = gl.projects.list(visibility='public') # List owned projects
projects = gl.projects.list(owned=True) # List starred projects
projects = gl.projects.list(starred=True) # Search projects
projects = gl.projects.list(search='keyword')
:param _private_token:
:param _fetch_all:
:param _exclude_project:
:param _visibility:
'''
self.url = "http://git.intra.weibo.com/"
self.private_token = _private_token
self.fetch_all = _fetch_all
self.exclude_project = _exclude_project
self.logger = logger
self.visibility = _visibility
self.git = gitlab.Gitlab(self.url, self.private_token)
self.git.auth()
self.username = self.git.user.username
self.user_id = self.git.user.id
self.logger_info = "parse private token for username : {USER_NAME} with id : {USER_ID}.".format(
USER_NAME = self.username,
USER_ID = self.user_id
)
print (self.logger_info)
self.logger.info(self.logger_info)
self.user_last_sign_in_at = self.git.user.last_sign_in_at
self.user_last_activity_on = self.git.user.last_activity_on self.logger.info("start retrieve git projects")
self.projects = self.git.projects.list(all=True, visibility = self.visibility) \
if(self.fetch_all) else \
self.git.projects.list(visibility = self.visibility)
self.logger.info("retrieve git projects done!") self.gpe = [GitProjectEntry(_project=project) for project in self.projects]
self.gpe_data = [_gpe.data for _gpe in self.gpe]
self.data = {
"url" : self.url ,
"private_token" : self.private_token ,
"username" : self.username ,
"user_id" : self.user_id ,
"user_last_sign_in_at" : self.user_last_sign_in_at ,
"user_last_activity_on" : self.user_last_activity_on,
"count_of_projects" : len(self.gpe)
} if(not self.exclude_project):
self.data.update({"projects" : self.gpe_data})
self.logger.debug(str(self.data)) def to_json(self):
self.json_string = json.dumps(self.data)
return self.json_string @app.route('/waic/git-retrieve/user-auth/<private_token>',methods = ['POST','GET'])
@result_decorator
def git_user_auth(private_token):
gme = GitManageEntry(_private_token=private_token)
return gme.data
# return gme.to_json() @app.route('/waic/git-retrieve/preview/<private_token>',methods = ['POST','GET'])
@result_decorator
def git_retrieve_preview(private_token):
gme = GitManageEntry(_private_token=private_token, _exclude_project=False)
return gme.data
# return gme.to_json() @app.route('/waic/git-retrieve/all/<private_token>',methods = ['POST','GET'])
@result_decorator
def git_retrieve_all_projects(private_token):
gme = GitManageEntry(_private_token=private_token, _fetch_all=True, _exclude_project=False)
return gme.data
# return gme.to_json() @app.route('/waic/git-retrieve/all-projects/<private_token>',methods = ['POST','GET'])
@result_decorator
def git_retrieve_all_internal_projects(private_token):
gme = GitManageEntry(_private_token=private_token, _visibility=git_const.VISIBILITY_INTERNAL, _fetch_all=True, _exclude_project=False)
return gme.data
# return gme.to_json() if __name__ == '__main__':
app.run(host=get_local_ip())
# job_state("12345678")
token = "anNN8srBMewKzvokyxaL"
# token = "yk-1v6J_txopP7x7xtif"
# gme = GitManageEntry(_private_token=token, _fetch_all=True, _exclude_project=False)
gme = GitManageEntry(_private_token=token, _exclude_project=False) code_stage = '''
# -*- coding: utf-8 -*-
import gitlab
from gitlab.v4.objects import Project
url = "http://git.intra.weibo.com/"
token = "fv29Z9seyCs7xRhYSUt8"
token = "anNN8srBMewKzvokyxaL"
gl = gitlab.Gitlab(url, token, per_page=50) projects = gl.projects.list(all=True) class GitManageEntry(Project):
def toJson(self): "url" : self.url ,
"private_token" : self.private_token ,
"git" : self.git ,
"username" : self.username ,
"user_id" : self.user_id ,
"user_last_sign_in_at" : self.user_last_sign_in_at ,
"user_last_activity_on" : self.user_last_activity_on , # 登录
gl = gitlab.Gitlab(url, token) # ---------------------------------------------------------------- #
# 获取第一页project
projects = gl.projects.list()
# 获取所有的project
projects = gl.projects.list(all=True)
# ---------------------------------------------------------------- # # ---------------------------------------------------------------- #
# 获取所有project的name,id
for p in gl.projects.list(all=True, as_list=False):
print(p.name, p.id)
# ---------------------------------------------------------------- # # ---------------------------------------------------------------- #
# 获取第一页project的name,id
for p in gl.projects.list(page=1):
print(p.name, p.id)
# ---------------------------------------------------------------- # # ---------------------------------------------------------------- #
# 通过指定id 获取 project 对象
project = gl.projects.get(501)
# ---------------------------------------------------------------- # # ---------------------------------------------------------------- #
# 查找项目
projects = gl.projects.list(search='keyword')
# ---------------------------------------------------------------- # # ---------------------------------------------------------------- #
# 创建一个项目
project = gl.projects.create({'name':'project1'})
# ---------------------------------------------------------------- # # ---------------------------------------------------------------- #
# 获取公开的项目
projects = gl.projects.list(visibility='public') # public, internal or private
# ---------------------------------------------------------------- # # 获取 project 对象是以下操作的基础 # ---------------------------------------------------------------- #
# 通过指定project对象获取该项目的所有分支
branches = project.branches.list()
print(branches)
# ---------------------------------------------------------------- # # ---------------------------------------------------------------- #
# 获取指定分支的属性
branch = project.branches.get('master')
print(branch)
# ---------------------------------------------------------------- # # ---------------------------------------------------------------- #
# 创建分支
branch = project.branches.create({'branch_name': 'feature1',
'ref': 'master'})
# ---------------------------------------------------------------- # # ---------------------------------------------------------------- #
# 删除分支
project.branches.delete('feature1')
# ---------------------------------------------------------------- # # ---------------------------------------------------------------- #
# 分支保护/取消保护
branch.protect()
branch.unprotect()
# ---------------------------------------------------------------- # # ---------------------------------------------------------------- #
# 获取指定项目的所有tags
tags = project.tags.list() # 获取某个指定tag 的信息
tags = project.tags.list('1.0') # 创建一个tag
tag = project.tags.create({'tag_name':'1.0', 'ref':'master'}) # 设置tags 说明:
tag.set_release_description('awesome v1.0 release') # 删除tags
project.tags.delete('1.0')
# or
tag.delete() # ---------------------------------------------------------------- #
# 获取所有commit info
commits = project.commits.list()
for c in commits:
print(c.author_name, c.message, c.title)
# ---------------------------------------------------------------- # # ---------------------------------------------------------------- #
# 获取指定commit的info
commit = project.commits.get('e3d5a71b')
# ---------------------------------------------------------------- # # ---------------------------------------------------------------- #
# 获取指定项目的所有merge request
mrs = project.mergerequests.list()
print(mrs)
# ---------------------------------------------------------------- # # ---------------------------------------------------------------- #
# 获取 指定mr info
mr = project.mergesession.get(mr_id)
# ---------------------------------------------------------------- # # ---------------------------------------------------------------- #
# 创建一个merge request
mr = project.mergerequests.create({'source_branch':'cool_feature',
'target_branch':'master',
'title':'merge cool feature', })
# ---------------------------------------------------------------- # # ---------------------------------------------------------------- #
# 更新一个merge request 的描述
mr.description = 'New description'
mr.save()
# ---------------------------------------------------------------- # # ---------------------------------------------------------------- #
# 开关一个merge request (close or reopen):
mr.state_event = 'close' # or 'reopen'
mr.save()
# ---------------------------------------------------------------- # # ---------------------------------------------------------------- #
# Delete a MR:
project.mergerequests.delete(mr_id)
# or
mr.delete()
# ---------------------------------------------------------------- # # ---------------------------------------------------------------- #
# Accept a MR:
mr.merge()
# ---------------------------------------------------------------- # # ---------------------------------------------------------------- #
# 指定条件过滤 所有的merge request
# state: state of the MR. It can be one of all, merged, opened or closed
# order_by: sort by created_at or updated_at
# sort: sort order (asc or desc)
mrs = project.mergerequests.list(state='merged', sort='asc') # all, merged, opened or closed
# ---------------------------------------------------------------- # # ---------------------------------------------------------------- #
# 创建一个commit
data = {
'branch_name': 'master', # v3
'commit_message': 'blah blah blah',
'actions': [
{
'action': 'create',
'file_path': 'blah',
'content': 'blah'
}
]
}
commit = project.commits.create(data)
# ---------------------------------------------------------------- # # ---------------------------------------------------------------- #
# Compare two branches, tags or commits:
result = project.repository_compare('develop', 'feature-20180104')
print(result)
# get the commits for commit in result['commits']:
print(commit)
#
# get the diffs
for file_diff in result['diffs']:
print(file_diff)
# ---------------------------------------------------------------- # # ---------------------------------------------------------------- #
# get the commits
for commit in result['commits']:
print(commit)
#
# get the diffs
for file_diff in result['diffs']:
print(file_diff)
# ---------------------------------------------------------------- # '''

python-gitlab 一个简单demo的更多相关文章

  1. 用Python写一个简单的Web框架

    一.概述 二.从demo_app开始 三.WSGI中的application 四.区分URL 五.重构 1.正则匹配URL 2.DRY 3.抽象出框架 六.参考 一.概述 在Python中,WSGI( ...

  2. 用Python编写一个简单的Http Server

    用Python编写一个简单的Http Server Python内置了支持HTTP协议的模块,我们可以用来开发单机版功能较少的Web服务器.Python支持该功能的实现模块是BaseFTTPServe ...

  3. python中一个简单的webserver

     python中一个简单的webserver 2013-02-24 15:37:49 分类: Python/Ruby 支持多线程的webserver   1 2 3 4 5 6 7 8 9 10 11 ...

  4. Python实现一个简单三层神经网络的搭建并测试

    python实现一个简单三层神经网络的搭建(有代码) 废话不多说了,直接步入正题,一个完整的神经网络一般由三层构成:输入层,隐藏层(可以有多层)和输出层.本文所构建的神经网络隐藏层只有一层.一个神经网 ...

  5. angular实现了一个简单demo,angular-weibo-favorites

    前面必须说一段 帮客户做了一个过渡期的项目,唯一的要求就是速度,我只是会点儿基础的php,于是就用tp帮客户做了这个项目.最近和客户架构沟通,后期想把项目重新做一下,就用现在最流行的技术,暂时想的使用 ...

  6. 用python实现一个简单的词云

    对于在windows(Pycharm工具)里实现一个简单的词云还是经过了几步小挫折,跟大家分享下,如果遇到类似问题可以参考: 1. 导入wordcloud包时候报错,当然很明显没有安装此包. 2. 安 ...

  7. python制作一个简单的中奖系统

    注释: 展示图下的代码,我是用pycharm写的,是python解释器中的一种,本课没不同解释器的要求,可根据自己喜欢的解释器编写. 步骤: 本期给大家带来的是,一个简单的中奖系统,首先打开自己电脑上 ...

  8. python 搭建一个简单的 搜索引擎

    我把代码和爬好的数据放在了git上,欢迎大家来参考 https://github.com/linyi0604/linyiSearcher 我是在 manjaro linux下做的, 使用python3 ...

  9. 使用Python制作一个简单的刷博器

    呵呵,不得不佩服Python的强大,寥寥几句代码就能做一个简单的刷博器. import webbrowser as web import time import os count=0 while co ...

  10. 在cengos中安装zabbix server/agent, 并创建一个简单demo

    添加zabbix更新源 rpm -ivh http://repo.zabbix.com/zabbix/2.4/rhel/6/x86_64/zabbix-release-2.4-1.el6.noarch ...

随机推荐

  1. Spring 之bean的生命周期

    文章目录 IOC Bean的生命周期 运行结果 实例演示 实体类 实例化前后置代码 初始化的前后置代码 application.xml 总结 今天我们来聊一下Spring Bean的生命周期,这是一个 ...

  2. 【解决方法】正常游览Flash页面,解决主流游览器的不支持问题(如Edge,Firefox)

    环境: 工具:360游览器-某特殊版本 系统版本:Windows 10 视频链接:[[解决方法]正常浏览flash页面,解决主流浏览器的不支持问题] https://www.bilibili.com/ ...

  3. OCR 文字检测(Differentiable Binarization --- DB)

    文本检测 基于分割的做法(如蓝色箭头所示): 传统的pipeline使用固定的阈值对于分割后的热力图进行二值化处理 首先,它们设置了固定的阈值,用于将分割网络生成的概率图转换为二进制图像 然后,用一些 ...

  4. 雪球 app 实战(1)

    开头 因为理论篇结束之后,需要一个实战,估选用了雪球app作为一个作业 业务场景: 雪球 app 自选设置(入口位于 行情 模块) 作业内容 使用 百度脑图 编写 思维导图 [自选设置]模块的测试用例 ...

  5. SSL 证书安装使用中遇到的常见问题

    为了实现网站HTTPS加密保护及身份的可信认证,防止传输数据的泄露或篡改,SSL证书已被各政企网站广泛应用.然而在部署和使用SSL证书的过程中,我们经常会遇到一些措手不及的问题,一旦处理不当,就会让网 ...

  6. CPU后面的字母含义

    M(Mobile):移动笔记本电脑标准电压,功耗小,适合笔记本,i5-4310M. U(Ultra Low Voltage):移动笔记本电脑超低电压,更小的功耗.如i5-8250U. H(Height ...

  7. Django date

    date根据给定格式对一个日期变量进行格式化. 可用的格式字符串: 格式化字符 描述 示例输出a 'a.m.'或'p.m.' 'a.m.'A 'AM'或'PM' 'AM'b 月份,文字形式,3个字母, ...

  8. jmeter如何保存变量到结果jtl文件里

    将变量保存到结果jtl文件里,可以方便的在generate报告时,自行取用jtl中的变量进行展示,实现过程如下: 1.打开jmeter/bin目录下的jmeter.properties文件,将变量名加 ...

  9. 源端为备库的场景下Duplicate失败问题

    环境: Oracle 11.2.0.3 + OEL 7.9 A -> B -> C 级联ADG环境:db11g -> db11gadg -> db11gcas 之前测试提到,从 ...

  10. Galaxy 生信平台(三):xlsx 上传与识别

    我在<Firefox Quantum 向左,Google Chrome 向右>中,曾经吐槽过在 Firefox 中使用 Galaxy 上传本地的 Excel 文件时,会出现 xlsx 无法 ...