canvaslms 5.1__tar.gz → 5.2__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.1 → canvaslms-5.2}/PKG-INFO +1 -1
  2. {canvaslms-5.1 → canvaslms-5.2}/pyproject.toml +1 -1
  3. {canvaslms-5.1 → canvaslms-5.2}/src/canvaslms/cli/pages.nw +59 -11
  4. {canvaslms-5.1 → canvaslms-5.2}/LICENSE +0 -0
  5. {canvaslms-5.1 → canvaslms-5.2}/README.md +0 -0
  6. {canvaslms-5.1 → canvaslms-5.2}/makefiles/.circleci/config.yml +0 -0
  7. {canvaslms-5.1 → canvaslms-5.2}/makefiles/.git +0 -0
  8. {canvaslms-5.1 → canvaslms-5.2}/makefiles/.gitignore +0 -0
  9. {canvaslms-5.1 → canvaslms-5.2}/makefiles/CONTRIBUTING.md +0 -0
  10. {canvaslms-5.1 → canvaslms-5.2}/makefiles/Dockerfile +0 -0
  11. {canvaslms-5.1 → canvaslms-5.2}/makefiles/Dockerfile.nw +0 -0
  12. {canvaslms-5.1 → canvaslms-5.2}/makefiles/Dockerfile.tex +0 -0
  13. {canvaslms-5.1 → canvaslms-5.2}/makefiles/LICENSE +0 -0
  14. {canvaslms-5.1 → canvaslms-5.2}/makefiles/Makefile +0 -0
  15. {canvaslms-5.1 → canvaslms-5.2}/makefiles/Makefile.nw +0 -0
  16. {canvaslms-5.1 → canvaslms-5.2}/makefiles/Makefile.tex +0 -0
  17. {canvaslms-5.1 → canvaslms-5.2}/makefiles/README.md +0 -0
  18. {canvaslms-5.1 → canvaslms-5.2}/makefiles/doc.mk +0 -0
  19. {canvaslms-5.1 → canvaslms-5.2}/makefiles/doc.mk.nw +0 -0
  20. {canvaslms-5.1 → canvaslms-5.2}/makefiles/doc.tex +0 -0
  21. {canvaslms-5.1 → canvaslms-5.2}/makefiles/exam.bib +0 -0
  22. {canvaslms-5.1 → canvaslms-5.2}/makefiles/exam.mk +0 -0
  23. {canvaslms-5.1 → canvaslms-5.2}/makefiles/exam.mk.nw +0 -0
  24. {canvaslms-5.1 → canvaslms-5.2}/makefiles/exam.tex +0 -0
  25. {canvaslms-5.1 → canvaslms-5.2}/makefiles/gitattributes +0 -0
  26. {canvaslms-5.1 → canvaslms-5.2}/makefiles/haskell.mk +0 -0
  27. {canvaslms-5.1 → canvaslms-5.2}/makefiles/haskell.mk.nw +0 -0
  28. {canvaslms-5.1 → canvaslms-5.2}/makefiles/haskell.tex +0 -0
  29. {canvaslms-5.1 → canvaslms-5.2}/makefiles/intro.tex +0 -0
  30. {canvaslms-5.1 → canvaslms-5.2}/makefiles/latexmkrc +0 -0
  31. {canvaslms-5.1 → canvaslms-5.2}/makefiles/ltxobj/_minted/AAA0D43723DCC5BE9DB71A96B52C1142.highlight.minted +0 -0
  32. {canvaslms-5.1 → canvaslms-5.2}/makefiles/ltxobj/_minted/E5724293DA12A769F97F0E91498CAEEF.highlight.minted +0 -0
  33. {canvaslms-5.1 → canvaslms-5.2}/makefiles/ltxobj/_minted/FFC039B25D180E99FC9FEBDB2D42EBAF.highlight.minted +0 -0
  34. {canvaslms-5.1 → canvaslms-5.2}/makefiles/ltxobj/_minted/_7945F0071C510291A619CE1658F673CB.index.minted +0 -0
  35. {canvaslms-5.1 → canvaslms-5.2}/makefiles/ltxobj/_minted/default.style.minted +0 -0
  36. {canvaslms-5.1 → canvaslms-5.2}/makefiles/ltxobj/makefiles.aux +0 -0
  37. {canvaslms-5.1 → canvaslms-5.2}/makefiles/ltxobj/makefiles.bbl +0 -0
  38. {canvaslms-5.1 → canvaslms-5.2}/makefiles/ltxobj/makefiles.bcf +0 -0
  39. {canvaslms-5.1 → canvaslms-5.2}/makefiles/ltxobj/makefiles.blg +0 -0
  40. {canvaslms-5.1 → canvaslms-5.2}/makefiles/ltxobj/makefiles.fdb_latexmk +0 -0
  41. {canvaslms-5.1 → canvaslms-5.2}/makefiles/ltxobj/makefiles.fls +0 -0
  42. {canvaslms-5.1 → canvaslms-5.2}/makefiles/ltxobj/makefiles.log +0 -0
  43. {canvaslms-5.1 → canvaslms-5.2}/makefiles/ltxobj/makefiles.out +0 -0
  44. {canvaslms-5.1 → canvaslms-5.2}/makefiles/ltxobj/makefiles.pdf +0 -0
  45. {canvaslms-5.1 → canvaslms-5.2}/makefiles/ltxobj/makefiles.run.xml +0 -0
  46. {canvaslms-5.1 → canvaslms-5.2}/makefiles/ltxobj/makefiles.toc +0 -0
  47. {canvaslms-5.1 → canvaslms-5.2}/makefiles/ltxobj/makefiles.xdv +0 -0
  48. {canvaslms-5.1 → canvaslms-5.2}/makefiles/makefiles.bib +0 -0
  49. {canvaslms-5.1 → canvaslms-5.2}/makefiles/makefiles.tex +0 -0
  50. {canvaslms-5.1 → canvaslms-5.2}/makefiles/miun.course.mk +0 -0
  51. {canvaslms-5.1 → canvaslms-5.2}/makefiles/miun.depend.mk +0 -0
  52. {canvaslms-5.1 → canvaslms-5.2}/makefiles/miun.docs.mk +0 -0
  53. {canvaslms-5.1 → canvaslms-5.2}/makefiles/miun.port.mk +0 -0
  54. {canvaslms-5.1 → canvaslms-5.2}/makefiles/miun.pub.mk +0 -0
  55. {canvaslms-5.1 → canvaslms-5.2}/makefiles/noweb.mk +0 -0
  56. {canvaslms-5.1 → canvaslms-5.2}/makefiles/noweb.mk.nw +0 -0
  57. {canvaslms-5.1 → canvaslms-5.2}/makefiles/noweb.tex +0 -0
  58. {canvaslms-5.1 → canvaslms-5.2}/makefiles/pkg.mk +0 -0
  59. {canvaslms-5.1 → canvaslms-5.2}/makefiles/pkg.mk.nw +0 -0
  60. {canvaslms-5.1 → canvaslms-5.2}/makefiles/pkg.tex +0 -0
  61. {canvaslms-5.1 → canvaslms-5.2}/makefiles/portability.mk +0 -0
  62. {canvaslms-5.1 → canvaslms-5.2}/makefiles/portability.mk.nw +0 -0
  63. {canvaslms-5.1 → canvaslms-5.2}/makefiles/portability.tex +0 -0
  64. {canvaslms-5.1 → canvaslms-5.2}/makefiles/preamble.tex +0 -0
  65. {canvaslms-5.1 → canvaslms-5.2}/makefiles/pub.mk +0 -0
  66. {canvaslms-5.1 → canvaslms-5.2}/makefiles/pub.mk.nw +0 -0
  67. {canvaslms-5.1 → canvaslms-5.2}/makefiles/pub.tex +0 -0
  68. {canvaslms-5.1 → canvaslms-5.2}/makefiles/results.mk +0 -0
  69. {canvaslms-5.1 → canvaslms-5.2}/makefiles/results.mk.nw +0 -0
  70. {canvaslms-5.1 → canvaslms-5.2}/makefiles/results.tex +0 -0
  71. {canvaslms-5.1 → canvaslms-5.2}/makefiles/subdir.mk +0 -0
  72. {canvaslms-5.1 → canvaslms-5.2}/makefiles/subdir.mk.nw +0 -0
  73. {canvaslms-5.1 → canvaslms-5.2}/makefiles/subdir.tex +0 -0
  74. {canvaslms-5.1 → canvaslms-5.2}/makefiles/tex.bib +0 -0
  75. {canvaslms-5.1 → canvaslms-5.2}/makefiles/tex.mk +0 -0
  76. {canvaslms-5.1 → canvaslms-5.2}/makefiles/tex.mk.nw +0 -0
  77. {canvaslms-5.1 → canvaslms-5.2}/makefiles/tex.tex +0 -0
  78. {canvaslms-5.1 → canvaslms-5.2}/makefiles/transform.bib +0 -0
  79. {canvaslms-5.1 → canvaslms-5.2}/makefiles/transform.mk +0 -0
  80. {canvaslms-5.1 → canvaslms-5.2}/makefiles/transform.mk.nw +0 -0
  81. {canvaslms-5.1 → canvaslms-5.2}/makefiles/transform.tex +0 -0
  82. {canvaslms-5.1 → canvaslms-5.2}/src/canvaslms/Makefile +0 -0
  83. {canvaslms-5.1 → canvaslms-5.2}/src/canvaslms/__init__.py +0 -0
  84. {canvaslms-5.1 → canvaslms-5.2}/src/canvaslms/cli/Makefile +0 -0
  85. {canvaslms-5.1 → canvaslms-5.2}/src/canvaslms/cli/assignments.nw +0 -0
  86. {canvaslms-5.1 → canvaslms-5.2}/src/canvaslms/cli/cache.nw +0 -0
  87. {canvaslms-5.1 → canvaslms-5.2}/src/canvaslms/cli/calendar.nw +0 -0
  88. {canvaslms-5.1 → canvaslms-5.2}/src/canvaslms/cli/cli.nw +0 -0
  89. {canvaslms-5.1 → canvaslms-5.2}/src/canvaslms/cli/content.nw +0 -0
  90. {canvaslms-5.1 → canvaslms-5.2}/src/canvaslms/cli/courses.nw +0 -0
  91. {canvaslms-5.1 → canvaslms-5.2}/src/canvaslms/cli/discussions.nw +0 -0
  92. {canvaslms-5.1 → canvaslms-5.2}/src/canvaslms/cli/grade.nw +0 -0
  93. {canvaslms-5.1 → canvaslms-5.2}/src/canvaslms/cli/login.nw +0 -0
  94. {canvaslms-5.1 → canvaslms-5.2}/src/canvaslms/cli/modules.nw +0 -0
  95. {canvaslms-5.1 → canvaslms-5.2}/src/canvaslms/cli/quizzes.nw +0 -0
  96. {canvaslms-5.1 → canvaslms-5.2}/src/canvaslms/cli/results.nw +0 -0
  97. {canvaslms-5.1 → canvaslms-5.2}/src/canvaslms/cli/results.py.broken +0 -0
  98. {canvaslms-5.1 → canvaslms-5.2}/src/canvaslms/cli/submissions.nw +0 -0
  99. {canvaslms-5.1 → canvaslms-5.2}/src/canvaslms/cli/users.nw +0 -0
  100. {canvaslms-5.1 → canvaslms-5.2}/src/canvaslms/cli/utils.nw +0 -0
  101. {canvaslms-5.1 → canvaslms-5.2}/src/canvaslms/grades/Makefile +0 -0
  102. {canvaslms-5.1 → canvaslms-5.2}/src/canvaslms/grades/conjunctavg.nw +0 -0
  103. {canvaslms-5.1 → canvaslms-5.2}/src/canvaslms/grades/conjunctavgsurvey.nw +0 -0
  104. {canvaslms-5.1 → canvaslms-5.2}/src/canvaslms/grades/disjunctmax.nw +0 -0
  105. {canvaslms-5.1 → canvaslms-5.2}/src/canvaslms/grades/grades.nw +0 -0
  106. {canvaslms-5.1 → canvaslms-5.2}/src/canvaslms/grades/grades.py +0 -0
  107. {canvaslms-5.1 → canvaslms-5.2}/src/canvaslms/grades/maxgradesurvey.nw +0 -0
  108. {canvaslms-5.1 → canvaslms-5.2}/src/canvaslms/grades/tilkryLAB1.nw +0 -0
  109. {canvaslms-5.1 → canvaslms-5.2}/src/canvaslms/hacks/Makefile +0 -0
  110. {canvaslms-5.1 → canvaslms-5.2}/src/canvaslms/hacks/__init__.py +0 -0
  111. {canvaslms-5.1 → canvaslms-5.2}/src/canvaslms/hacks/attachment_cache.nw +0 -0
  112. {canvaslms-5.1 → canvaslms-5.2}/src/canvaslms/hacks/canvasapi.nw +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: canvaslms
