Initialer Commit

This commit is contained in:
Clemens Klug 2019-05-23 17:27:10 +02:00
commit 7d486554e8
3 changed files with 255 additions and 0 deletions

130
gitea.py Normal file
View File

@ -0,0 +1,130 @@
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)

63
sample.json Normal file
View File

@ -0,0 +1,63 @@
{
"name": "ScriptTest",
"groups": 6,
"ALTERNATIVE_groups_with_names_and_users": {"admin": ["cklug", "mgoetz", "ckremitzl"]},
"ALTERNATIVE_groups_with_users": [["cklug", "mgoetz"]],
"labels": {
"deliverable": "#ff0000",
"hint": "#00f000"
},
"milestones": {
"ms1": {
"title": "Milestone 1",
"description": "The first milestone covers the game desgin basics (game design document), a firs architectural approach (e.g. UML diagram), and assignment of responsibilities",
"due_on": "2019-05-23T13:37:00Z"
},"ms2": {
"title": "Milestone 2",
"description": "Presentation of the final geogame (walktrough, demo, video,…)",
"due_on": "2019-07-22T13:37:00Z"
}
},
"issues": [
{
"title": "Game design document",
"body": "Write a game design document.\nYou can use the template in the VC as starting point.",
"labels": ["hint", "deliverable"],
"milestone": "ms1"
},
{
"title": "Assign responsibilites",
"body": "Split the project into equal parts",
"labels": ["deliverable"],
"milestone": "ms1"
},
{
"title": "Learn Android",
"body": "Get to know Android, especially Activites with their lifecycle and Services (Remote, Local, bind/unBind, start/stop)",
"labels": ["hint"],
"milestone": "ms1"
},
{
"title": "Create Slides",
"body": "Presenting a word document (or A4 PDF) is cumbersome",
"labels": ["hint"],
"milestone": "ms1"
},
{
"title": "Implement App",
"body": "Do it",
"labels": ["deliverable"],
"milestone": "ms2"
},
{
"title": "Game design document",
"body": "Write a game design document.\nYou can use the template in the VC as starting point.",
"labels": ["hint", "deliverable"],
"milestone": "ms1"
},
{
"title": "have fun",
"body": "'nuff said"
}
]
}

62
sample.py Normal file
View File

@ -0,0 +1,62 @@
class Testdata:
name = "ScriptTest"
groups = 5 # Group0, Group1, Group2
#groups = {"admin": ["cklug", "mgoetz", "ckremitzl"]} # "admin" with 3 members
#groups = [["cklug", "mgoetz"]] # Group0 with 2 members
labels = {
"deliverable": "#ff0000",
"hint": "#00f000"
}
milestones = {
"ms1": {
"title": "Milestone 1",
"description": "The first milestone covers the game desgin basics (game design document), a firs architectural approach (e.g. UML diagram), and assignment of responsibilities",
"due_on": "2019-05-23T13:37:00Z"
},"ms2": {
"title": "Milestone 2",
"description": "Presentation of the final geogame (walktrough, demo, video,…)",
"due_on": "2019-07-22T13:37:00Z"
}
}
issues = [
{
"title": "Game design document",
"body": "Write a game design document.\nYou can use the template in the VC as starting point.",
"labels": ["hint", "deliverable"],
"milestone": "ms1"
},
{
"title": "Assign responsibilites",
"body": "Split the project into equal parts",
"labels": ["deliverable"],
"milestone": "ms1"
},
{
"title": "Learn Android",
"body": "Get to know Android, especially Activites with their lifecycle and Services (Remote, Local, bind/unBind, start/stop)",
"labels": ["hint"],
"milestone": "ms1"
},
{
"title": "Create Slides",
"body": "Presenting a word document (or A4 PDF) is cumbersome",
"labels": ["hint"],
"milestone": "ms1"
},
{
"title": "Implement App",
"body": "Do it",
"labels": ["deliverable"],
"milestone": "ms2"
},
{
"title": "Game design document",
"body": "Write a game design document.\nYou can use the template in the VC as starting point.",
"labels": ["hint", "deliverable"],
"milestone": "ms1"
},
{
"title": "have fun",
"body": "'nuff said"
}
]