kattis2canvas 0.1.5__tar.gz → 0.1.6__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {kattis2canvas-0.1.5 → kattis2canvas-0.1.6}/PKG-INFO +1 -1
- {kattis2canvas-0.1.5 → kattis2canvas-0.1.6}/pyproject.toml +1 -1
- {kattis2canvas-0.1.5 → kattis2canvas-0.1.6}/src/kattis2canvas/cli.py +64 -44
- {kattis2canvas-0.1.5 → kattis2canvas-0.1.6}/src/kattis2canvas.egg-info/PKG-INFO +1 -1
- {kattis2canvas-0.1.5 → kattis2canvas-0.1.6}/README.md +0 -0
- {kattis2canvas-0.1.5 → kattis2canvas-0.1.6}/setup.cfg +0 -0
- {kattis2canvas-0.1.5 → kattis2canvas-0.1.6}/src/kattis2canvas/__init__.py +0 -0
- {kattis2canvas-0.1.5 → kattis2canvas-0.1.6}/src/kattis2canvas/__main__.py +0 -0
- {kattis2canvas-0.1.5 → kattis2canvas-0.1.6}/src/kattis2canvas.egg-info/SOURCES.txt +0 -0
- {kattis2canvas-0.1.5 → kattis2canvas-0.1.6}/src/kattis2canvas.egg-info/dependency_links.txt +0 -0
- {kattis2canvas-0.1.5 → kattis2canvas-0.1.6}/src/kattis2canvas.egg-info/entry_points.txt +0 -0
- {kattis2canvas-0.1.5 → kattis2canvas-0.1.6}/src/kattis2canvas.egg-info/requires.txt +0 -0
- {kattis2canvas-0.1.5 → kattis2canvas-0.1.6}/src/kattis2canvas.egg-info/top_level.txt +0 -0
|
@@ -734,10 +734,12 @@ def kattislinks(canvas_course):
|
|
|
734
734
|
@click.option("--dryrun/--no-dryrun", default=True, help="show planned actions, do not make them happen.")
|
|
735
735
|
@click.option("--assignment-group", default="kattis", help="the canvas assignment group to use (default: kattis).")
|
|
736
736
|
@click.option("--section", help="only process submissions for students in this specific section.")
|
|
737
|
-
|
|
737
|
+
@click.option("--force-comment/--no-force-comment", default=False, help="add a comment about the best submission even if there is already a comment in canvas.")
|
|
738
|
+
def submissions2canvas(offering, canvas_course, dryrun, assignment_group, section, force_comment):
|
|
738
739
|
"""
|
|
739
740
|
mirror summary of submission from kattis into canvas as a submission comment.
|
|
740
741
|
"""
|
|
742
|
+
print(force_comment)
|
|
741
743
|
load_config()
|
|
742
744
|
offerings = list(get_offerings(offering))
|
|
743
745
|
if len(offerings) == 0:
|
|
@@ -796,20 +798,22 @@ def submissions2canvas(offering, canvas_course, dryrun, assignment_group, sectio
|
|
|
796
798
|
f'duplicate submission for {kattis_user2canvas_id[canvas_submission.user_id]} in {assignment.title}')
|
|
797
799
|
submissions_by_user[canvas_id2kattis_user[canvas_submission.user_id]] = canvas_submission
|
|
798
800
|
last_comment = datetime.datetime.fromordinal(1).replace(tzinfo=datetime.timezone.utc)
|
|
801
|
+
last_comment_text = ''
|
|
799
802
|
if canvas_submission.submission_comments:
|
|
800
803
|
for comment in canvas_submission.submission_comments:
|
|
801
804
|
created_at = extract_canvas_date(comment['created_at'])
|
|
802
|
-
if created_at > last_comment:
|
|
805
|
+
if config.kattis_hostname in comment.get('comment', '') and created_at > last_comment:
|
|
803
806
|
last_comment = created_at
|
|
807
|
+
last_comment_text = comment.get('comment', '')
|
|
804
808
|
canvas_submission.last_comment = last_comment
|
|
805
|
-
|
|
809
|
+
canvas_submission.last_comment_text = last_comment_text
|
|
806
810
|
for user, best in best_submissions.items():
|
|
807
811
|
for kattis_submission in best.values():
|
|
808
812
|
if user not in submissions_by_user:
|
|
809
813
|
warn(f"i don't see a canvas user for {user}")
|
|
810
814
|
elif user not in kattis_user2canvas_id:
|
|
811
815
|
warn(f'skipping submission for unknown user {user}')
|
|
812
|
-
elif kattis_submission.date > submissions_by_user[user].last_comment:
|
|
816
|
+
elif kattis_submission.date > submissions_by_user[user].last_comment or force_comment:
|
|
813
817
|
if dryrun:
|
|
814
818
|
warn(
|
|
815
819
|
f"would update {kattis_user2canvas_id[kattis_submission.user]} on problem {kattis_submission.problem} scored {kattis_submission.score}")
|
|
@@ -820,51 +824,67 @@ def submissions2canvas(offering, canvas_course, dryrun, assignment_group, sectio
|
|
|
820
824
|
info(
|
|
821
825
|
f"updated {submissions_by_user[user]} {kattis_user2canvas_id[kattis_submission.user]} for {assignment.title}")
|
|
822
826
|
else:
|
|
823
|
-
info(f"{user} up to date")
|
|
827
|
+
info(f"{user} up to date {kattis_submission.date} > {submissions_by_user[user].last_comment} {submissions_by_user[user].last_comment_text} ")
|
|
824
828
|
|
|
825
829
|
|
|
826
830
|
def get_best_submissions(offering: str, assignment_id: str) -> {str: {str: Submission}}:
|
|
827
831
|
best_submissions = collections.defaultdict(dict)
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
if not
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
832
|
+
base_url = f"https://{config.kattis_hostname}{offering}/assignments/{assignment_id}/submissions"
|
|
833
|
+
headers = None
|
|
834
|
+
page = 0
|
|
835
|
+
|
|
836
|
+
while True:
|
|
837
|
+
url = f"{base_url}?page={page}"
|
|
838
|
+
rsp = web_get(url)
|
|
839
|
+
bs = BeautifulSoup(rsp.content, "html.parser")
|
|
840
|
+
judge_table = bs.find("table", id="judge_table")
|
|
841
|
+
|
|
842
|
+
if not judge_table:
|
|
843
|
+
if page == 0:
|
|
844
|
+
info(f"no submissions yet for {assignment_id}")
|
|
845
|
+
break
|
|
846
|
+
|
|
847
|
+
if headers is None:
|
|
848
|
+
headers = [x.get_text().strip() for x in judge_table.find_all("th")]
|
|
849
|
+
|
|
850
|
+
tbody = judge_table.find("tbody")
|
|
851
|
+
rows = [r for r in tbody.find_all("tr", recursive=False) if r.get("data-submission-id")]
|
|
852
|
+
|
|
853
|
+
if not rows:
|
|
854
|
+
break
|
|
855
|
+
|
|
856
|
+
for row in rows:
|
|
857
|
+
cells = row.find_all("td", recursive=False)
|
|
858
|
+
if not cells:
|
|
859
|
+
continue
|
|
860
|
+
props = {}
|
|
861
|
+
for index, td in enumerate(cells):
|
|
862
|
+
a = td.find("a")
|
|
863
|
+
props[headers[index]] = a.get("href") if a else td.get_text().strip()
|
|
864
|
+
date = props["Date"]
|
|
865
|
+
if "-" in date:
|
|
866
|
+
date = datetime.datetime.strptime(date, "%Y-%m-%d %H:%M:%S").replace(tzinfo=now.tzinfo)
|
|
867
|
+
else:
|
|
868
|
+
hms = datetime.datetime.strptime(date, "%H:%M:%S")
|
|
869
|
+
date = now.replace(hour=hms.hour, minute=hms.minute, second=hms.second)
|
|
870
|
+
# it's not clear when the short date version is used. it might be used when it is less than 24 hours,
|
|
871
|
+
# in which case, just setting the time will make the date 24 hours more than it should be
|
|
872
|
+
if date > now:
|
|
873
|
+
date -= datetime.timedelta(days=1)
|
|
874
|
+
|
|
875
|
+
score = 0.0 if props["Test cases"] == "-/-" else float(Fraction(props["Test cases"])) * 100
|
|
876
|
+
submission = Submission(user=extract_last(props["User"]), problem=extract_last(props["Problem"]), date=date,
|
|
877
|
+
score=score, url=props[""])
|
|
878
|
+
if submission.problem not in best_submissions[submission.user]:
|
|
867
879
|
best_submissions[submission.user][submission.problem] = submission
|
|
880
|
+
else:
|
|
881
|
+
current_best = best_submissions[submission.user][submission.problem]
|
|
882
|
+
if current_best.score < submission.score or (
|
|
883
|
+
current_best.score == submission.score and current_best.date < submission.date):
|
|
884
|
+
best_submissions[submission.user][submission.problem] = submission
|
|
885
|
+
|
|
886
|
+
page += 1
|
|
887
|
+
|
|
868
888
|
return best_submissions
|
|
869
889
|
|
|
870
890
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|