-
Notifications
You must be signed in to change notification settings - Fork 1
/
main.py
196 lines (170 loc) · 9.13 KB
/
main.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
# #####################################################################################
# 脚本逻辑
# 首先在当前目录下创建一个临时目录,然后让用户授权Gitee和GitHub账号以获得账号中的所有Git仓库信息
# 最后使用 `git clone --mirror xxx` 命令克隆裸仓库,并使用 `git push --mirror xxx` 推送,
# 以达到转移仓库的目的
# #####################################################################################
# 脚本使用前置条件
# - 电脑上已安装Python,并且安装了下方import的Python库
# - 没有安装的话可以使用 `pip install <库名>` 进行安装
# - 建议先配置好pip国内镜像,再使用pip安装,这样安装速度会快一些
# - 电脑上已安装Git
# - 已经配置好本地SSH信息
# - 即可以直接使用git命令克隆或推送SSH地址git@git___.com:xxx.git
# - 特别是对于您的私有仓库,只有配置好了SSH公钥的情况下才能直接使用git命令完成克隆
# - 对于大多数在国内的用户,需要准备一个梯子,否则GitHub请求很容易超时,无法获取仓库信息
# - 如果GitHub不需要使用代理,请将下方 githubProxies 变量中的代理配置设置为空
# - 使用梯子请求的话,请将下方 githubProxies 变量中的代理配置设置为梯子的IP地址
# - 如果Git提示SSL验证失败,可以使用 `git config --global http.sslVerify false` 关闭SSL验证
# #####################################################################################
# 注意事项
# - 使用时,需要使用Gitee和GitHub进行授权
# - 使用前,请注意备份数据,虽然我们已经使用我们自己的账号测试脚本没有问题,
# 但受由于执行环境的不同,不排除脚本出现错误等情况。
# 若因脚本执行错误或者您的失误导致数据丢失,我们不承担责任,感谢您的理解!
# #####################################################################################
import os # 执行系统命令
import requests # 发送请求
import signal # 捕获Ctrl+C退出信号
import webbrowser # 打开浏览器
import time # 时间模块 (倒计时退出,创建带时间戳的工作目录)
import shutil # 文件夹操作 (递归删除文件夹)
import json # 读写JSON
import configparser # 读取ini配置文件
import copy # 字典深拷贝
# ######################################## 工作路径 ########################################
# 当前目录
CurrentDir = os.path.dirname(os.path.abspath(__file__))
# 临时工作目录
WorkingDirName = "WorkingDir" # './temp-' + str(int(time.time() * 10 ** 6))
WorkingDir = os.path.abspath(os.path.join(CurrentDir, WorkingDirName))
# 设置保存路径
GlobalVarsSavePath = os.path.abspath(os.path.join(WorkingDir, "GlobalVars.json"))
# 准备工作目录
from assets.prepareWorkingDir import prepareWorkingDir
prepareWorkingDir(CurrentDir = CurrentDir, WorkingDir = WorkingDir)
# ######################################## 读取配置 ########################################
# 读取配置文件
from assets.readConfigFile import readConfigFile
config = readConfigFile(os.path.abspath("config.ini"))
if not 'Gitee' in config or not 'GitHub' in config:
print("[error] 配置文件读取失败,请检查配置文件是否正确")
exit()
if not 'ClientID' in config['Gitee'] or not 'ClientSecret' in config['Gitee']:
print("[error] Gitee ClientID或ClientSecret配置错误,请检查配置文件是否正确")
exit()
if not 'ClientID' in config['GitHub'] or not 'ClientSecret' in config['GitHub']:
print("[error] GitHub ClientID或ClientSecret配置错误,请检查配置文件是否正确")
exit()
# ClientID 与 ClientSecret
# Gitee
GiteeClientID = config['Gitee']['ClientID']
GiteeClientSecret = config['Gitee']['ClientSecret']
# GitHub
GitHubClientID =config['GitHub']['ClientID']
GitHubClientSecret = config['GitHub']['ClientSecret']
# Protocol: https or ssh
GiteeProtocol = 'https'
GitHubProtocol = 'https'
# Gitee
if 'Protocol' in config['Gitee'] and config['Gitee']['Protocol'] == 'ssh':
GiteeProtocol = "ssh"
# GitHub
if 'Protocol' in config['GitHub'] and config['GitHub']['Protocol'] == 'ssh':
GitHubProtocol = "ssh"
# 代理
# Gitee请求代理,默认为不使用代理 { "http": None, "https": None }
giteeProxies = { "http": None, "https": None }
if 'Proxy' in config['Gitee'] and config['Gitee']['Proxy'] != "":
giteeProxies['http'] = config['Gitee']['Proxy']
giteeProxies['https'] = config['Gitee']['Proxy']
# GitHub请求代理,默认为使用本地代理 { "http": "127.0.0.1:15732", "https": "127.0.0.1:15732" }
# python3 requests使用proxy代理,cookies https://www.cnblogs.com/lshan/p/11878638.html
githubProxies = { "http": None, "https": None }
if 'Proxy' in config['GitHub'] and config['GitHub']['Proxy'] != "":
githubProxies['http'] = config['GitHub']['Proxy']
githubProxies['https'] = config['GitHub']['Proxy']
# 请求超时时间
timeout = 10
if 'RequestTimeout' in config['Common'] and config['Common']['RequestTimeout'].isdigit():
timeout = int(config['Common']['RequestTimeout'])
print("[info] 请求超时时间设置为:" + str(timeout) + "秒")
# ######################################## 主函数 ########################################
if __name__ == '__main__':
"""
主函数
"""
from assets.common import saveJSON, readJSON, fileExists
GlobalVars = {
'lastRunTime': time.time(),
'giteeRepos': {},
'githubRepos': {},
'RepoMatch': {},
}
# 如果存在之前的获取结果,则首先导入先前的结果
importFileOrNot = ''
if not fileExists(WorkingDir): # 如果工作目录不存在,那么不可导入
importFileOrNot = 'n'
if fileExists(GlobalVarsSavePath): # 如果JSON文件存在,那么询问用户否导入
while(importFileOrNot != 'y' and importFileOrNot != 'n'):
importFileOrNot = input("[info] 发现上次运行结果,是否读取?(y/n) 默认为y ")
if importFileOrNot == '':
importFileOrNot = 'y'
else: # 如果JSON文件不存在,那么不可导入
importFileOrNot = 'n'
if importFileOrNot == 'y': # 导入
# 读取上次的结果
GlobalVars = readJSON(GlobalVarsSavePath)
GlobalVars['RepoMatch'] = {}
print("[info] 导入JSON文件成功")
# 注册 Ctrl+C 退出处理程序
# from assets.defineWorkingDirCleanFunction import defineWorkingDirCleanFunction
# defineWorkingDirCleanFunction(saveJSONFunction = saveJSON)
# 询问用户是否重新获取Gitee仓库列表
if GlobalVars['giteeRepos']:
userInput = 'unknown'
while userInput != 'y' and userInput != 'n' and userInput != '':
userInput = input("[info] 已经获取过Gitee仓库列表,是否重新获取?(y/n) 默认为n ")
if userInput == 'y':
GlobalVars['giteeRepos'] = {} # 清空之前的记录
if not GlobalVars['giteeRepos']:
# 读取 Gitee 仓库列表
from assets.giteeOauth import giteeOauth
[GlobalVars['giteeReposOrigin'], GlobalVars['giteeRepos']] = \
giteeOauth(GiteeClientID = GiteeClientID, GiteeClientSecret = GiteeClientSecret, giteeProxies = giteeProxies, timeout = timeout)
print("[info] 获取到 {} 个Git仓库".format(len(GlobalVars['giteeRepos'])))
# 保存JSON文件
saveJSON(GlobalVars, GlobalVarsSavePath)
print("[info] 保存JSON文件完成")
# 询问用户是否重新获取Gitee仓库列表
if GlobalVars['githubRepos']:
userInput = 'unknown'
while userInput != 'y' and userInput != 'n' and userInput != '':
userInput = input("[info] 已经获取过GitHub仓库列表,是否重新获取?(y/n) 默认为n ")
if userInput == 'y':
GlobalVars['githubRepos'] = {} # 清空之前的记录
if not GlobalVars['githubRepos']:
# 读取 GitHub 仓库列表
from assets.githubOauth import githubOauth
[GlobalVars['githubReposOrigin'], GlobalVars['githubRepos']] = \
githubOauth(GitHubClientID = GitHubClientID, GitHubClientSecret = GitHubClientSecret, githubProxies = githubProxies, timeout = timeout)
print("[info] 获取到 {} 个Git仓库".format(len(GlobalVars['githubRepos'])))
# 保存JSON文件
saveJSON(GlobalVars, GlobalVarsSavePath)
print("[info] 保存JSON文件完成")
# 匹配仓库
from assets.repoMatching import repoMatching, printMatchintInfo
matchList = repoMatching(repo1 = GlobalVars['giteeRepos'], repo2 = GlobalVars['githubRepos'])
GlobalVars['RepoMatch'] = matchList
# 保存JSON文件
saveJSON(GlobalVars, GlobalVarsSavePath)
print("[info] 保存JSON文件完成")
# 打印匹配信息
printMatchintInfo(matchList, repo1Name = "Gitee", repo2Name = "GitHub")
# 转移仓库
input("[info] 确认无误后按回车继续: ")
print("[info] 开始同步仓库")
from assets.transferRepos import transferRepos
transferRepos(matchList.get('match'), WorkingDir, fromRepoProtocol = GiteeProtocol, toRepoProtocol = GitHubProtocol)
print("程序结束,将退出")
os.system("pause")