-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathgithub_sync.py
More file actions
128 lines (106 loc) · 4.04 KB
/
github_sync.py
File metadata and controls
128 lines (106 loc) · 4.04 KB
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
import os , json
import requests
from github import Github, InputGitAuthor
import conf
import utils as u
dir_path = os.path.dirname(os.path.realpath(__file__))
# OAUTH APP
clientId = conf.gitClientID
clientSecret = conf.gitClientSecret
def is_git_auth():
""" Return True if the app requires github auth"""
u.reload_config()
return True if conf.gitClientID != "" else False
def ask_user_permission(code):
""" get user permission when authenticating via github"""
res = None
body = {
"client_id" : clientId,
"client_secret" : clientSecret,
"code" : code
}
req = requests.post('https://github.com/login/oauth/access_token', data=body,
headers={"accept": "application/json"})
if req.status_code == 200:
res = req.json()
print(res)
return res
def get_user_login(res):
""" get github user information """
userlogin, usermail = None, None
print("user requesting github login:", res)
access_token = res["access_token"]
req_user = requests.get("https://api.github.com/user",
headers={"Authorization": "token "+access_token})
if req_user.status_code == 200:
res_user = req_user.json()
userlogin = res_user["login"]
usermail = res_user["email"]
# new call in case no email is returned
if not usermail:
req_emails = requests.get(
"https://api.github.com/user/emails",
headers={"Authorization": f"token {access_token}"}
)
emails = req_emails.json()
if req_emails.status_code == 200:
emails = req_emails.json()
primary_email = next(
(e["email"] for e in emails if e.get("primary")),
None
)
if primary_email:
usermail = primary_email
return userlogin, usermail, access_token
def get_github_users(userlogin):
""" match user with collaborators of github repository"""
is_valid_user = False
if conf.token != '' and conf.owner != '' and conf.repo_name != '':
req = requests.get("https://api.github.com/repos/"+conf.owner+"/"+conf.repo_name+"/collaborators",
headers={"Authorization": "token "+conf.token})
if req.status_code == 200:
users = [user['login'] for user in req.json()]
if userlogin in users:
is_valid_user = True
return is_valid_user
def push(local_file_path, branch='main', gituser=None, email=None, bearer_token=None, action=''):
""" create a new file or update an existing file.
the remote file has the same relative path of the local one"""
token = conf.token if bearer_token is None else bearer_token
user = conf.author if gituser is None else gituser
usermail = conf.author_email if email is None else email
owner = conf.owner
repo_name = conf.repo_name
g = Github(token)
repo = g.get_repo(owner+"/"+repo_name)
author = InputGitAuthor(user,usermail) # commit author
try:
contents = repo.get_contents(local_file_path) # Retrieve the online file to get its SHA and path
update=True
message = "updated file "+local_file_path+' '+action
except:
update=False
message = "created file "+local_file_path
with open(local_file_path) as f: # Both create/update file replace the file with the local one
data = f.read() # could be done in a smarter way
if update == True: # If file already exists, update it
repo.update_file(contents.path, message, data, contents.sha, author=author) # Add, commit and push branch
else:
try:
# If file doesn't exist, create it in the same relative path of the local file
repo.create_file(local_file_path, message, data, branch=branch, author=author) # Add, commit and push branch
except Exception as e:
print(e)
def delete_file(local_file_path, branch, gituser=None, email=None, bearer_token=None):
""" delete files form github """
token = conf.token if bearer_token is None else bearer_token
user = conf.author if gituser is None else gituser
usermail = conf.author_email if email is None else email
owner = conf.owner
repo_name = conf.repo_name
g = Github(token)
repo = g.get_repo(owner+"/"+repo_name)
author = InputGitAuthor(user,usermail) # commit author
contents = repo.get_contents(local_file_path)
message = "deleted file "+local_file_path
repo.delete_file(contents.path, message, contents.sha, branch=branch)