canvaslms 5.4__tar.gz → 5.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.
Files changed (112) hide show
  1. {canvaslms-5.4 → canvaslms-5.6}/PKG-INFO +1 -1
  2. {canvaslms-5.4 → canvaslms-5.6}/pyproject.toml +1 -1
  3. {canvaslms-5.4 → canvaslms-5.6}/src/canvaslms/cli/modules.nw +22 -7
  4. {canvaslms-5.4 → canvaslms-5.6}/src/canvaslms/cli/quizzes.nw +767 -31
  5. {canvaslms-5.4 → canvaslms-5.6}/LICENSE +0 -0
  6. {canvaslms-5.4 → canvaslms-5.6}/README.md +0 -0
  7. {canvaslms-5.4 → canvaslms-5.6}/makefiles/.circleci/config.yml +0 -0
  8. {canvaslms-5.4 → canvaslms-5.6}/makefiles/.git +0 -0
  9. {canvaslms-5.4 → canvaslms-5.6}/makefiles/.gitignore +0 -0
  10. {canvaslms-5.4 → canvaslms-5.6}/makefiles/CONTRIBUTING.md +0 -0
  11. {canvaslms-5.4 → canvaslms-5.6}/makefiles/Dockerfile +0 -0
  12. {canvaslms-5.4 → canvaslms-5.6}/makefiles/Dockerfile.nw +0 -0
  13. {canvaslms-5.4 → canvaslms-5.6}/makefiles/Dockerfile.tex +0 -0
  14. {canvaslms-5.4 → canvaslms-5.6}/makefiles/LICENSE +0 -0
  15. {canvaslms-5.4 → canvaslms-5.6}/makefiles/Makefile +0 -0
  16. {canvaslms-5.4 → canvaslms-5.6}/makefiles/Makefile.nw +0 -0
  17. {canvaslms-5.4 → canvaslms-5.6}/makefiles/Makefile.tex +0 -0
  18. {canvaslms-5.4 → canvaslms-5.6}/makefiles/README.md +0 -0
  19. {canvaslms-5.4 → canvaslms-5.6}/makefiles/doc.mk +0 -0
  20. {canvaslms-5.4 → canvaslms-5.6}/makefiles/doc.mk.nw +0 -0
  21. {canvaslms-5.4 → canvaslms-5.6}/makefiles/doc.tex +0 -0
  22. {canvaslms-5.4 → canvaslms-5.6}/makefiles/exam.bib +0 -0
  23. {canvaslms-5.4 → canvaslms-5.6}/makefiles/exam.mk +0 -0
  24. {canvaslms-5.4 → canvaslms-5.6}/makefiles/exam.mk.nw +0 -0
  25. {canvaslms-5.4 → canvaslms-5.6}/makefiles/exam.tex +0 -0
  26. {canvaslms-5.4 → canvaslms-5.6}/makefiles/gitattributes +0 -0
  27. {canvaslms-5.4 → canvaslms-5.6}/makefiles/haskell.mk +0 -0
  28. {canvaslms-5.4 → canvaslms-5.6}/makefiles/haskell.mk.nw +0 -0
  29. {canvaslms-5.4 → canvaslms-5.6}/makefiles/haskell.tex +0 -0
  30. {canvaslms-5.4 → canvaslms-5.6}/makefiles/intro.tex +0 -0
  31. {canvaslms-5.4 → canvaslms-5.6}/makefiles/latexmkrc +0 -0
  32. {canvaslms-5.4 → canvaslms-5.6}/makefiles/ltxobj/_minted/AAA0D43723DCC5BE9DB71A96B52C1142.highlight.minted +0 -0
  33. {canvaslms-5.4 → canvaslms-5.6}/makefiles/ltxobj/_minted/E5724293DA12A769F97F0E91498CAEEF.highlight.minted +0 -0
  34. {canvaslms-5.4 → canvaslms-5.6}/makefiles/ltxobj/_minted/FFC039B25D180E99FC9FEBDB2D42EBAF.highlight.minted +0 -0
  35. {canvaslms-5.4 → canvaslms-5.6}/makefiles/ltxobj/_minted/_7945F0071C510291A619CE1658F673CB.index.minted +0 -0
  36. {canvaslms-5.4 → canvaslms-5.6}/makefiles/ltxobj/_minted/default.style.minted +0 -0
  37. {canvaslms-5.4 → canvaslms-5.6}/makefiles/ltxobj/makefiles.aux +0 -0
  38. {canvaslms-5.4 → canvaslms-5.6}/makefiles/ltxobj/makefiles.bbl +0 -0
  39. {canvaslms-5.4 → canvaslms-5.6}/makefiles/ltxobj/makefiles.bcf +0 -0
  40. {canvaslms-5.4 → canvaslms-5.6}/makefiles/ltxobj/makefiles.blg +0 -0
  41. {canvaslms-5.4 → canvaslms-5.6}/makefiles/ltxobj/makefiles.fdb_latexmk +0 -0
  42. {canvaslms-5.4 → canvaslms-5.6}/makefiles/ltxobj/makefiles.fls +0 -0
  43. {canvaslms-5.4 → canvaslms-5.6}/makefiles/ltxobj/makefiles.log +0 -0
  44. {canvaslms-5.4 → canvaslms-5.6}/makefiles/ltxobj/makefiles.out +0 -0
  45. {canvaslms-5.4 → canvaslms-5.6}/makefiles/ltxobj/makefiles.pdf +0 -0
  46. {canvaslms-5.4 → canvaslms-5.6}/makefiles/ltxobj/makefiles.run.xml +0 -0
  47. {canvaslms-5.4 → canvaslms-5.6}/makefiles/ltxobj/makefiles.toc +0 -0
  48. {canvaslms-5.4 → canvaslms-5.6}/makefiles/ltxobj/makefiles.xdv +0 -0
  49. {canvaslms-5.4 → canvaslms-5.6}/makefiles/makefiles.bib +0 -0
  50. {canvaslms-5.4 → canvaslms-5.6}/makefiles/makefiles.tex +0 -0
  51. {canvaslms-5.4 → canvaslms-5.6}/makefiles/miun.course.mk +0 -0
  52. {canvaslms-5.4 → canvaslms-5.6}/makefiles/miun.depend.mk +0 -0
  53. {canvaslms-5.4 → canvaslms-5.6}/makefiles/miun.docs.mk +0 -0
  54. {canvaslms-5.4 → canvaslms-5.6}/makefiles/miun.port.mk +0 -0
  55. {canvaslms-5.4 → canvaslms-5.6}/makefiles/miun.pub.mk +0 -0
  56. {canvaslms-5.4 → canvaslms-5.6}/makefiles/noweb.mk +0 -0
  57. {canvaslms-5.4 → canvaslms-5.6}/makefiles/noweb.mk.nw +0 -0
  58. {canvaslms-5.4 → canvaslms-5.6}/makefiles/noweb.tex +0 -0
  59. {canvaslms-5.4 → canvaslms-5.6}/makefiles/pkg.mk +0 -0
  60. {canvaslms-5.4 → canvaslms-5.6}/makefiles/pkg.mk.nw +0 -0
  61. {canvaslms-5.4 → canvaslms-5.6}/makefiles/pkg.tex +0 -0
  62. {canvaslms-5.4 → canvaslms-5.6}/makefiles/portability.mk +0 -0
  63. {canvaslms-5.4 → canvaslms-5.6}/makefiles/portability.mk.nw +0 -0
  64. {canvaslms-5.4 → canvaslms-5.6}/makefiles/portability.tex +0 -0
  65. {canvaslms-5.4 → canvaslms-5.6}/makefiles/preamble.tex +0 -0
  66. {canvaslms-5.4 → canvaslms-5.6}/makefiles/pub.mk +0 -0
  67. {canvaslms-5.4 → canvaslms-5.6}/makefiles/pub.mk.nw +0 -0
  68. {canvaslms-5.4 → canvaslms-5.6}/makefiles/pub.tex +0 -0
  69. {canvaslms-5.4 → canvaslms-5.6}/makefiles/results.mk +0 -0
  70. {canvaslms-5.4 → canvaslms-5.6}/makefiles/results.mk.nw +0 -0
  71. {canvaslms-5.4 → canvaslms-5.6}/makefiles/results.tex +0 -0
  72. {canvaslms-5.4 → canvaslms-5.6}/makefiles/subdir.mk +0 -0
  73. {canvaslms-5.4 → canvaslms-5.6}/makefiles/subdir.mk.nw +0 -0
  74. {canvaslms-5.4 → canvaslms-5.6}/makefiles/subdir.tex +0 -0
  75. {canvaslms-5.4 → canvaslms-5.6}/makefiles/tex.bib +0 -0
  76. {canvaslms-5.4 → canvaslms-5.6}/makefiles/tex.mk +0 -0
  77. {canvaslms-5.4 → canvaslms-5.6}/makefiles/tex.mk.nw +0 -0
  78. {canvaslms-5.4 → canvaslms-5.6}/makefiles/tex.tex +0 -0
  79. {canvaslms-5.4 → canvaslms-5.6}/makefiles/transform.bib +0 -0
  80. {canvaslms-5.4 → canvaslms-5.6}/makefiles/transform.mk +0 -0
  81. {canvaslms-5.4 → canvaslms-5.6}/makefiles/transform.mk.nw +0 -0
  82. {canvaslms-5.4 → canvaslms-5.6}/makefiles/transform.tex +0 -0
  83. {canvaslms-5.4 → canvaslms-5.6}/src/canvaslms/Makefile +0 -0
  84. {canvaslms-5.4 → canvaslms-5.6}/src/canvaslms/__init__.py +0 -0
  85. {canvaslms-5.4 → canvaslms-5.6}/src/canvaslms/cli/Makefile +0 -0
  86. {canvaslms-5.4 → canvaslms-5.6}/src/canvaslms/cli/assignments.nw +0 -0
  87. {canvaslms-5.4 → canvaslms-5.6}/src/canvaslms/cli/cache.nw +0 -0
  88. {canvaslms-5.4 → canvaslms-5.6}/src/canvaslms/cli/calendar.nw +0 -0
  89. {canvaslms-5.4 → canvaslms-5.6}/src/canvaslms/cli/cli.nw +0 -0
  90. {canvaslms-5.4 → canvaslms-5.6}/src/canvaslms/cli/content.nw +0 -0
  91. {canvaslms-5.4 → canvaslms-5.6}/src/canvaslms/cli/courses.nw +0 -0
  92. {canvaslms-5.4 → canvaslms-5.6}/src/canvaslms/cli/discussions.nw +0 -0
  93. {canvaslms-5.4 → canvaslms-5.6}/src/canvaslms/cli/grade.nw +0 -0
  94. {canvaslms-5.4 → canvaslms-5.6}/src/canvaslms/cli/login.nw +0 -0
  95. {canvaslms-5.4 → canvaslms-5.6}/src/canvaslms/cli/pages.nw +0 -0
  96. {canvaslms-5.4 → canvaslms-5.6}/src/canvaslms/cli/results.nw +0 -0
  97. {canvaslms-5.4 → canvaslms-5.6}/src/canvaslms/cli/results.py.broken +0 -0
  98. {canvaslms-5.4 → canvaslms-5.6}/src/canvaslms/cli/submissions.nw +0 -0
  99. {canvaslms-5.4 → canvaslms-5.6}/src/canvaslms/cli/users.nw +0 -0
  100. {canvaslms-5.4 → canvaslms-5.6}/src/canvaslms/cli/utils.nw +0 -0
  101. {canvaslms-5.4 → canvaslms-5.6}/src/canvaslms/grades/Makefile +0 -0
  102. {canvaslms-5.4 → canvaslms-5.6}/src/canvaslms/grades/conjunctavg.nw +0 -0
  103. {canvaslms-5.4 → canvaslms-5.6}/src/canvaslms/grades/conjunctavgsurvey.nw +0 -0
  104. {canvaslms-5.4 → canvaslms-5.6}/src/canvaslms/grades/disjunctmax.nw +0 -0
  105. {canvaslms-5.4 → canvaslms-5.6}/src/canvaslms/grades/grades.nw +0 -0
  106. {canvaslms-5.4 → canvaslms-5.6}/src/canvaslms/grades/grades.py +0 -0
  107. {canvaslms-5.4 → canvaslms-5.6}/src/canvaslms/grades/maxgradesurvey.nw +0 -0
  108. {canvaslms-5.4 → canvaslms-5.6}/src/canvaslms/grades/tilkryLAB1.nw +0 -0
  109. {canvaslms-5.4 → canvaslms-5.6}/src/canvaslms/hacks/Makefile +0 -0
  110. {canvaslms-5.4 → canvaslms-5.6}/src/canvaslms/hacks/__init__.py +0 -0
  111. {canvaslms-5.4 → canvaslms-5.6}/src/canvaslms/hacks/attachment_cache.nw +0 -0
  112. {canvaslms-5.4 → canvaslms-5.6}/src/canvaslms/hacks/canvasapi.nw +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: canvaslms
