learning-credentials 0.5.3__tar.gz → 0.5.4__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 (58) hide show
  1. {learning_credentials-0.5.3 → learning_credentials-0.5.4}/CHANGELOG.rst +9 -0
  2. {learning_credentials-0.5.3/learning_credentials.egg-info → learning_credentials-0.5.4}/PKG-INFO +10 -1
  3. {learning_credentials-0.5.3 → learning_credentials-0.5.4}/learning_credentials/generators.py +2 -2
  4. {learning_credentials-0.5.3 → learning_credentials-0.5.4/learning_credentials.egg-info}/PKG-INFO +10 -1
  5. {learning_credentials-0.5.3 → learning_credentials-0.5.4}/pyproject.toml +1 -1
  6. {learning_credentials-0.5.3 → learning_credentials-0.5.4}/tests/test_generators.py +29 -0
  7. {learning_credentials-0.5.3 → learning_credentials-0.5.4}/LICENSE.txt +0 -0
  8. {learning_credentials-0.5.3 → learning_credentials-0.5.4}/MANIFEST.in +0 -0
  9. {learning_credentials-0.5.3 → learning_credentials-0.5.4}/README.rst +0 -0
  10. {learning_credentials-0.5.3 → learning_credentials-0.5.4}/learning_credentials/__init__.py +0 -0
  11. {learning_credentials-0.5.3 → learning_credentials-0.5.4}/learning_credentials/admin.py +0 -0
  12. {learning_credentials-0.5.3 → learning_credentials-0.5.4}/learning_credentials/api/__init__.py +0 -0
  13. {learning_credentials-0.5.3 → learning_credentials-0.5.4}/learning_credentials/api/urls.py +0 -0
  14. {learning_credentials-0.5.3 → learning_credentials-0.5.4}/learning_credentials/api/v1/__init__.py +0 -0
  15. {learning_credentials-0.5.3 → learning_credentials-0.5.4}/learning_credentials/api/v1/permissions.py +0 -0
  16. {learning_credentials-0.5.3 → learning_credentials-0.5.4}/learning_credentials/api/v1/serializers.py +0 -0
  17. {learning_credentials-0.5.3 → learning_credentials-0.5.4}/learning_credentials/api/v1/urls.py +0 -0
  18. {learning_credentials-0.5.3 → learning_credentials-0.5.4}/learning_credentials/api/v1/views.py +0 -0
  19. {learning_credentials-0.5.3 → learning_credentials-0.5.4}/learning_credentials/apps.py +0 -0
  20. {learning_credentials-0.5.3 → learning_credentials-0.5.4}/learning_credentials/compat.py +0 -0
  21. {learning_credentials-0.5.3 → learning_credentials-0.5.4}/learning_credentials/conf/locale/config.yaml +0 -0
  22. {learning_credentials-0.5.3 → learning_credentials-0.5.4}/learning_credentials/exceptions.py +0 -0
  23. {learning_credentials-0.5.3 → learning_credentials-0.5.4}/learning_credentials/migrations/0001_initial.py +0 -0
  24. {learning_credentials-0.5.3 → learning_credentials-0.5.4}/learning_credentials/migrations/0002_migrate_to_learning_credentials.py +0 -0
  25. {learning_credentials-0.5.3 → learning_credentials-0.5.4}/learning_credentials/migrations/0003_rename_certificates_to_credentials.py +0 -0
  26. {learning_credentials-0.5.3 → learning_credentials-0.5.4}/learning_credentials/migrations/0004_replace_course_keys_with_learning_context_keys.py +0 -0
  27. {learning_credentials-0.5.3 → learning_credentials-0.5.4}/learning_credentials/migrations/0005_rename_processors_and_generators.py +0 -0
  28. {learning_credentials-0.5.3 → learning_credentials-0.5.4}/learning_credentials/migrations/0006_cleanup_openedx_certificates_tables.py +0 -0
  29. {learning_credentials-0.5.3 → learning_credentials-0.5.4}/learning_credentials/migrations/0007_migrate_to_text_elements_format.py +0 -0
  30. {learning_credentials-0.5.3 → learning_credentials-0.5.4}/learning_credentials/migrations/0008_validation.py +0 -0
  31. {learning_credentials-0.5.3 → learning_credentials-0.5.4}/learning_credentials/migrations/0009_credential_user_fk.py +0 -0
  32. {learning_credentials-0.5.3 → learning_credentials-0.5.4}/learning_credentials/migrations/0010_credential_configuration_fk.py +0 -0
  33. {learning_credentials-0.5.3 → learning_credentials-0.5.4}/learning_credentials/migrations/__init__.py +0 -0
  34. {learning_credentials-0.5.3 → learning_credentials-0.5.4}/learning_credentials/models.py +0 -0
  35. {learning_credentials-0.5.3 → learning_credentials-0.5.4}/learning_credentials/processors.py +0 -0
  36. {learning_credentials-0.5.3 → learning_credentials-0.5.4}/learning_credentials/settings/__init__.py +0 -0
  37. {learning_credentials-0.5.3 → learning_credentials-0.5.4}/learning_credentials/settings/common.py +0 -0
  38. {learning_credentials-0.5.3 → learning_credentials-0.5.4}/learning_credentials/settings/production.py +0 -0
  39. {learning_credentials-0.5.3 → learning_credentials-0.5.4}/learning_credentials/tasks.py +0 -0
  40. {learning_credentials-0.5.3 → learning_credentials-0.5.4}/learning_credentials/templates/learning_credentials/base.html +0 -0
  41. {learning_credentials-0.5.3 → learning_credentials-0.5.4}/learning_credentials/templates/learning_credentials/edx_ace/certificate_generated/email/body.html +0 -0
  42. {learning_credentials-0.5.3 → learning_credentials-0.5.4}/learning_credentials/templates/learning_credentials/edx_ace/certificate_generated/email/body.txt +0 -0
  43. {learning_credentials-0.5.3 → learning_credentials-0.5.4}/learning_credentials/templates/learning_credentials/edx_ace/certificate_generated/email/from_name.txt +0 -0
  44. {learning_credentials-0.5.3 → learning_credentials-0.5.4}/learning_credentials/templates/learning_credentials/edx_ace/certificate_generated/email/head.html +0 -0
  45. {learning_credentials-0.5.3 → learning_credentials-0.5.4}/learning_credentials/templates/learning_credentials/edx_ace/certificate_generated/email/subject.txt +0 -0
  46. {learning_credentials-0.5.3 → learning_credentials-0.5.4}/learning_credentials/urls.py +0 -0
  47. {learning_credentials-0.5.3 → learning_credentials-0.5.4}/learning_credentials.egg-info/SOURCES.txt +0 -0
  48. {learning_credentials-0.5.3 → learning_credentials-0.5.4}/learning_credentials.egg-info/dependency_links.txt +0 -0
  49. {learning_credentials-0.5.3 → learning_credentials-0.5.4}/learning_credentials.egg-info/entry_points.txt +0 -0
  50. {learning_credentials-0.5.3 → learning_credentials-0.5.4}/learning_credentials.egg-info/requires.txt +0 -0
  51. {learning_credentials-0.5.3 → learning_credentials-0.5.4}/learning_credentials.egg-info/top_level.txt +0 -0
  52. {learning_credentials-0.5.3 → learning_credentials-0.5.4}/setup.cfg +0 -0
  53. {learning_credentials-0.5.3 → learning_credentials-0.5.4}/tests/test_admin.py +0 -0
  54. {learning_credentials-0.5.3 → learning_credentials-0.5.4}/tests/test_migrations.py +0 -0
  55. {learning_credentials-0.5.3 → learning_credentials-0.5.4}/tests/test_models.py +0 -0
  56. {learning_credentials-0.5.3 → learning_credentials-0.5.4}/tests/test_processors.py +0 -0
  57. {learning_credentials-0.5.3 → learning_credentials-0.5.4}/tests/test_tasks.py +0 -0
  58. {learning_credentials-0.5.3 → learning_credentials-0.5.4}/tests/test_views.py +0 -0
