canvaslms 5.1__py3-none-any.whl → 5.2__py3-none-any.whl
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.
- canvaslms/cli/pages.nw +59 -11
- canvaslms/cli/pages.py +161 -37
- {canvaslms-5.1.dist-info → canvaslms-5.2.dist-info}/METADATA +1 -1
- {canvaslms-5.1.dist-info → canvaslms-5.2.dist-info}/RECORD +7 -7
- {canvaslms-5.1.dist-info → canvaslms-5.2.dist-info}/WHEEL +0 -0
- {canvaslms-5.1.dist-info → canvaslms-5.2.dist-info}/entry_points.txt +0 -0
- {canvaslms-5.1.dist-info → canvaslms-5.2.dist-info}/licenses/LICENSE +0 -0
canvaslms/cli/pages.nw
CHANGED
|
@@ -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
|
|
407
|
-
[[
|
|
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{
|
|
519
|
+
\subsubsection{Title-based page identification}
|
|
519
520
|
|
|
520
|
-
When no
|
|
521
|
-
to find
|
|
522
|
-
|
|
523
|
-
|
|
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
|
-
|
|
527
|
-
|
|
528
|
-
|
|
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.
|
canvaslms/cli/pages.py
CHANGED
|
@@ -296,53 +296,177 @@ def pages_edit_command(config, canvas, args):
|
|
|
296
296
|
)
|
|
297
297
|
return
|
|
298
298
|
else:
|
|
299
|
-
|
|
299
|
+
if "title" in attributes and attributes["title"]:
|
|
300
|
+
title = attributes["title"]
|
|
301
|
+
course_list = canvaslms.cli.courses.process_course_option(canvas, args)
|
|
302
|
+
if not course_list:
|
|
303
|
+
print("Error: No courses found matching criteria", file=sys.stderr)
|
|
304
|
+
return
|
|
300
305
|
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
306
|
+
course = course_list[0]
|
|
307
|
+
|
|
308
|
+
matching_pages = [p for p in course.get_pages() if p.title == title]
|
|
309
|
+
|
|
310
|
+
if len(matching_pages) == 1:
|
|
311
|
+
full_page = course.get_page(matching_pages[0].url)
|
|
312
|
+
full_page.course = course
|
|
313
|
+
update_data = {
|
|
314
|
+
"wiki_page": {
|
|
315
|
+
"title": attributes.get("title", full_page.title),
|
|
316
|
+
"body": html_content,
|
|
317
|
+
}
|
|
308
318
|
}
|
|
309
|
-
}
|
|
310
319
|
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
320
|
+
if "published" in attributes:
|
|
321
|
+
update_data["wiki_page"]["published"] = attributes["published"]
|
|
322
|
+
if "front_page" in attributes:
|
|
323
|
+
update_data["wiki_page"]["front_page"] = attributes[
|
|
324
|
+
"front_page"
|
|
325
|
+
]
|
|
326
|
+
if "editing_roles" in attributes and attributes["editing_roles"]:
|
|
327
|
+
update_data["wiki_page"]["editing_roles"] = attributes[
|
|
328
|
+
"editing_roles"
|
|
329
|
+
]
|
|
319
330
|
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
)
|
|
331
|
-
if added:
|
|
332
|
-
print(
|
|
333
|
-
f" Added to modules: {', '.join(added)}",
|
|
334
|
-
file=sys.stderr,
|
|
331
|
+
try:
|
|
332
|
+
full_page.edit(**update_data)
|
|
333
|
+
full_page._fetched_at = datetime.now()
|
|
334
|
+
if hasattr(full_page.course, "page_cache"):
|
|
335
|
+
full_page.course.page_cache[full_page.url] = (full_page, {})
|
|
336
|
+
logger.info(f"Updated page: {full_page.title}")
|
|
337
|
+
if "modules" in attributes:
|
|
338
|
+
module_regexes = attributes["modules"]
|
|
339
|
+
added, removed = canvaslms.cli.modules.update_item_modules(
|
|
340
|
+
full_page.course, "Page", full_page.url, module_regexes
|
|
335
341
|
)
|
|
336
|
-
|
|
342
|
+
if added:
|
|
343
|
+
print(
|
|
344
|
+
f" Added to modules: {', '.join(added)}",
|
|
345
|
+
file=sys.stderr,
|
|
346
|
+
)
|
|
347
|
+
if removed:
|
|
348
|
+
print(
|
|
349
|
+
f" Removed from modules: {', '.join(removed)}",
|
|
350
|
+
file=sys.stderr,
|
|
351
|
+
)
|
|
352
|
+
except Exception as e:
|
|
353
|
+
logger.error(f"Error updating page '{full_page.title}': {e}")
|
|
354
|
+
print(
|
|
355
|
+
f"Error updating page '{full_page.title}': {e}",
|
|
356
|
+
file=sys.stderr,
|
|
357
|
+
)
|
|
358
|
+
elif len(matching_pages) == 0:
|
|
359
|
+
if args.create:
|
|
360
|
+
create_params = {
|
|
361
|
+
"title": attributes.get("title", "Untitled Page"),
|
|
362
|
+
"body": html_content,
|
|
363
|
+
}
|
|
364
|
+
if "published" in attributes:
|
|
365
|
+
create_params["published"] = attributes["published"]
|
|
366
|
+
if "front_page" in attributes:
|
|
367
|
+
create_params["front_page"] = attributes["front_page"]
|
|
368
|
+
if (
|
|
369
|
+
"editing_roles" in attributes
|
|
370
|
+
and attributes["editing_roles"]
|
|
371
|
+
):
|
|
372
|
+
create_params["editing_roles"] = attributes["editing_roles"]
|
|
373
|
+
|
|
374
|
+
try:
|
|
375
|
+
new_page = course.create_page(wiki_page=create_params)
|
|
376
|
+
new_page.course = course
|
|
337
377
|
print(
|
|
338
|
-
f"
|
|
378
|
+
f"Created page: {new_page.title} (url: {new_page.url})",
|
|
339
379
|
file=sys.stderr,
|
|
340
380
|
)
|
|
341
|
-
|
|
342
|
-
|
|
381
|
+
if "modules" in attributes:
|
|
382
|
+
module_regexes = attributes["modules"]
|
|
383
|
+
added, removed = (
|
|
384
|
+
canvaslms.cli.modules.update_item_modules(
|
|
385
|
+
new_page.course,
|
|
386
|
+
"Page",
|
|
387
|
+
new_page.url,
|
|
388
|
+
module_regexes,
|
|
389
|
+
)
|
|
390
|
+
)
|
|
391
|
+
if added:
|
|
392
|
+
print(
|
|
393
|
+
f" Added to modules: {', '.join(added)}",
|
|
394
|
+
file=sys.stderr,
|
|
395
|
+
)
|
|
396
|
+
except Exception as e:
|
|
397
|
+
logger.error(f"Error creating page: {e}")
|
|
398
|
+
print(f"Error creating page: {e}", file=sys.stderr)
|
|
399
|
+
else:
|
|
400
|
+
print(
|
|
401
|
+
f"Error: Page '{title}' not found. "
|
|
402
|
+
f"Use --create to create a new page.",
|
|
403
|
+
file=sys.stderr,
|
|
404
|
+
)
|
|
405
|
+
return
|
|
406
|
+
else:
|
|
343
407
|
print(
|
|
344
|
-
f"Error
|
|
408
|
+
f"Error: Multiple pages with title '{title}' found. "
|
|
409
|
+
f"Add 'url' field to YAML to identify specific page.",
|
|
410
|
+
file=sys.stderr,
|
|
345
411
|
)
|
|
412
|
+
return
|
|
413
|
+
else:
|
|
414
|
+
pages = process_page_option(canvas, args)
|
|
415
|
+
if len(pages) > 1:
|
|
416
|
+
print(
|
|
417
|
+
f"Error: {len(pages)} pages match filter. "
|
|
418
|
+
f"Add 'title' or 'url' to YAML, or use -p to narrow selection.",
|
|
419
|
+
file=sys.stderr,
|
|
420
|
+
)
|
|
421
|
+
return
|
|
422
|
+
for page in pages:
|
|
423
|
+
full_page = page.course.get_page(page.url)
|
|
424
|
+
full_page.course = page.course
|
|
425
|
+
update_data = {
|
|
426
|
+
"wiki_page": {
|
|
427
|
+
"title": attributes.get("title", full_page.title),
|
|
428
|
+
"body": html_content,
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
if "published" in attributes:
|
|
433
|
+
update_data["wiki_page"]["published"] = attributes["published"]
|
|
434
|
+
if "front_page" in attributes:
|
|
435
|
+
update_data["wiki_page"]["front_page"] = attributes[
|
|
436
|
+
"front_page"
|
|
437
|
+
]
|
|
438
|
+
if "editing_roles" in attributes and attributes["editing_roles"]:
|
|
439
|
+
update_data["wiki_page"]["editing_roles"] = attributes[
|
|
440
|
+
"editing_roles"
|
|
441
|
+
]
|
|
442
|
+
|
|
443
|
+
try:
|
|
444
|
+
full_page.edit(**update_data)
|
|
445
|
+
full_page._fetched_at = datetime.now()
|
|
446
|
+
if hasattr(full_page.course, "page_cache"):
|
|
447
|
+
full_page.course.page_cache[full_page.url] = (full_page, {})
|
|
448
|
+
logger.info(f"Updated page: {full_page.title}")
|
|
449
|
+
if "modules" in attributes:
|
|
450
|
+
module_regexes = attributes["modules"]
|
|
451
|
+
added, removed = canvaslms.cli.modules.update_item_modules(
|
|
452
|
+
full_page.course, "Page", full_page.url, module_regexes
|
|
453
|
+
)
|
|
454
|
+
if added:
|
|
455
|
+
print(
|
|
456
|
+
f" Added to modules: {', '.join(added)}",
|
|
457
|
+
file=sys.stderr,
|
|
458
|
+
)
|
|
459
|
+
if removed:
|
|
460
|
+
print(
|
|
461
|
+
f" Removed from modules: {', '.join(removed)}",
|
|
462
|
+
file=sys.stderr,
|
|
463
|
+
)
|
|
464
|
+
except Exception as e:
|
|
465
|
+
logger.error(f"Error updating page '{full_page.title}': {e}")
|
|
466
|
+
print(
|
|
467
|
+
f"Error updating page '{full_page.title}': {e}",
|
|
468
|
+
file=sys.stderr,
|
|
469
|
+
)
|
|
346
470
|
else:
|
|
347
471
|
try:
|
|
348
472
|
page_list = process_page_option(canvas, args)
|
|
@@ -22,8 +22,8 @@ canvaslms/cli/login.nw,sha256=93LyHO_LXL1WdEvMg3OLhWulgkdoO8pfjYZVLwUbX4I,4419
|
|
|
22
22
|
canvaslms/cli/login.py,sha256=GSO_wIT4TvCOwxaNW0VfUqjrkzsHvnImuSH4SdCu92M,2751
|
|
23
23
|
canvaslms/cli/modules.nw,sha256=Wuh1aFwZJDEUAEzzgALnc-YVXNdRgRI819zdV7oIB_E,21864
|
|
24
24
|
canvaslms/cli/modules.py,sha256=n1MfeZfjPTKyFwgluHwBqW8PKHwCGktWzYA6nuFLeL0,11483
|
|
25
|
-
canvaslms/cli/pages.nw,sha256=
|
|
26
|
-
canvaslms/cli/pages.py,sha256=
|
|
25
|
+
canvaslms/cli/pages.nw,sha256=MQOdVmMpERc5xUmnnTeEACZwVA6w8PcYACZvpmRKmZE,28648
|
|
26
|
+
canvaslms/cli/pages.py,sha256=lW8DpMeyQQoVcu7ztSj_PdW-oUJC0HSh5mDeo8BuaRc,27713
|
|
27
27
|
canvaslms/cli/quizzes.nw,sha256=nO0lAJLpE03fwPTV8wCC0Zr65p7J5x2H7J0OU8KW5CA,203138
|
|
28
28
|
canvaslms/cli/quizzes.py,sha256=gx-SPm0rI2XNVUl5Qm7s4UHvsvitwFyrNh35J3Lay9Y,152014
|
|
29
29
|
canvaslms/cli/results.nw,sha256=T-ry1k_cHCH_nJfvPl4d9UBbIl_SxvXjBMxyYfXgyaw,22503
|
|
@@ -57,8 +57,8 @@ canvaslms/hacks/attachment_cache.py,sha256=LcOZqaa6jPrEJWUD-JYN5GTc3bxCbv2fr_vqu
|
|
|
57
57
|
canvaslms/hacks/canvasapi.nw,sha256=ixmIHn4tgy-ZKtQ1rqWSw97hfY2m0qtGX0de2x89lwA,136470
|
|
58
58
|
canvaslms/hacks/canvasapi.py,sha256=A-r48x7gO6143_QkuZ8n6EW66i-a2AXXr7X7oeehOAU,31868
|
|
59
59
|
canvaslms/hacks/test_hacks.py,sha256=JSJNvZqHu1E_s51HsPD7yr1gC-R-xVe-tuMMAKU9Gj8,66709
|
|
60
|
-
canvaslms-5.
|
|
61
|
-
canvaslms-5.
|
|
62
|
-
canvaslms-5.
|
|
63
|
-
canvaslms-5.
|
|
64
|
-
canvaslms-5.
|
|
60
|
+
canvaslms-5.2.dist-info/METADATA,sha256=QxMvCwVUPBhVxceECZCQMa69iYbtY_BoBCf1J2ZAdoM,5978
|
|
61
|
+
canvaslms-5.2.dist-info/WHEEL,sha256=zp0Cn7JsFoX2ATtOhtaFYIiE2rmFAD4OcMhtUki8W3U,88
|
|
62
|
+
canvaslms-5.2.dist-info/entry_points.txt,sha256=lyblfkLbodN5yb7q1c6-rwIoJPV-ygXrB9PYb5boHXM,48
|
|
63
|
+
canvaslms-5.2.dist-info/licenses/LICENSE,sha256=N_TKsbzzD5Ax5fWJqEQk9bkwtf394MJkNeFld4HV6-E,1074
|
|
64
|
+
canvaslms-5.2.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|