summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoYanZh <32470225+BoYanZh@users.noreply.github.com>2020-10-05 02:48:10 +0800
committerBoYanZh <32470225+BoYanZh@users.noreply.github.com>2020-10-05 02:48:10 +0800
commit11657edd4519e0432aa75324fdb0f9e9640b6494 (patch)
tree10835cf76628dc6a5b6c07975e967e4c55769b87
parentba5d08bcf2e545f03a174961c0e6f470f8b22d23 (diff)
update: gitea worker and minor fix
-rw-r--r--.gitignore1
-rw-r--r--VG101GradeHelper.py14
-rw-r--r--util.py11
-rw-r--r--worker/CanvasWorker.py1
-rw-r--r--worker/GitWorker.py89
-rw-r--r--worker/GiteaWorker.py34
-rw-r--r--worker/__init__.py1
7 files changed, 107 insertions, 44 deletions
diff --git a/.gitignore b/.gitignore
index 12ef888..72193b9 100644
--- a/.gitignore
+++ b/.gitignore
@@ -7,3 +7,4 @@ indv/
hgroups.json
scores.json
settings.py
+*.csv
diff --git a/VG101GradeHelper.py b/VG101GradeHelper.py
index 677a25e..507296b 100644
--- a/VG101GradeHelper.py
+++ b/VG101GradeHelper.py
@@ -4,7 +4,7 @@ import argparse
import json
import os
-from worker import CanvasWorker, GitWorker, JOJWorker
+from worker import CanvasWorker, GitWorker, JOJWorker, GiteaWorker
from settings import *
@@ -16,6 +16,11 @@ def parse():
parser.add_argument('-h', '--hw', type=int, help='# homework')
parser.add_argument('-p', '--proj', type=int, help='# project')
parser.add_argument('-m', '--ms', type=int, help='# milestone')
+ parser.add_argument('-r',
+ '--rejudge',
+ type=int,
+ default=-1,
+ help='rejudge group num or stu ID')
parser.add_argument('-a', '--all', action='store_true', help='check all')
parser.add_argument('-s',
'--score',
@@ -63,7 +68,7 @@ if __name__ == "__main__":
args = parse()
indvScores, groupScores, jojScores = {}, {}, {}
gitWorker = GitWorker(args, hgroups,
- [item[0] for item in JOJ_INFO["problemInfo"]])
+ [item[0] for item in JOJ_INFO["problemInfo"]])
if args.indv:
indvScores = gitWorker.checkIndv()
if args.group:
@@ -78,4 +83,7 @@ if __name__ == "__main__":
if args.upload:
canvasWorker.grade2Canvas()
if args.proj:
- gitWorker.checkProj(args.proj, args.ms)
+ projScores = gitWorker.checkProj(args.proj, args.ms)
+ giteaWorker = GiteaWorker(args, GITEA_BASE_URL, ORG_NAME, GITEA_TOKEN,
+ hgroups)
+ giteaWorker.raiseIssues(projScores)
diff --git a/util.py b/util.py
index e1c9e2d..bd916df 100644
--- a/util.py
+++ b/util.py
@@ -1,5 +1,5 @@
import logging
-
+import re
class Logger():
_instance = None
@@ -27,4 +27,11 @@ def first(iterable, condition=lambda x: True):
try:
return next(x for x in iterable if condition(x))
except StopIteration:
- return None \ No newline at end of file
+ return None
+
+def getProjRepoName(arg):
+ id_, name, projNum, *_ = arg
+ eng = re.sub('[\u4e00-\u9fa5]', '', name)
+ eng = ''.join(
+ [word[0].capitalize() + word[1:] for word in eng.split()])
+ return f"{eng}{id_}-p{projNum}" \ No newline at end of file
diff --git a/worker/CanvasWorker.py b/worker/CanvasWorker.py
index e5457a2..954d1da 100644
--- a/worker/CanvasWorker.py
+++ b/worker/CanvasWorker.py
@@ -66,6 +66,7 @@ class CanvasWorker():
if currentUser is None: continue
name = currentUser.name.strip()
if name not in self.names: continue
+ if not self.scores[name]: continue
data = self.generateHomeworkData(self.scores[name])
self.logger.debug(f"{name} {data.__repr__()}")
submission.edit(**data)
diff --git a/worker/GitWorker.py b/worker/GitWorker.py
index af5ed12..fd52853 100644
--- a/worker/GitWorker.py
+++ b/worker/GitWorker.py
@@ -1,10 +1,9 @@
from shutil import ignore_patterns, copytree, rmtree
-from util import Logger
+from util import Logger, getProjRepoName
import multiprocessing
import traceback
import git
import os
-import re
class GitWorker():
@@ -27,13 +26,6 @@ class GitWorker():
if len(fn) == 6: return fn == "readme"
return fn[:7] == "readme."
- def checkProjRepoName(self, arg):
- id_, name, projNum, *_ = arg
- eng = re.sub('[\u4e00-\u9fa5]', '', name)
- eng = ''.join(
- [word[0].capitalize() + word[1:] for word in eng.split()])
- return f"{eng}{id_}-p{projNum}"
-
def checkIndvProcess(self, groupNum, hwNum):
tidy = self.args.tidy
repoName = f"hgroup-{groupNum:02}"
@@ -65,8 +57,8 @@ class GitWorker():
scores[stuName]['indvComment'].append(
"individual branch individual branch missing")
continue
- repo.git.checkout(f"{stuID}", "-f")
repo.git.reset('--hard')
+ repo.git.checkout(f"{stuID}", "-f")
repo.git.pull("origin", f"{stuID}", "-f")
repo.git.reset(f"origin/{stuID}", "--hard")
repo.git.clean("-d", "-f", "-x")
@@ -92,8 +84,7 @@ class GitWorker():
scores[stuName]['indvFailSubmit'] = 1
scores[stuName]['indvComment'].append(
f"individual branch h{hwNum}/{fn} file missing")
- if not list(filter(GitWorker.isREADME,
- os.listdir(hwDir))):
+ if not list(filter(GitWorker.isREADME, os.listdir(hwDir))):
self.logger.warning(
f"{repoName} {stuID} {stuName} h{hwNum}/README file missing"
)
@@ -105,29 +96,28 @@ class GitWorker():
filter(
lambda x: x not in [
".git", *[f"h{n}" for n in range(20)]
- ] and not GitWorker.isREADME(x),
- os.listdir(repoDir)))
+ ] and not GitWorker.isREADME(x), os.listdir(repoDir)))
if dirList:
self.logger.warning(
- f"{repoName} {stuID} {stuName} untidy {dirList.__repr__()}"
+ f"{repoName} {stuID} {stuName} untidy {', '.join(dirList)}"
)
scores[stuName]['indvUntidy'] = 1
scores[stuName]['indvComment'].append(
- f"individual branch redundant files: {dirList.__repr__()}"
+ f"individual branch redundant files: {', '.join(dirList)}"
)
if os.path.exists(hwDir):
dirList = os.listdir(hwDir)
dirList = list(
filter(
- lambda x: not x.startswith("ex") and
- not GitWorker.isREADME(x), dirList))
+ lambda x: not x.startswith("ex") and not GitWorker.
+ isREADME(x), dirList))
if dirList:
self.logger.warning(
- f"{repoName} {stuID} {stuName} h{hwNum}/ untidy {dirList.__repr__()}"
+ f"{repoName} {stuID} {stuName} h{hwNum}/ untidy {', '.join(dirList)}"
)
scores[stuName]['indvUntidy'] = 1
scores[stuName]['indvComment'].append(
- f"individual branch redundant files: {dirList.__repr__()}"
+ f"individual branch redundant files: {', '.join(dirList)}"
)
except Exception:
self.logger.error(f"{repoName} {stuID} {stuName} error")
@@ -146,6 +136,7 @@ class GitWorker():
branch='master')
else:
repo = git.Repo(repoDir)
+ repo.git.reset('--hard')
repo.git.checkout("master", "-f")
repo.git.fetch("--tags", "-f")
tagNames = [tag.name for tag in repo.tags]
@@ -164,6 +155,7 @@ class GitWorker():
scores[stuName]['groupComment'].append(
f"tags/h{hwNum} missing")
return scores
+ repo.git.reset('--hard')
repo.git.checkout(f"tags/h{hwNum}", "-f")
if not os.path.exists(hwDir):
self.logger.warning(f"{repoName} h{hwNum} dir missing")
@@ -194,11 +186,11 @@ class GitWorker():
lambda x: x not in [".git", *[f"h{n}" for n in range(20)]] and
not GitWorker.isREADME(x), dirList))
if dirList:
- self.logger.warning(f"{repoName} untidy {dirList.__repr__()}")
+ self.logger.warning(f"{repoName} untidy {', '.join(dirList)}")
for _, stuName in self.hgroups[repoName]:
scores[stuName]['groupUntidy'] = 1
scores[stuName]['groupComment'].append(
- f"master branch redundant files: {dirList.__repr__()}")
+ f"master branch redundant files: {', '.join(dirList)}")
if os.path.exists(hwDir):
dirList = os.listdir(hwDir)
dirList = list(
@@ -207,16 +199,22 @@ class GitWorker():
isREADME(x), dirList))
if dirList:
self.logger.warning(
- f"{repoName} h{hwNum} untidy {dirList.__repr__()}")
+ f"{repoName} h{hwNum} untidy {', '.join(dirList)}")
for _, stuName in self.hgroups[repoName]:
scores[stuName]['groupUntidy'] = 1
scores[stuName]['groupComment'].append(
- f"master branch redundant files: {dirList.__repr__()}")
+ f"master branch redundant files: {', '.join(dirList)}")
return scores
def checkProjProcess(self, id_, name, projNum, milestoneNum):
- repoName = self.checkProjRepoName([id_, name, projNum, milestoneNum])
+ stuName = name
+ repoName = getProjRepoName([id_, name, projNum, milestoneNum])
repoDir = os.path.join('projrepos', f'p{projNum}', repoName)
+ scores = {
+ stuName: {
+ "projComment": [],
+ }
+ }
if not os.path.exists(repoDir):
repo = git.Repo.clone_from(
f"https://focs.ji.sjtu.edu.cn/git/vg101/{repoName}", repoDir)
@@ -225,43 +223,55 @@ class GitWorker():
repo.git.fetch()
remoteBranches = [ref.name for ref in repo.remote().refs]
if 'origin/master' not in remoteBranches:
- self.logger.warning(f"{repoName} branch master missing")
- return
- repo.git.checkout(f"master", "-f")
+ self.logger.warning(f"{repoName} master branch missing")
+ scores[stuName]["projComment"].append(f"master branch missing")
+ return scores
repo.git.reset('--hard')
+ repo.git.checkout(f"master", "-f")
repo.git.pull("origin", "master", "-f")
repo.git.reset('--hard')
repo.git.clean("-d", "-f", "-x")
if not list(filter(GitWorker.isREADME, os.listdir(repoDir))):
- self.logger.warning(f"{repoName} README missing")
+ self.logger.warning(f"{repoName} README file missing")
+ scores[stuName]["projComment"].append(f"README file missing")
if milestoneNum:
tagNames = [tag.name for tag in repo.tags]
if f"m{milestoneNum}" not in tagNames:
self.logger.warning(f"{repoName} tags/m{milestoneNum} missing")
- return
+ scores[stuName]["projComment"].append(
+ f"tags/m{milestoneNum} missing")
+ return scores
+ repo.git.reset('--hard')
repo.git.checkout(f"tags/m{milestoneNum}", "-f")
self.logger.debug(
f"{repoName} checkout to tags/m{milestoneNum} succeed")
else:
self.logger.debug(f"{repoName} pull succeed")
+ return scores
def checkIndv(self):
if self.args.dir:
if os.path.exists(os.path.join('indv')):
rmtree(os.path.join('indv'))
hwNum = self.args.hw
- with multiprocessing.Pool(self.processCount) as p:
- res = p.starmap(self.checkIndvProcess,
- [(i, hwNum)
- for i in range(len(self.hgroups.keys()))])
+ if self.args.rejudge < 0:
+ with multiprocessing.Pool(self.processCount) as p:
+ res = p.starmap(self.checkIndvProcess,
+ [(i, hwNum)
+ for i in range(len(self.hgroups.keys()))])
+ else:
+ res = [self.checkIndvProcess(self.args.rejudge, hwNum)]
return {k: v for d in res for k, v in d.items()}
def checkGroup(self):
hwNum = self.args.hw
- with multiprocessing.Pool(self.processCount) as p:
- res = p.starmap(self.checkGroupProcess,
- [(i, hwNum)
- for i in range(len(self.hgroups.keys()))])
+ if self.args.rejudge < 0:
+ with multiprocessing.Pool(self.processCount) as p:
+ res = p.starmap(self.checkGroupProcess,
+ [(i, hwNum)
+ for i in range(len(self.hgroups.keys()))])
+ else:
+ res = [self.checkGroupProcess(self.args.rejudge, hwNum)]
return {k: v for d in res for k, v in d.items()}
def checkProj(self, projNum, milestoneNum):
@@ -275,4 +285,5 @@ class GitWorker():
else:
return
with multiprocessing.Pool(self.processCount) as p:
- p.starmap(self.checkProjProcess, infos) \ No newline at end of file
+ res = p.starmap(self.checkProjProcess, infos)
+ return {k: v for d in res for k, v in d.items()} \ No newline at end of file
diff --git a/worker/GiteaWorker.py b/worker/GiteaWorker.py
new file mode 100644
index 0000000..7a2c79c
--- /dev/null
+++ b/worker/GiteaWorker.py
@@ -0,0 +1,34 @@
+from util import Logger, getProjRepoName
+import requests
+
+
+class GiteaWorker():
+ def __init__(self, args, baseUrl, orgName, token, hgroups,
+ logger=Logger()):
+ self.args = args
+ # self.id_ = id_
+ # self.name = name
+ # self.projNum = projNum
+ # self.projScores = projScores
+ self.logger = logger
+ self.names = {
+ item[1]: item[0]
+ for items in hgroups.values() for item in items
+ }
+ self.baseUrl = baseUrl
+ self.orgName = orgName
+ self.sess = requests.Session()
+ self.sess.params.update({"access_token": token})
+
+ def raiseIssues(self, scores):
+ for key, value in scores.items():
+ if not value.get('projComment'): continue
+ id_ = self.names[key]
+ repoName = getProjRepoName([id_, key, self.args.proj])
+ url = f"{self.baseUrl}/repos/{self.orgName}/{repoName}/issues"
+ data = {
+ "title": f"m{self.args.ms} feedback",
+ "body": '\n'.join(value.get('projComment')),
+ }
+ req = self.sess.post(url, data)
+ self.logger.debug(f"{repoName} issue {req.status_code} {req.text}")
diff --git a/worker/__init__.py b/worker/__init__.py
index 153ec1b..1e5df1a 100644
--- a/worker/__init__.py
+++ b/worker/__init__.py
@@ -1,3 +1,4 @@
from .CanvasWorker import CanvasWorker
+from .GiteaWorker import GiteaWorker
from .GitWorker import GitWorker
from .JOJWorker import JOJWorker \ No newline at end of file