Update for PB071
This commit is contained in:
parent
18fa316bac
commit
0a1370ec92
6 changed files with 97 additions and 108 deletions
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
|
|
||||||
import os
|
import os
|
||||||
from typing import List
|
from typing import Dict, List
|
||||||
|
|
||||||
from git import checkout_branch
|
from git import checkout_branch
|
||||||
from gitlab import Gitlab
|
from gitlab import Gitlab
|
||||||
|
@ -11,9 +11,11 @@ from submission import Submission
|
||||||
|
|
||||||
|
|
||||||
class BaseCommand:
|
class BaseCommand:
|
||||||
def __init__(self, submissions: List[Submission], gitlab: Gitlab) -> None:
|
def __init__(self, submissions: List[Submission], gitlab: Gitlab, details:
|
||||||
|
Dict) -> None:
|
||||||
self.submissions = submissions
|
self.submissions = submissions
|
||||||
self.gitlab = gitlab
|
self.gitlab = gitlab
|
||||||
|
self.hw = details
|
||||||
|
|
||||||
def __call__(self) -> None:
|
def __call__(self) -> None:
|
||||||
for submission in self.submissions:
|
for submission in self.submissions:
|
||||||
|
|
|
@ -11,9 +11,9 @@ from utils import run_cmd
|
||||||
|
|
||||||
|
|
||||||
class MergeRequests(BaseGitCommand):
|
class MergeRequests(BaseGitCommand):
|
||||||
@staticmethod
|
def get_files(self, submission: Submission) -> None:
|
||||||
def get_files(submission: Submission) -> None:
|
# files = f"master-naostro/LoadTest/{submission.homework}.py"
|
||||||
files = f"master-naostro/LoadTest/{submission.homework}.py"
|
files = f"master-nanecisto/nanecisto/{','.join(self.hw['files'])}"
|
||||||
|
|
||||||
if run_cmd("rsync", "-avzP", f"aisa:{submission.path}/{files}", "./")[0] != 0:
|
if run_cmd("rsync", "-avzP", f"aisa:{submission.path}/{files}", "./")[0] != 0:
|
||||||
exit(1)
|
exit(1)
|
||||||
|
@ -26,17 +26,17 @@ class MergeRequests(BaseGitCommand):
|
||||||
|
|
||||||
def exec(self, submission: Submission) -> None:
|
def exec(self, submission: Submission) -> None:
|
||||||
self.get_files(submission)
|
self.get_files(submission)
|
||||||
self.call_flake(submission)
|
# self.call_flake(submission)
|
||||||
|
|
||||||
add_files(f"{submission.homework}.py", "flake.log")
|
add_files(*self.hw['files'])
|
||||||
commit(f'"Add sources and flake log ({submission.branch} {submission.login})"')
|
commit(f'"Add sources ({submission.branch} {submission.login})"')
|
||||||
push("origin", submission.branch)
|
push("origin", submission.branch)
|
||||||
|
|
||||||
self.gitlab.post_mr(
|
self.gitlab.post_mr(
|
||||||
source_branch=submission.branch,
|
source_branch=submission.branch,
|
||||||
target_branch="master",
|
target_branch="master",
|
||||||
title=f"[{submission.homework}{'-opravne' if submission.correction else ''}] {submission.login}",
|
title=f"[{submission.homework}{'-opravne' if submission.correction else ''}] {submission.login}",
|
||||||
description=f"```\n{submission.get_mail()}\n```",
|
description=submission.get_mail(),
|
||||||
labels=submission.homework,
|
labels=submission.homework,
|
||||||
remove_source_branch="true",
|
remove_source_branch="true",
|
||||||
assignee_ids=["1772"],
|
assignee_ids=["1772"],
|
||||||
|
|
83
gitlab.py
83
gitlab.py
|
@ -1,83 +0,0 @@
|
||||||
#!/usr/bin/env python3
|
|
||||||
|
|
||||||
|
|
||||||
import os
|
|
||||||
import requests
|
|
||||||
|
|
||||||
|
|
||||||
class Gitlab:
|
|
||||||
def __init__(self, project, token):
|
|
||||||
self.base_url = "https://gitlab.fi.muni.cz/api/v4/projects"
|
|
||||||
self.project = project
|
|
||||||
self.token = token
|
|
||||||
|
|
||||||
self.headers = {"Private-Token": token}
|
|
||||||
|
|
||||||
def post_mr(
|
|
||||||
self,
|
|
||||||
source_branch,
|
|
||||||
target_branch,
|
|
||||||
title,
|
|
||||||
description,
|
|
||||||
labels,
|
|
||||||
remove_source_branch,
|
|
||||||
assignee_ids,
|
|
||||||
):
|
|
||||||
params = {
|
|
||||||
"source_branch": source_branch,
|
|
||||||
"target_branch": target_branch,
|
|
||||||
"title": title,
|
|
||||||
"description": description,
|
|
||||||
"labels": labels,
|
|
||||||
"remove_source_branch": remove_source_branch,
|
|
||||||
"assignee_ids": assignee_ids,
|
|
||||||
}
|
|
||||||
|
|
||||||
with requests.post(
|
|
||||||
f"{self.base_url}/{self.project}/merge_requests",
|
|
||||||
params=params,
|
|
||||||
headers=self.headers,
|
|
||||||
) as req:
|
|
||||||
print(req.status_code)
|
|
||||||
|
|
||||||
def get_mrs_for_branch(self, branch):
|
|
||||||
params = {"source_branch": branch}
|
|
||||||
|
|
||||||
with requests.get(
|
|
||||||
f"{self.base_url}/{self.project}/merge_requests",
|
|
||||||
params=params,
|
|
||||||
headers=self.headers,
|
|
||||||
) as req:
|
|
||||||
return req.json()
|
|
||||||
|
|
||||||
def merge_mr(self, iid):
|
|
||||||
|
|
||||||
with requests.put(
|
|
||||||
f"{self.base_url}/{self.project}/merge_requests/{iid}/merge",
|
|
||||||
headers=self.headers,
|
|
||||||
) as req:
|
|
||||||
print(req.status_code)
|
|
||||||
|
|
||||||
def set_assignees(self, iid, assignee_ids):
|
|
||||||
params = {"assignee_ids[]": assignee_ids}
|
|
||||||
|
|
||||||
with requests.put(
|
|
||||||
f"{self.base_url}/{self.project}/merge_requests/{iid}",
|
|
||||||
params=params,
|
|
||||||
headers=self.headers,
|
|
||||||
) as req:
|
|
||||||
print(req.status_code)
|
|
||||||
|
|
||||||
def get_comments(self, iid, page=1):
|
|
||||||
params = {"sort": "asc", "page": page}
|
|
||||||
|
|
||||||
with requests.get(
|
|
||||||
f"{self.base_url}/{self.project}/merge_requests/{iid}/notes",
|
|
||||||
params=params,
|
|
||||||
headers=self.headers,
|
|
||||||
) as req:
|
|
||||||
comments = req.json()
|
|
||||||
if 'rel="next"' in req.headers["Link"]:
|
|
||||||
comments.extend(self.get_comments(iid, page + 1))
|
|
||||||
return comments
|
|
||||||
|
|
50
gitlab_provider.py
Normal file
50
gitlab_provider.py
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
|
||||||
|
from ogr.services.gitlab import GitlabService
|
||||||
|
|
||||||
|
|
||||||
|
class Gitlab:
|
||||||
|
def __init__(self, namespace, repo, token):
|
||||||
|
self.ogr_service = GitlabService(
|
||||||
|
token=token,
|
||||||
|
instance_url="https://gitlab.fi.muni.cz"
|
||||||
|
)
|
||||||
|
self.ogr_project = self.ogr_service.get_project(
|
||||||
|
repo=repo,
|
||||||
|
namespace=namespace
|
||||||
|
)
|
||||||
|
|
||||||
|
def post_mr(
|
||||||
|
self,
|
||||||
|
source_branch,
|
||||||
|
target_branch,
|
||||||
|
title,
|
||||||
|
description,
|
||||||
|
labels,
|
||||||
|
remove_source_branch,
|
||||||
|
assignee_ids,
|
||||||
|
):
|
||||||
|
self.ogr_project.create_pr(
|
||||||
|
title=title,
|
||||||
|
body=description,
|
||||||
|
target_branch=target_branch,
|
||||||
|
source_branch=source_branch
|
||||||
|
)
|
||||||
|
|
||||||
|
def get_mrs_for_branch(self, branch):
|
||||||
|
# TODO
|
||||||
|
pass
|
||||||
|
|
||||||
|
def merge_mr(self, iid):
|
||||||
|
# TODO
|
||||||
|
pass
|
||||||
|
|
||||||
|
def set_assignees(self, iid, assignee_ids):
|
||||||
|
# TODO
|
||||||
|
pass
|
||||||
|
|
||||||
|
def get_comments(self, iid, page=1):
|
||||||
|
# TODO
|
||||||
|
pass
|
||||||
|
|
|
@ -8,22 +8,31 @@ from mailbox import mbox, mboxMessage
|
||||||
import math
|
import math
|
||||||
import re
|
import re
|
||||||
from typing import Dict, List, Tuple
|
from typing import Dict, List, Tuple
|
||||||
|
import json
|
||||||
|
|
||||||
|
|
||||||
from submission import Submission, print_submissions
|
from submission import Submission, print_submissions
|
||||||
|
|
||||||
|
|
||||||
class Parser:
|
class Parser:
|
||||||
INFO_REGEX = re.compile(r"(\d{6}) \| (x\S*)\s*")
|
INFO_REGEX = re.compile(r"<td>(\d{6}) \| <code>(x\S*)</code>\s*")
|
||||||
SUBMISSION_REGEX = re.compile(r"adresář:\s+(\S*\/(\S*))\s*")
|
SUBMISSION_REGEX = re.compile(r"adresář:\s+(\S*\/(\S*))\s*")
|
||||||
POINTS_REGEX = re.compile(r"\*\scelkový počet bodů\s+((\d|\.)*)\s*")
|
POINTS_REGEX = re.compile(r"\*\scelkový počet bodů\s+((\d|\.)*)\s*")
|
||||||
DATE_FORMAT = "%Y_%m%d_%H%M%S"
|
DATE_FORMAT = "%Y_%m%d_%H%M%S"
|
||||||
OFFSET_FOR_CORRECTION = datetime.timedelta(days=8)
|
OFFSET_FOR_CORRECTION = datetime.timedelta(days=8)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_match_from_mail(regex: re.Pattern, mail: mboxMessage) -> re.Match:
|
def get_mail(mail: mboxMessage) -> str:
|
||||||
body = mail.get_payload()
|
body = None
|
||||||
match = regex.search(body)
|
for payload in mail.get_payload():
|
||||||
|
if payload['Content-Type'].startswith('text/html'):
|
||||||
|
body = payload.get_payload()
|
||||||
|
|
||||||
|
return body
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_match_from_mail(regex: re.Pattern, mail: str) -> re.Match:
|
||||||
|
match = regex.search(mail)
|
||||||
if not match:
|
if not match:
|
||||||
raise ValueError("invalid mail has been given")
|
raise ValueError("invalid mail has been given")
|
||||||
|
|
||||||
|
@ -44,12 +53,13 @@ class Parser:
|
||||||
match = Parser.get_match_from_mail(Parser.POINTS_REGEX, mail)
|
match = Parser.get_match_from_mail(Parser.POINTS_REGEX, mail)
|
||||||
return float(match.group(1))
|
return float(match.group(1))
|
||||||
|
|
||||||
def __init__(self, path: str, deadline: str, correction: bool = False) -> None:
|
def __init__(self, details: Dict, reviewer: str) -> None:
|
||||||
self.box = mbox(path)
|
self.box = mbox(details["mbox_path"])
|
||||||
|
self.reviewer = reviewer
|
||||||
|
|
||||||
self.deadline = datetime.datetime.strptime(deadline, Parser.DATE_FORMAT)
|
self.deadline = datetime.datetime.strptime(details["deadline"], Parser.DATE_FORMAT)
|
||||||
self.correction = correction
|
self.correction = details["correction"]
|
||||||
if correction:
|
if self.correction:
|
||||||
# in case of correction pass the date of
|
# in case of correction pass the date of
|
||||||
# submitting review to IS for automatic computation
|
# submitting review to IS for automatic computation
|
||||||
self.deadline = self.deadline.replace(hour=0, minute=0, second=0)
|
self.deadline = self.deadline.replace(hour=0, minute=0, second=0)
|
||||||
|
@ -59,9 +69,14 @@ class Parser:
|
||||||
submissions = []
|
submissions = []
|
||||||
|
|
||||||
for mail in self.box.values():
|
for mail in self.box.values():
|
||||||
uco, login = Parser.parse_info(mail)
|
if self.reviewer not in mail['subject']:
|
||||||
path, submission_id = Parser.parse_submission(mail)
|
continue
|
||||||
points = Parser.parse_points(mail)
|
|
||||||
|
text = Parser.get_mail(mail)
|
||||||
|
|
||||||
|
uco, login = Parser.parse_info(text)
|
||||||
|
path, submission_id = Parser.parse_submission(text)
|
||||||
|
points = Parser.parse_points(text)
|
||||||
|
|
||||||
submissions.append(
|
submissions.append(
|
||||||
Submission(
|
Submission(
|
||||||
|
@ -72,7 +87,7 @@ class Parser:
|
||||||
points,
|
points,
|
||||||
hw_tag,
|
hw_tag,
|
||||||
self.correction,
|
self.correction,
|
||||||
mail.get_payload(),
|
text,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
submissions[-1].set_late_tag(self.deadline)
|
submissions[-1].set_late_tag(self.deadline)
|
||||||
|
|
11
pushee.py
11
pushee.py
|
@ -8,7 +8,7 @@ import sys
|
||||||
|
|
||||||
|
|
||||||
from commands import MergeRequests, UpdateAssignees, Comments, Merge, Test
|
from commands import MergeRequests, UpdateAssignees, Comments, Merge, Test
|
||||||
from gitlab import Gitlab
|
from gitlab_provider import Gitlab
|
||||||
from kontr_emails import Parser
|
from kontr_emails import Parser
|
||||||
|
|
||||||
|
|
||||||
|
@ -52,10 +52,15 @@ def main():
|
||||||
print_usage()
|
print_usage()
|
||||||
exit(2)
|
exit(2)
|
||||||
|
|
||||||
|
details = config["homeworks"][config["homework"]]
|
||||||
|
|
||||||
submissions = Parser(
|
submissions = Parser(
|
||||||
config["mbox_path"], config["deadline"], config["correction"]
|
details, config["reviewer"]
|
||||||
).parse(config["homework"])
|
).parse(config["homework"])
|
||||||
COMMANDS[sys.argv[1]](submissions, Gitlab(config["project"], config["token"]))()
|
|
||||||
|
COMMANDS[sys.argv[1]](submissions, Gitlab(config["project_namespace"],
|
||||||
|
config["project_name"],
|
||||||
|
config["token"]), details)()
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|
Reference in a new issue