@@ -16,6 +16,15 @@ Unreleased
16
16
 
17
17
  *
18
18
 
19
+ 0.5.4 - 2026-11-10
20
+ ******************
21
+
22
+ Fixed
23
+ =====
24
+
25
+ * PDF credential generation with ``pypdf>=7.0.0``. The overlay is now merged into the page after it is attached to
26
+ the ``PdfWriter``, because merging into a page that is not attached to a writer is no longer supported.
27
+
19
28
  0.5.3 - 2026-08-11
20
29
  ******************
21
30
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: learning-credentials
3
- Version: 0.5.3
3
+ Version: 0.5.4
4
4
  Summary: A pluggable service for preparing Open edX credentials.
5
5
  Author-email: OpenCraft <help@opencraft.com>
6
6
  License-Expression: AGPL-3.0-or-later
@@ -177,6 +177,15 @@ Unreleased
177
177
 
178
178
  *
179
179
 
180
+ 0.5.4 - 2026-11-10
181
+ ******************
182
+
183
+ Fixed
184
+ =====
185
+
186
+ * PDF credential generation with ``pypdf>=7.0.0``. The overlay is now merged into the page after it is attached to
187
+ the ``PdfWriter``, because merging into a page that is not attached to a writer is no longer supported.
188
+
180
189
  0.5.3 - 2026-08-11
