背景
需要收集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({&#