130 lines
4.7 KiB
Python
130 lines
4.7 KiB
Python
import argparse
|
|
import json
|
|
|
|
import requests
|
|
|
|
def setup_args():
|
|
parser = argparse.ArgumentParser(description="Gitea classroom helper")
|
|
parser.add_argument("--url", "-u", default="http://git.kinf.wiai.uni-bamberg.de", help="Gitea path")
|
|
parser.add_argument("--token", "-t", help="Gitea application token", required=True)
|
|
args = parser.parse_args()
|
|
return args
|
|
|
|
class GiteaClassRoom:
|
|
def __init__(self, host, token):
|
|
self.session = requests.Session()
|
|
self.session.headers.update({"accept": "application/json","Content-Type": "application/json"})
|
|
self.label_id = None
|
|
self.milestone_id = None
|
|
self.host = host
|
|
self.token = token
|
|
self.validate()
|
|
|
|
def url(self, url):
|
|
url = f"{self.host}/api/v1/{url}?token={self.token}"
|
|
#print(url)
|
|
return url
|
|
|
|
def post(self, endpoint, data):
|
|
return self.session.post(self.url(endpoint), data=json.dumps(data))
|
|
|
|
def get(self, endpoint):
|
|
return self.session.get(self.url(endpoint))
|
|
|
|
def put(self, endpoint):
|
|
return self.session.put(self.url(endpoint))
|
|
|
|
def validate(self):
|
|
test = self.get("user/orgs")
|
|
if not test.ok:
|
|
raise ValueError("invalid token", test.status_code, test.text)
|
|
|
|
def filtered(self, endpoint, filters):
|
|
data = self.get(endpoint).json()
|
|
for entry in data:
|
|
if all([entry[name] == filters[name] for name in filters]):
|
|
return entry
|
|
return None
|
|
|
|
def add_label(self, repo, name="deliverables", color="#ff0000"):
|
|
label = self.filtered(f"repos/{repo}/labels", {"name": name})
|
|
if not label:
|
|
label = self.post(f"repos/{repo}/labels", {"name": name, "color":color}).json()
|
|
return label["id"]
|
|
|
|
def add_milestone(self, repo, title, description, due_on):
|
|
milestone = self.filtered(f"repos/{repo}/milestones", {"title": title, "due_on": due_on})
|
|
if not milestone:
|
|
data = {"title": title, "description": description, "due_on": due_on}
|
|
milestone = self.post(f"repos/{repo}/milestones", data).json()
|
|
return milestone["id"]
|
|
|
|
def add_issue(self, repo, title, body, milestone=None, labels=None):
|
|
issue = self.filtered(f"repos/{repo}/issues", {"title": title, "state": "open"})
|
|
if not issue:
|
|
data = {"title": title, "body": body}
|
|
if milestone:
|
|
data["milestone"] = milestone
|
|
if labels:
|
|
data["labels"] = labels
|
|
issue = self.post(f"repos/{repo}/issues", data).json()
|
|
return issue
|
|
|
|
def add_org(self, name):
|
|
print("don't forget to set the visibility to private (if you want)")
|
|
return self.post("orgs", {"username": name, "visibility": "private"}).json()
|
|
|
|
def add_org_repo(self, org, repo):
|
|
return self.post(f"org/{org}/repos", {"name": repo,"private":True}).json()
|
|
|
|
def add_team(self, org, name):
|
|
team = self.filtered(f"orgs/{org}/teams", {"name": name})
|
|
if not team:
|
|
team = self.post(f"orgs/{org}/teams", {"name": name, "permission": "write", "units":["repo.code","repo.issues","repo.pulls","repo.releases","repo.wiki"]}).json()
|
|
return team["id"]
|
|
|
|
def add_user_to_team(self, team_id, user):
|
|
return self.put(f"teams/{team_id}/members/{user}")
|
|
|
|
def add_repo_to_team(self, team_id, repo):
|
|
return self.put(f"teams/{team_id}/repos/{repo}")
|
|
|
|
def init_org(self, name, groups, labels={}, milestones={}, issues=[], **kwargs):
|
|
"""
|
|
name: name of the oranisation
|
|
groups: number of groups (int) or collection with group names
|
|
labels: map (key->props) for labels (name, color)
|
|
milestones: map (key->props) for milestones (title, description, due_on)
|
|
issues: list of issues (title, body, ([label_keys]), (milestone_key))
|
|
"""
|
|
self.add_org(name)
|
|
if isinstance(groups, int):
|
|
groups = {f"Group{i}":[] for i in range(groups)}
|
|
elif isinstance(groups, list):
|
|
groups = {f"Group{i}":v for i,v in enumerate(groups)}
|
|
for group in groups:
|
|
repo = f"{name}/{group}"
|
|
self.add_org_repo(name, group)
|
|
team = self.add_team(name, group)
|
|
for user in groups[group]:
|
|
self.add_user_to_team(team, user)
|
|
self.add_repo_to_team(team, repo)
|
|
added_labels = {label: self.add_label(repo, name=label, color=labels[label]) for label in list(labels)}
|
|
added_milestones = {milestone: self.add_milestone(repo, **milestones[milestone]) for milestone in dict(milestones)}
|
|
for issue in issues:
|
|
milestone = added_milestones[issue["milestone"]] if "milestone" in issue else None
|
|
label_ids = [added_labels[label] for label in issue["labels"]] if "labels" in issue else None
|
|
self.add_issue(repo, issue["title"], issue["body"], milestone, label_ids)
|
|
|
|
if __name__ == "__main__":
|
|
args = setup_args()
|
|
gitea = GiteaClassRoom(host=args.url, token=args.token)
|
|
|
|
# config with json file
|
|
with open("sample.json") as src:
|
|
data = json.load(src)
|
|
gitea.init_org(**data)
|
|
|
|
# config with python class
|
|
#from sample import Testdata
|
|
#gitea.init_org(Testdata.name, Testdata.groups, Testdata.labels, Testdata.milestones, Testdata.issues) |