181
190
  ******************
182
191
 
@@ -449,8 +449,8 @@ def generate_pdf_credential(credential: Credential, options: dict[str, Any], *,
449
449
  )
450
450
 
451
451
  overlay_pdf = PdfReader(io.BytesIO(pdf_canvas.getpdfdata()))
452
- template.merge_page(overlay_pdf.pages[0])
453
- pdf_writer.add_page(template)
452
+ page = pdf_writer.add_page(template)
453
+ page.merge_page(overlay_pdf.pages[0])
454
454
 
455
455
  url = _save_credential(pdf_writer, credential.uuid)
456
456
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: learning-credentials
3
- Version: 0.5.3
3
+ Version: 0.5.4
4
4
  Summary: A pluggable service for preparing Open edX credentials.
5
5
  Author-email: OpenCraft <help@opencraft.com>
6
6
  License-Expression: AGPL-3.0-or-later
@@ -177,6 +177,15 @@ Unreleased
177
177
 
178
178
  *
179
179
 
180
+ 0.5.4 - 2026-11-10
181
+ ******************
182
+
183
+ Fixed
184
+ =====
185
+
186
+ * PDF credential generation with ``pypdf>=7.0.0``. The overlay is now merged into the page after it is attached to
187
+ the ``PdfWriter``, because merging into a page that is not attached to a writer is no longer supported.
188
+
180
189
  0.5.3 - 2026-08-11
181
190
  ******************
182
191
 
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "learning-credentials"
3
- version = "0.5.3"
3
+ version = "0.5.4"
4
4
  description = "A pluggable service for preparing Open edX credentials."
5
5
  dynamic = ["readme"]
6
6
  requires-python = ">=3.11"
@@ -542,6 +542,35 @@ def test_generate_pdf_credential( # noqa: PLR0917
542
542
  mock_save_credential.assert_called_once()
543
543
 
544
544
 
545
+ @pytest.mark.filterwarnings('error::DeprecationWarning')
546
+ @patch('learning_credentials.generators._save_credential', return_value='credential_url')
547
+ @patch('learning_credentials.generators.CredentialAsset.get_asset_by_slug')
548
+ def test_generate_pdf_credential_merges_overlay_into_template(mock_get_asset_by_slug: Mock, mock_save_credential: Mock):
549
+ """Test that generate_pdf_credential merges the overlay into the template without using deprecated pypdf APIs."""
550
+ template_writer = PdfWriter()
551
+ template_writer.add_blank_page(width=842, height=595)
552
+ template_buffer = io.BytesIO()
553
+ template_writer.write(template_buffer)
554
+ mock_get_asset_by_slug.return_value = ContentFile(template_buffer.getvalue(), name='template.pdf')
555
+
556
+ credential = Mock(
557
+ user_full_name='Test User',
558
+ learning_context_name='Test Course',
559
+ verify_uuid=uuid4(),
560
+ created=Mock(),
561
+ )
562
+
563
+ with patch('learning_credentials.generators.get_localized_credential_date', return_value='April 1, 2021'):
564
+ result = generate_pdf_credential(credential, {'template': 'template'})
565
+
566
+ assert result == 'credential_url'
567
+ pdf_writer = mock_save_credential.call_args.args[0]
568
+ assert len(pdf_writer.pages) == 1
569
+ page_text = pdf_writer.pages[0].extract_text()
570
+ assert 'Test User' in page_text
571
+ assert 'Test Course' in page_text
572
+
573
+
545
574
  def test_generate_pdf_credential_no_template():
546
575
  """Test that generate_pdf_credential raises ValueError when no template is specified."""
547
576
  credential = Mock(learning_context_name='Test Course')