feat: joj3 check
This commit is contained in:
parent
da28e15a28
commit
dd9c150598
|
@ -1,5 +1,6 @@
|
||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
|
import re
|
||||||
from datetime import datetime, timedelta
|
from datetime import datetime, timedelta
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from time import sleep
|
from time import sleep
|
||||||
|
@ -13,6 +14,7 @@ from joint_teapot.config import Settings, set_settings, settings
|
||||||
from joint_teapot.teapot import Teapot
|
from joint_teapot.teapot import Teapot
|
||||||
from joint_teapot.utils import joj3
|
from joint_teapot.utils import joj3
|
||||||
from joint_teapot.utils.logger import logger, set_logger
|
from joint_teapot.utils.logger import logger, set_logger
|
||||||
|
from joint_teapot.utils.main import first
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
import focs_gitea
|
import focs_gitea
|
||||||
|
@ -637,6 +639,88 @@ def joj3_all(
|
||||||
sleep(retry_interval)
|
sleep(retry_interval)
|
||||||
|
|
||||||
|
|
||||||
|
@app.command(
|
||||||
|
"joj3-check",
|
||||||
|
help="check joj3 restrictions",
|
||||||
|
)
|
||||||
|
def joj3_check(
|
||||||
|
env_path: str = Argument("", help="path to .env file"),
|
||||||
|
submitter: str = Argument("", help="submitter ID"),
|
||||||
|
repo_name: str = Argument(
|
||||||
|
"",
|
||||||
|
help="name of grading repo to push scoreboard file",
|
||||||
|
),
|
||||||
|
submitter_repo_name: str = Argument(
|
||||||
|
"",
|
||||||
|
help="repository's name of the submitter",
|
||||||
|
),
|
||||||
|
scoreboard_file_name: str = Argument(
|
||||||
|
"scoreboard.csv", help="name of scoreboard file in the gitea repo"
|
||||||
|
),
|
||||||
|
exercise_name: str = Argument(
|
||||||
|
"unknown",
|
||||||
|
help="name of the exercise that appears on the issue title",
|
||||||
|
),
|
||||||
|
group_config: str = Option(
|
||||||
|
...,
|
||||||
|
help=(
|
||||||
|
"Configuration for groups in the format "
|
||||||
|
"'group_name=max_count:time_period(in hours)'. "
|
||||||
|
"Empty group name for all groups. "
|
||||||
|
"Negative max_count or time_period for no limit. "
|
||||||
|
"Example: --group-config joj=10:24,run=20:48"
|
||||||
|
),
|
||||||
|
),
|
||||||
|
) -> None:
|
||||||
|
set_settings(Settings(_env_file=env_path))
|
||||||
|
set_logger(settings.stderr_log_level, diagnose=False, backtrace=False)
|
||||||
|
repo: Repo = tea.pot.git.get_repo(repo_name)
|
||||||
|
now = datetime.now()
|
||||||
|
items = group_config.split(",")
|
||||||
|
for item in items:
|
||||||
|
group, values = item.split("=")
|
||||||
|
max_count, time_period = map(int, values.split(":"))
|
||||||
|
if max_count < 0 or time_period < 0:
|
||||||
|
continue
|
||||||
|
since = now - timedelta(hours=time_period)
|
||||||
|
since_git_format = since.strftime("%Y-%m-%dT%H:%M:%S")
|
||||||
|
submit_count = 0
|
||||||
|
commits = repo.iter_commits(paths=scoreboard_file_name, since=since_git_format)
|
||||||
|
for commit in commits:
|
||||||
|
msg = commit.message.strip()
|
||||||
|
lines = msg.splitlines()
|
||||||
|
pattern = (
|
||||||
|
r"joj3: update scoreboard for (?P<exercise_name>.+?) "
|
||||||
|
r"by @(?P<submitter>.+) in "
|
||||||
|
r"(?P<gitea_org_name>.+)/(?P<submitter_repo_name>.+)@(?P<commit_hash>.+)" # 捕获 gitea_org_name, submitter_repo_name 和 commit_hash
|
||||||
|
)
|
||||||
|
match = re.match(pattern, lines[0])
|
||||||
|
if not match:
|
||||||
|
continue
|
||||||
|
d = match.groupdict()
|
||||||
|
if (
|
||||||
|
exercise_name != d["exercise_name"]
|
||||||
|
or submitter != d["submitter"]
|
||||||
|
or submitter_repo_name != d["submitter_repo_name"]
|
||||||
|
):
|
||||||
|
continue
|
||||||
|
if group != "":
|
||||||
|
line = first(lines, lambda l: l.startswith("groups: "))
|
||||||
|
if line is not None:
|
||||||
|
groups = line[len("groups: ") :].split(",")
|
||||||
|
if group not in groups:
|
||||||
|
continue
|
||||||
|
submit_count += 1
|
||||||
|
if submit_count > max_count:
|
||||||
|
logger.error(
|
||||||
|
f"submitter {submitter} has submitted too many times, "
|
||||||
|
f"group={group}, "
|
||||||
|
f"time period={time_period} hour(s), "
|
||||||
|
f"max count={max_count}, submit count={submit_count}"
|
||||||
|
)
|
||||||
|
raise Exit(code=1)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
try:
|
try:
|
||||||
app()
|
app()
|
||||||
|
|
Loading…
Reference in New Issue
Block a user