3
- Version: 5.1
3
+ Version: 5.2
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.1"
3
+ version = "5.2"
4
4
  description = "Command-line interface to Canvas LMS"
5
5
  authors = [
6
6
  {name = "Daniel Bosk", email = "daniel@bosk.se"}
@@ -403,8 +403,9 @@ specific page to update. This enables a Git-based workflow where the page can
403
403
  be reliably identified even if the title changes. If the URL is not found and
404
404
  [[--create]] is specified, we create a new page instead.
405
405
 
406
- If no [[url]] is in the YAML, we fall back to the filter-based matching using
407
- [[-p]] and [[-M]] options (the existing behavior).
406
+ If no [[url]] is in the YAML, we try title-based matching first (using the
407
+ [[title]] field from the front matter), then fall back to filter-based matching
408
+ using [[-p]] and [[-M]] options only if no title is specified.
408
409
  <<update pages with new content>>=
409
410
  if args.html:
410
411
  html_content = body_content # Already HTML, no conversion needed
@@ -515,18 +516,65 @@ if 'modules' in attributes:
515
516
  print(f" Added to modules: {', '.join(added)}", file=sys.stderr)
516
517
  @
517
518
 
518
- \subsubsection{Filter-based page matching}
519
+ \subsubsection{Title-based page identification}
519
520
 
520
- When no URL is specified in the YAML, we use the filter options ([[-p]], [[-M]])
521
- to find matching pages. This maintains backwards compatibility with the original
522
- behavior.
523
- <<update pages by filter matching>>=
524
- pages = process_page_option(canvas, args)
521
+ When no [[url]] is specified in the YAML but a [[title]] is present, we use the
522
+ title to find the page. This is the most common case when creating or updating
523
+ pages from Markdown files: the user specifies a title in the front matter and
524
+ expects the command to find or create a page with that title.
525
525
 
526
- for page in pages:
527
- full_page = page.course.get_page(page.url)
528
- full_page.course = page.course
526
+ We use exact title matching (not regex) to avoid accidentally updating multiple
527
+ pages. If exactly one page matches, we update it. If no pages match and
528
+ [[--create]] is specified, we create a new page. If multiple pages match, we
529
+ report an error---the user should add a [[url]] field to disambiguate.
530
+ <<update or create page by title>>=
531
+ title = attributes['title']
532
+ course_list = canvaslms.cli.courses.process_course_option(canvas, args)
533
+ if not course_list:
534
+ print("Error: No courses found matching criteria", file=sys.stderr)
535
+ return
536
+
537
+ course = course_list[0]
538
+
539
+ matching_pages = [p for p in course.get_pages() if p.title == title]
540
+
541
+ if len(matching_pages) == 1:
542
+ full_page = course.get_page(matching_pages[0].url)
543
+ full_page.course = course
529
544
  <<update existing page>>
545
+ elif len(matching_pages) == 0:
546
+ if args.create:
547
+ <<create new page>>
548
+ else:
549
+ print(f"Error: Page '{title}' not found. "
550
+ f"Use --create to create a new page.", file=sys.stderr)
551
+ return
552
+ else:
553
+ print(f"Error: Multiple pages with title '{title}' found. "
554
+ f"Add 'url' field to YAML to identify specific page.", file=sys.stderr)
555
+ return
556
+ @
557
+
558
+ \subsubsection{Filter-based page matching}
559
+
560
+ When neither [[url]] nor [[title]] is specified in the YAML, we fall back to the
561
+ filter options ([[-p]], [[-M]]) to find matching pages. This is a rare case but
562
+ maintains backwards compatibility. We add a safety check: if multiple pages
563
+ match, we report an error rather than updating all of them.
564
+ <<update pages by filter matching>>=
565
+ if 'title' in attributes and attributes['title']:
566
+ <<update or create page by title>>
567
+ else:
568
+ pages = process_page_option(canvas, args)
569
+ if len(pages) > 1:
570
+ print(f"Error: {len(pages)} pages match filter. "
571
+ f"Add 'title' or 'url' to YAML, or use -p to narrow selection.",
572
+ file=sys.stderr)
573
+ return
574
+ for page in pages:
575
+ full_page = page.course.get_page(page.url)
576
+ full_page.course = page.course
577
+ <<update existing page>>
530
578
  @
531
579
 
532
580
  We add optional attributes only if they are present in the YAML front matter.
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
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
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
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
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
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes