之前一直用简单的def函数形式写脚本,前段时间学习django的时候刚好将类复习了下,果然还是面向对象的编程比较好用,所以自己以后打算尽量都用类来练手写一些东西,以下是使用了父类和子类写的脚本。
# D:\Program Files (x86)\Python36
# -*- coding=utf-8 -*-
import gitlab, os
from pathlib import Path
class Login :
    def __init__(self, url, private_token, project_name) :
        self.url = url
        self.private_token = private_token
        self.project_name = project_name
    def stategl(self) :
        gl = gitlab.Gitlab(self.url, private_token=self.private_token)
        return gl
    def search(self) :
        projects = self.stategl().projects.list(search=self.project_name)
        # url = line.http_url_to_repo for line in projects if line.name == self.project_name
        for line in projects :
            if line.name == self.project_name :
                url = line.http_url_to_repo
                pid = line.id
                return url, pid
    def __str__(self) :
        return list(self.search())
class GitREPO(Login) :
    def __init__(self,  url, private_token, project_name) :
        super().__init__(url, private_token, project_name)
        
    def DOWNRepo(self,workdir, branch, repodir) :
        if not os.path.exists(workdir) :
            os.makedirs(workdir)
        project = self.stategl().projects.get(list(self.search())[1])
        branches = project.branches.list()
        fileList = project.repository_tree(path=repodir, ref=branch, recursive=True, all=True)
        for i in fileList :
            print(i)
            dirs = os.path.join(workdir, i['path'])
            if i['type'] == "tree" :
                print(dirs)
                if not os.path.exists(dirs) :
                    os.mkdir(dirs)
                    repodir = os.path.join(repodir, i['name'])
                    self.DOWNRepo(workdir, branch, repodir)
            elif i['type'] == "blob" :
                print(dirs)
                with open(dirs, 'wb') as f :
                    project.files.raw(file_path=i['path'], ref=branch, streamed=True, action=f.write)
                    print("%s" % dirs)
    #以下为提交代码到gitlab仓库的功能,我没加入到主程序中
    def COMMITCode(self, branch, workdir, filelist) :
        project = self.stategl().projects.get(list(self.search())[1])
        '''filelist为代码仓内部的相对路径,比如D:\REPO\JAVA1\JAVA2\est.java,这里仓库名称为JAVA1,那么filelist 就是 JAVA1\JAVA2\est.java'''
        filepath = os.path.join(workdir, filelist)  # 本机需要提交的文件的具体路径
        commitpaths = filepath.split(workdir)[1]  # 远程仓库的路径,以/开始作为远程仓库的路径
        data = {
            'branch' : branch,
            'commit_message' : 'update content',
            'actions' : [
                {
                    'action' : 'create',
                    'file_path' : commitpaths,
                    'content' : open(filepath, 'r', encoding='UTF-8').read(),
                },
            ]
        }
        commit = project.commits.create(data)
if __name__ == '__main__' :
    CUR_DIR = Path(__file__).resolve().parent  # Path(__file__).resolve())当前脚本的详细路径
    filepath = os.path.join(CUR_DIR, 'add-list.txt')  #将需要下载的服务写到里面
    url = 'http://10.80.99.35/'
    token = 'rwwrtttrteaRwwww'
    repodir = '/'     #远程仓库的根目录,即下载整个代码仓,如果带/file,就是下载代码仓中file目录下的文件
    branch = 'develop'   #指定下载的分支
    with open(filepath,'r',encoding='utf-8') as f:
        for line in f.readlines():
            reponame = line.strip()
            workdir = os.path.join(r'D:\Program Files\GitlabReposity', reponame)
            GitREPO(url, token, reponame).DOWNRepo(workdir, branch, repodir)
