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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: kattis2canvas
3
- Version: 0.1.5
3
+ Version: 0.1.6
4
4
  Summary: CLI tool to integrate Kattis offerings with Canvas LMS courses
5
5
  Author: bcr33d
6
6
  License-Expression: MIT
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "kattis2canvas"
7
- version = "0.1.5"
7
+ version = "0.1.6"
8
8
  description = "CLI tool to integrate Kattis offerings with Canvas LMS courses"
9
9
  readme = "README.md"
10
10
  license = "MIT"
@@ -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
- def submissions2canvas(offering, canvas_course, dryrun, assignment_group, section):
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
- url = f"https://{config.kattis_hostname}{offering}/assignments/{assignment_id}/submissions"
829
- rsp = web_get(url)
830
- bs = BeautifulSoup(rsp.content, "html.parser")
831
- judge_table = bs.find("table", id="judge_table")
832
- if not judge_table:
833
- info(f"no submissions yet for {assignment_id}")
834
- return best_submissions
835
- headers = [x.get_text().strip() for x in judge_table.find_all("th")]
836
- tbody = judge_table.find("tbody")
837
- for submissions in tbody.find_all("tr", recursive=False):
838
- if not submissions.get("data-submission-id"):
839
- continue
840
- submissions = submissions.find_all("td", recursive=False)
841
- if not submissions:
842
- continue
843
- props = {}
844
- for index, td in enumerate(submissions):
845
- a = td.find("a")
846
- props[headers[index]] = a.get("href") if a else td.get_text().strip()
847
- date = props["Date"]
848
- if "-" in date:
849
- date = datetime.datetime.strptime(date, "%Y-%m-%d %H:%M:%S").replace(tzinfo=now.tzinfo)
850
- else:
851
- hms = datetime.datetime.strptime(date, "%H:%M:%S")
852
- date = now.replace(hour=hms.hour, minute=hms.minute, second=hms.second)
853
- # it's not clear when the short date version is used. it might be used when it is less than 24 hours,
854
- # in which case, just setting the time will make the date 24 hours more than it should be
855
- if date > now:
856
- date -= datetime.timedelta(days=1)
857
-
858
- score = 0.0 if props["Test cases"] == "-/-" else float(Fraction(props["Test cases"])) * 100
859
- submission = Submission(user=extract_last(props["User"]), problem=extract_last(props["Problem"]), date=date,
860
- score=score, url=props[""])
861
- if submission.problem not in best_submissions[submission.user]:
862
- best_submissions[submission.user] = {submission.problem: submission}
863
- else:
864
- current_best = best_submissions[submission.user][submission.problem]
865
- if current_best.score < submission.score or (
866
- current_best.score == submission.score and current_best.date < submission.date):
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
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: kattis2canvas
3
- Version: 0.1.5
3
+ Version: 0.1.6
4
4
  Summary: CLI tool to integrate Kattis offerings with Canvas LMS courses
5
5
  Author: bcr33d
6
6
  License-Expression: MIT
File without changes
File without changes