3
- Version: 5.4
3
+ Version: 5.6
4
4
  Summary: Command-line interface to Canvas LMS
5
5
  License-Expression: MIT
6
6
  License-File: LICENSE
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "canvaslms"
3
- version = "5.4"
3
+ version = "5.6"
4
4
  description = "Command-line interface to Canvas LMS"
5
5
  authors = [
6
6
  {name = "Daniel Bosk", email = "daniel@bosk.se"}
@@ -486,6 +486,14 @@ def get_item_modules(course, item_type, item_id):
486
486
  Returns:
487
487
  List of module names containing this item
488
488
  """
489
+ target_url = None
490
+ if item_type == 'Page':
491
+ try:
492
+ target_url = course.get_page(item_id).url
493
+ except Exception:
494
+ # If we can't resolve the target page, fall back to raw comparisons.
495
+ target_url = item_id
496
+
489
497
  modules = []
490
498
  for module in course.get_modules():
491
499
  try:
@@ -514,10 +522,10 @@ elif item_type == 'Page':
514
522
  if item.page_url == item_id:
515
523
  modules.append(module.name)
516
524
  break
517
- # Check if URLs resolve to same page (handles redirects)
525
+ # Compare canonical URLs to avoid duplicates when Canvas redirects old slugs.
518
526
  try:
519
527
  resolved_page = course.get_page(item.page_url)
520
- if resolved_page.url == item_id:
528
+ if resolved_page.url == target_url:
521
529
  modules.append(module.name)
522
530
  break
523
531
  except Exception:
@@ -598,11 +606,18 @@ with its new canonical URL.
598
606
  Without handling this, the direct comparison [[item.page_url == item_id]] would
599
607
  fail, causing the page to be added to the module again (creating duplicates).
600
608
 
601
- To detect this, we fetch the page using the module item's [[page_url]] and
602
- compare its canonical [[url]] attribute with [[item_id]]. This adds an API call
603
- per page item, but only when the direct comparison fails.
609
+ To detect this, we fetch both the target page ([[item_id]]) and the module
610
+ item's page ([[item.page_url]]) and compare canonical [[url]] values. This adds
611
+ API calls, but only when the direct comparison fails.
604
612
  <<find current module item if present>>=
605
613
  current_item = None
614
+ canonical_page_url = None
615
+ if item_type == 'Page':
616
+ try:
617
+ canonical_page_url = course.get_page(item_id).url
618
+ except Exception:
619
+ canonical_page_url = item_id
620
+
606
621
  try:
607
622
  for item in module.get_module_items():
608
623
  if not hasattr(item, 'type') or item.type != item_type:
@@ -625,10 +640,10 @@ Canvas has created a redirect from an old URL to a new one.
625
640
  if item.page_url == item_id:
626
641
  current_item = item
627
642
  break
628
- # URLs don't match directly; check if they resolve to same page
643
+ # URLs don't match directly; compare canonical URLs to avoid duplicates.
629
644
  try:
630
645
  resolved_page = course.get_page(item.page_url)
631
- if resolved_page.url == item_id:
646
+ if resolved_page.url == canonical_page_url:
632
647
  current_item = item
633
648
  break
634
649
  except Exception: