docassemble.AssemblyLine 4.2.0__tar.gz → 4.3.0__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 (104) hide show
  1. {docassemble_assemblyline-4.2.0/docassemble.AssemblyLine.egg-info → docassemble_assemblyline-4.3.0}/PKG-INFO +8 -10
  2. {docassemble_assemblyline-4.2.0 → docassemble_assemblyline-4.3.0}/README.md +2 -1
  3. docassemble_assemblyline-4.3.0/docassemble/AssemblyLine/__init__.py +1 -0
  4. {docassemble_assemblyline-4.2.0 → docassemble_assemblyline-4.3.0}/docassemble/AssemblyLine/al_document.py +52 -32
  5. {docassemble_assemblyline-4.2.0 → docassemble_assemblyline-4.3.0}/docassemble/AssemblyLine/al_general.py +29 -20
  6. {docassemble_assemblyline-4.2.0 → docassemble_assemblyline-4.3.0}/docassemble/AssemblyLine/data/questions/al_language.yml +1 -0
  7. {docassemble_assemblyline-4.2.0 → docassemble_assemblyline-4.3.0}/docassemble/AssemblyLine/data/questions/ql_baseline.yml +45 -4
  8. {docassemble_assemblyline-4.2.0 → docassemble_assemblyline-4.3.0}/docassemble/AssemblyLine/data/questions/test_aldocument.yml +4 -1
  9. {docassemble_assemblyline-4.2.0 → docassemble_assemblyline-4.3.0}/docassemble/AssemblyLine/data/questions/test_alexhibit_maxsize.yml +1 -1
  10. docassemble_assemblyline-4.3.0/docassemble/AssemblyLine/data/questions/test_preferred_name.yml +132 -0
  11. {docassemble_assemblyline-4.2.0 → docassemble_assemblyline-4.3.0}/docassemble/AssemblyLine/data/questions/test_question_library.yml +3 -0
  12. docassemble_assemblyline-4.3.0/docassemble/AssemblyLine/data/sources/ar-words.yml +753 -0
  13. docassemble_assemblyline-4.3.0/docassemble/AssemblyLine/data/sources/es-words.yml +863 -0
  14. docassemble_assemblyline-4.3.0/docassemble/AssemblyLine/data/sources/fr-words.yml +878 -0
  15. docassemble_assemblyline-4.3.0/docassemble/AssemblyLine/data/sources/ne-words.yml +841 -0
  16. {docassemble_assemblyline-4.2.0 → docassemble_assemblyline-4.3.0}/docassemble/AssemblyLine/sessions.py +72 -76
  17. {docassemble_assemblyline-4.2.0 → docassemble_assemblyline-4.3.0}/docassemble/AssemblyLine/test_al_document.py +2 -0
  18. {docassemble_assemblyline-4.2.0 → docassemble_assemblyline-4.3.0}/docassemble/AssemblyLine/test_al_general.py +131 -1
  19. {docassemble_assemblyline-4.2.0 → docassemble_assemblyline-4.3.0}/docassemble/AssemblyLine/test_language.py +2 -0
  20. {docassemble_assemblyline-4.2.0 → docassemble_assemblyline-4.3.0/docassemble.AssemblyLine.egg-info}/PKG-INFO +8 -10
  21. {docassemble_assemblyline-4.2.0 → docassemble_assemblyline-4.3.0}/docassemble.AssemblyLine.egg-info/SOURCES.txt +4 -1
  22. docassemble_assemblyline-4.3.0/docassemble.AssemblyLine.egg-info/requires.txt +2 -0
  23. docassemble_assemblyline-4.3.0/pyproject.toml +64 -0
  24. {docassemble_assemblyline-4.2.0 → docassemble_assemblyline-4.3.0}/setup.py +1 -1
  25. docassemble_assemblyline-4.2.0/docassemble/AssemblyLine/__init__.py +0 -1
  26. docassemble_assemblyline-4.2.0/docassemble/AssemblyLine/data/sources/es-words.yml +0 -687
  27. docassemble_assemblyline-4.2.0/docassemble/__init__.py +0 -1
  28. docassemble_assemblyline-4.2.0/docassemble.AssemblyLine.egg-info/requires.txt +0 -2
  29. docassemble_assemblyline-4.2.0/pyproject.toml +0 -30
  30. {docassemble_assemblyline-4.2.0 → docassemble_assemblyline-4.3.0}/LICENSE +0 -0
  31. {docassemble_assemblyline-4.2.0 → docassemble_assemblyline-4.3.0}/MANIFEST.in +0 -0
  32. {docassemble_assemblyline-4.2.0 → docassemble_assemblyline-4.3.0}/docassemble/AssemblyLine/al_courts.py +0 -0
  33. {docassemble_assemblyline-4.2.0 → docassemble_assemblyline-4.3.0}/docassemble/AssemblyLine/custom_jinja_filters.py +0 -0
  34. {docassemble_assemblyline-4.2.0 → docassemble_assemblyline-4.3.0}/docassemble/AssemblyLine/data/questions/al_code.yml +0 -0
  35. {docassemble_assemblyline-4.2.0 → docassemble_assemblyline-4.3.0}/docassemble/AssemblyLine/data/questions/al_document.yml +0 -0
  36. {docassemble_assemblyline-4.2.0 → docassemble_assemblyline-4.3.0}/docassemble/AssemblyLine/data/questions/al_package.yml +0 -0
  37. {docassemble_assemblyline-4.2.0 → docassemble_assemblyline-4.3.0}/docassemble/AssemblyLine/data/questions/al_package_unstyled.yml +0 -0
  38. {docassemble_assemblyline-4.2.0 → docassemble_assemblyline-4.3.0}/docassemble/AssemblyLine/data/questions/al_question_test.yml +0 -0
  39. {docassemble_assemblyline-4.2.0 → docassemble_assemblyline-4.3.0}/docassemble/AssemblyLine/data/questions/al_reminders.yml +0 -0
  40. {docassemble_assemblyline-4.2.0 → docassemble_assemblyline-4.3.0}/docassemble/AssemblyLine/data/questions/al_saved_sessions.yml +0 -0
  41. {docassemble_assemblyline-4.2.0 → docassemble_assemblyline-4.3.0}/docassemble/AssemblyLine/data/questions/al_saved_sessions_store.yml +0 -0
  42. {docassemble_assemblyline-4.2.0 → docassemble_assemblyline-4.3.0}/docassemble/AssemblyLine/data/questions/al_settings.yml +0 -0
  43. {docassemble_assemblyline-4.2.0 → docassemble_assemblyline-4.3.0}/docassemble/AssemblyLine/data/questions/al_terms_of_use.yml +0 -0
  44. {docassemble_assemblyline-4.2.0 → docassemble_assemblyline-4.3.0}/docassemble/AssemblyLine/data/questions/al_visual.yml +0 -0
  45. {docassemble_assemblyline-4.2.0 → docassemble_assemblyline-4.3.0}/docassemble/AssemblyLine/data/questions/assembly_line.yml +0 -0
  46. {docassemble_assemblyline-4.2.0 → docassemble_assemblyline-4.3.0}/docassemble/AssemblyLine/data/questions/assembly_line_unstyled.yml +0 -0
  47. {docassemble_assemblyline-4.2.0 → docassemble_assemblyline-4.3.0}/docassemble/AssemblyLine/data/questions/demo_search_sessions.yml +0 -0
  48. {docassemble_assemblyline-4.2.0 → docassemble_assemblyline-4.3.0}/docassemble/AssemblyLine/data/questions/feedback.yml +0 -0
  49. {docassemble_assemblyline-4.2.0 → docassemble_assemblyline-4.3.0}/docassemble/AssemblyLine/data/questions/interview_list.yml +0 -0
  50. {docassemble_assemblyline-4.2.0 → docassemble_assemblyline-4.3.0}/docassemble/AssemblyLine/data/questions/ql_catchall.yml +0 -0
  51. {docassemble_assemblyline-4.2.0 → docassemble_assemblyline-4.3.0}/docassemble/AssemblyLine/data/questions/ql_namechange.yml +0 -0
  52. {docassemble_assemblyline-4.2.0 → docassemble_assemblyline-4.3.0}/docassemble/AssemblyLine/data/questions/reserved_words.yml +0 -0
  53. {docassemble_assemblyline-4.2.0 → docassemble_assemblyline-4.3.0}/docassemble/AssemblyLine/data/questions/test_al_table_document.yml +0 -0
  54. {docassemble_assemblyline-4.2.0 → docassemble_assemblyline-4.3.0}/docassemble/AssemblyLine/data/questions/test_aladdendum.yml +0 -0
  55. {docassemble_assemblyline-4.2.0 → docassemble_assemblyline-4.3.0}/docassemble/AssemblyLine/data/questions/test_alcourts.yml +0 -0
  56. {docassemble_assemblyline-4.2.0 → docassemble_assemblyline-4.3.0}/docassemble/AssemblyLine/data/questions/test_aldocument_background_assembly.yml +0 -0
  57. {docassemble_assemblyline-4.2.0 → docassemble_assemblyline-4.3.0}/docassemble/AssemblyLine/data/questions/test_alexhibit.yml +0 -0
  58. {docassemble_assemblyline-4.2.0 → docassemble_assemblyline-4.3.0}/docassemble/AssemblyLine/data/questions/test_bundle_parity.yml +0 -0
  59. {docassemble_assemblyline-4.2.0 → docassemble_assemblyline-4.3.0}/docassemble/AssemblyLine/data/questions/test_catchall.yml +0 -0
  60. {docassemble_assemblyline-4.2.0 → docassemble_assemblyline-4.3.0}/docassemble/AssemblyLine/data/questions/test_familiar_disambiguation.yml +0 -0
  61. {docassemble_assemblyline-4.2.0 → docassemble_assemblyline-4.3.0}/docassemble/AssemblyLine/data/questions/test_if_final.yml +0 -0
  62. {docassemble_assemblyline-4.2.0 → docassemble_assemblyline-4.3.0}/docassemble/AssemblyLine/data/questions/test_preferred_formats.yml +0 -0
  63. {docassemble_assemblyline-4.2.0 → docassemble_assemblyline-4.3.0}/docassemble/AssemblyLine/data/questions/test_signature.yml +0 -0
  64. {docassemble_assemblyline-4.2.0 → docassemble_assemblyline-4.3.0}/docassemble/AssemblyLine/data/sources/README.md +0 -0
  65. {docassemble_assemblyline-4.2.0 → docassemble_assemblyline-4.3.0}/docassemble/AssemblyLine/data/sources/languages.yml +0 -0
  66. {docassemble_assemblyline-4.2.0 → docassemble_assemblyline-4.3.0}/docassemble/AssemblyLine/data/sources/test_aldocument.feature +0 -0
  67. {docassemble_assemblyline-4.2.0 → docassemble_assemblyline-4.3.0}/docassemble/AssemblyLine/data/sources/test_alexhibit_docx_1.docx +0 -0
  68. {docassemble_assemblyline-4.2.0 → docassemble_assemblyline-4.3.0}/docassemble/AssemblyLine/data/sources/test_alexhibit_jpg_1.jpg +0 -0
  69. {docassemble_assemblyline-4.2.0 → docassemble_assemblyline-4.3.0}/docassemble/AssemblyLine/data/sources/test_alexhibit_pdf_1.pdf +0 -0
  70. {docassemble_assemblyline-4.2.0 → docassemble_assemblyline-4.3.0}/docassemble/AssemblyLine/data/sources/test_alexhibit_png_1.png +0 -0
  71. {docassemble_assemblyline-4.2.0 → docassemble_assemblyline-4.3.0}/docassemble/AssemblyLine/data/sources/test_question_library.feature +0 -0
  72. {docassemble_assemblyline-4.2.0 → docassemble_assemblyline-4.3.0}/docassemble/AssemblyLine/data/sources/translation_es.xlsx +0 -0
  73. {docassemble_assemblyline-4.2.0 → docassemble_assemblyline-4.3.0}/docassemble/AssemblyLine/data/sources/translation_ht.xlsx +0 -0
  74. {docassemble_assemblyline-4.2.0 → docassemble_assemblyline-4.3.0}/docassemble/AssemblyLine/data/sources/translation_pt.xlsx +0 -0
  75. {docassemble_assemblyline-4.2.0 → docassemble_assemblyline-4.3.0}/docassemble/AssemblyLine/data/static/README.md +0 -0
  76. {docassemble_assemblyline-4.2.0 → docassemble_assemblyline-4.3.0}/docassemble/AssemblyLine/data/static/al_audio.css +0 -0
  77. {docassemble_assemblyline-4.2.0 → docassemble_assemblyline-4.3.0}/docassemble/AssemblyLine/data/static/al_audio.js +0 -0
  78. {docassemble_assemblyline-4.2.0 → docassemble_assemblyline-4.3.0}/docassemble/AssemblyLine/data/static/aldocument.css +0 -0
  79. {docassemble_assemblyline-4.2.0 → docassemble_assemblyline-4.3.0}/docassemble/AssemblyLine/data/static/aldocument.js +0 -0
  80. {docassemble_assemblyline-4.2.0 → docassemble_assemblyline-4.3.0}/docassemble/AssemblyLine/data/static/interview_list.css +0 -0
  81. {docassemble_assemblyline-4.2.0 → docassemble_assemblyline-4.3.0}/docassemble/AssemblyLine/data/static/limit_upload_size.js +0 -0
  82. {docassemble_assemblyline-4.2.0 → docassemble_assemblyline-4.3.0}/docassemble/AssemblyLine/data/static/lt1-pullout-10-getting-organized.pdf +0 -0
  83. {docassemble_assemblyline-4.2.0 → docassemble_assemblyline-4.3.0}/docassemble/AssemblyLine/data/static/ma_logo.png +0 -0
  84. {docassemble_assemblyline-4.2.0 → docassemble_assemblyline-4.3.0}/docassemble/AssemblyLine/data/static/placeholder.png +0 -0
  85. {docassemble_assemblyline-4.2.0 → docassemble_assemblyline-4.3.0}/docassemble/AssemblyLine/data/static/seal.jpg +0 -0
  86. {docassemble_assemblyline-4.2.0 → docassemble_assemblyline-4.3.0}/docassemble/AssemblyLine/data/static/styles.css +0 -0
  87. {docassemble_assemblyline-4.2.0 → docassemble_assemblyline-4.3.0}/docassemble/AssemblyLine/data/templates/README.md +0 -0
  88. {docassemble_assemblyline-4.2.0 → docassemble_assemblyline-4.3.0}/docassemble/AssemblyLine/data/templates/al_basic_addendum.docx +0 -0
  89. {docassemble_assemblyline-4.2.0 → docassemble_assemblyline-4.3.0}/docassemble/AssemblyLine/data/templates/exhibit_cover_sheet.docx +0 -0
  90. {docassemble_assemblyline-4.2.0 → docassemble_assemblyline-4.3.0}/docassemble/AssemblyLine/data/templates/exhibit_table_of_contents.docx +0 -0
  91. {docassemble_assemblyline-4.2.0 → docassemble_assemblyline-4.3.0}/docassemble/AssemblyLine/data/templates/general_cover_sheet.docx +0 -0
  92. {docassemble_assemblyline-4.2.0 → docassemble_assemblyline-4.3.0}/docassemble/AssemblyLine/data/templates/sample_word_template.docx +0 -0
  93. {docassemble_assemblyline-4.2.0 → docassemble_assemblyline-4.3.0}/docassemble/AssemblyLine/data/templates/test_aldocument_docx_1.docx +0 -0
  94. {docassemble_assemblyline-4.2.0 → docassemble_assemblyline-4.3.0}/docassemble/AssemblyLine/data/templates/test_aldocument_pdf_1.pdf +0 -0
  95. {docassemble_assemblyline-4.2.0 → docassemble_assemblyline-4.3.0}/docassemble/AssemblyLine/data/templates/test_catchall.docx +0 -0
  96. {docassemble_assemblyline-4.2.0 → docassemble_assemblyline-4.3.0}/docassemble/AssemblyLine/data/templates/test_if_final.docx +0 -0
  97. {docassemble_assemblyline-4.2.0 → docassemble_assemblyline-4.3.0}/docassemble/AssemblyLine/language.py +0 -0
  98. {docassemble_assemblyline-4.2.0 → docassemble_assemblyline-4.3.0}/docassemble/AssemblyLine/py.typed +0 -0
  99. {docassemble_assemblyline-4.2.0 → docassemble_assemblyline-4.3.0}/docassemble/AssemblyLine/requirements.txt +0 -0
  100. {docassemble_assemblyline-4.2.0 → docassemble_assemblyline-4.3.0}/docassemble/AssemblyLine/sign.py +0 -0
  101. {docassemble_assemblyline-4.2.0 → docassemble_assemblyline-4.3.0}/docassemble.AssemblyLine.egg-info/dependency_links.txt +0 -0
  102. {docassemble_assemblyline-4.2.0 → docassemble_assemblyline-4.3.0}/docassemble.AssemblyLine.egg-info/not-zip-safe +0 -0
  103. {docassemble_assemblyline-4.2.0 → docassemble_assemblyline-4.3.0}/docassemble.AssemblyLine.egg-info/top_level.txt +0 -0
  104. {docassemble_assemblyline-4.2.0 → docassemble_assemblyline-4.3.0}/setup.cfg +0 -0
@@ -1,22 +1,19 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: docassemble.AssemblyLine
3
- Version: 4.2.0
3
+ Version: 4.3.0
4
+ Summary: Quickly go from a paper court form to a runnable, guided, step-by-step web application powered by Docassemble. Swap out branding and pre-built questions to meet your needs.
4
5
  Home-page: https://courtformsonline.org
5
6
  Author: Suffolk Legal Innovation and Technology Lab
6
- Author-email: qsteenhuis@suffolk.edu
7
- License: The MIT License (MIT)
7
+ Author-email: Suffolk Legal Innovation and Technology Lab <litlab@suffolk.edu>
8
+ License-Expression: MIT
9
+ Project-URL: Homepage, https://courtformsonline.org
8
10
  Description-Content-Type: text/markdown
9
11
  License-File: LICENSE
10
12
  Requires-Dist: docassemble.ALToolbox>=0.12.0
11
- Requires-Dist: docassemble.GithubFeedbackForm>=0.4.1.1
13
+ Requires-Dist: docassemble.GitHubFeedbackForm>=0.4.1.1
12
14
  Dynamic: author
13
- Dynamic: author-email
14
- Dynamic: description
15
- Dynamic: description-content-type
16
15
  Dynamic: home-page
17
- Dynamic: license
18
16
  Dynamic: license-file
19
- Dynamic: requires-dist
20
17
 
21
18
  # Suffolk LIT Lab Document Assembly Line
22
19
 
@@ -55,7 +52,7 @@ https://suffolklitlab.org/docassemble-AssemblyLine-documentation/
55
52
 
56
53
  ## Menu-driven installation
57
54
 
58
- The recommended installation method is with the [guided installation script](https://suffolklitlab.org/docassemble-AssemblyLine-documentation/docs/installation).
55
+ The recommended installation method is with the [guided installation script](https://assemblyline.suffolklitlab.org/docs/get_started/installation).
59
56
 
60
57
  ## Manual installation
61
58
 
@@ -155,3 +152,4 @@ code: |
155
152
  # Changelog
156
153
 
157
154
  See [CHANGELOG.MD](https://github.com/SuffolkLITLab/docassemble-AssemblyLine/blob/main/CHANGELOG.md)
155
+
@@ -35,7 +35,7 @@ https://suffolklitlab.org/docassemble-AssemblyLine-documentation/
35
35
 
36
36
  ## Menu-driven installation
37
37
 
38
- The recommended installation method is with the [guided installation script](https://suffolklitlab.org/docassemble-AssemblyLine-documentation/docs/installation).
38
+ The recommended installation method is with the [guided installation script](https://assemblyline.suffolklitlab.org/docs/get_started/installation).
39
39
 
40
40
  ## Manual installation
41
41
 
@@ -135,3 +135,4 @@ code: |
135
135
  # Changelog
136
136
 
137
137
  See [CHANGELOG.MD](https://github.com/SuffolkLITLab/docassemble-AssemblyLine/blob/main/CHANGELOG.md)
138
+
@@ -0,0 +1 @@
1
+ __version__ = '4.3.0'
@@ -12,6 +12,7 @@ from docassemble.base.util import (
12
12
  DAFile,
13
13
  DAFileCollection,
14
14
  DAFileList,
15
+ DALazyTemplate,
15
16
  defined,
16
17
  pdf_concatenate,
17
18
  zip_file,
@@ -28,6 +29,7 @@ from docassemble.base.util import (
28
29
  DAStaticFile,
29
30
  alpha,
30
31
  showifdef,
32
+ word,
31
33
  )
32
34
  from docassemble.base.pdfa import pdf_to_pdfa
33
35
  from textwrap import wrap
@@ -39,7 +41,6 @@ from typing import Tuple
39
41
  import secrets
40
42
  import string
41
43
 
42
-
43
44
  __all__ = [
44
45
  "ALAddendumField",
45
46
  "ALAddendumFieldDict",
@@ -315,6 +316,9 @@ class ALAddendumField(DAObject):
315
316
 
316
317
  # If trigger is not a boolean value, overflow value is the value that starts at the end of the safe value.
317
318
  original_value = self.value_if_defined()
319
+ # Ensure a DALazyTemplate is rendered to a string for downstream string ops
320
+ if isinstance(original_value, DALazyTemplate):
321
+ original_value = str(original_value)
318
322
  safe_text = self.safe_value(
319
323
  overflow_message=overflow_message,
320
324
  input_width=input_width,
@@ -409,6 +413,9 @@ class ALAddendumField(DAObject):
409
413
  val = _original_value
410
414
  else:
411
415
  val = self.value_if_defined()
416
+ # If this is a template block, render it now so comparisons work correctly
417
+ if isinstance(val, DALazyTemplate):
418
+ val = str(val)
412
419
 
413
420
  return (
414
421
  self.safe_value(
@@ -508,6 +515,11 @@ class ALAddendumField(DAObject):
508
515
  value = _original_value
509
516
  else:
510
517
  value = self.value_if_defined()
518
+
519
+ # Convert template blocks to strings for purposes of evaluating overflow
520
+ if isinstance(value, DALazyTemplate):
521
+ value = str(value)
522
+
511
523
  if (
512
524
  isinstance(value, str)
513
525
  and len(value) <= self.overflow_trigger
@@ -1996,11 +2008,11 @@ class ALDocumentBundle(DAList):
1996
2008
  refresh: bool = True,
1997
2009
  pdfa: bool = False,
1998
2010
  include_zip: bool = True,
1999
- view_label="View",
2011
+ view_label: Optional[str] = None,
2000
2012
  view_icon: str = "eye",
2001
- download_label: str = "Download",
2013
+ download_label: Optional[str] = None,
2002
2014
  download_icon: str = "download",
2003
- send_label: str = "Send",
2015
+ send_label: Optional[str] = None,
2004
2016
  send_icon: str = "envelope",
2005
2017
  zip_label: Optional[str] = None,
2006
2018
  zip_icon: str = "file-archive",
@@ -2023,11 +2035,11 @@ class ALDocumentBundle(DAList):
2023
2035
  refresh (bool): Flag to reconsider the 'enabled' attribute, default is True.
2024
2036
  pdfa (bool): Flag to return documents in PDF/A format, default is False.
2025
2037
  include_zip (bool): Flag to include a zip option, default is True.
2026
- view_label (str): Label for the 'view' button, default is "View".
2038
+ view_label (str): Label for the 'view' button, default is self.view_label or "View".
2027
2039
  view_icon (str): Icon for the 'view' button, default is "eye".
2028
- download_label (str): Label for the 'download' button, default is "Download".
2040
+ download_label (str): Label for the 'download' button, default is self.download_label or "Download".
2029
2041
  download_icon (str): Icon for the 'download' button, default is "download".
2030
- send_label (str): Label for the 'send' button. Default is "Send".
2042
+ send_label (str): Label for the 'send' button. Default is self.send_label or "Send".
2031
2043
  send_icon (str): Fontawesome icon for the 'send' button. Default is "envelope".
2032
2044
  zip_label (Optional[str]): Label for the zip option. If not provided, uses the generic template for `self.zip_label` ("Download all").
2033
2045
  zip_icon (str): Icon for the zip option, default is "file-archive".
@@ -2044,11 +2056,14 @@ class ALDocumentBundle(DAList):
2044
2056
  Returns:
2045
2057
  str: HTML representation of a table with documents and their associated actions.
2046
2058
  """
2047
- if not hasattr(self, "_cached_zip_label"):
2048
- self._cached_zip_label = str(self.zip_label)
2059
+ if not view_label:
2060
+ view_label = str(self.view_label) or word("View")
2049
2061
 
2050
- if not hasattr(self, "_cached_full_pdf_label"):
2051
- self._cached_full_pdf_label = str(self.full_pdf_label)
2062
+ if not download_label:
2063
+ download_label = str(self.download_label) or word("Download")
2064
+
2065
+ if not send_label:
2066
+ send_label = str(self.send_label) or word("Send")
2052
2067
 
2053
2068
  if zip_format is None:
2054
2069
  zip_format = format
@@ -2123,7 +2138,7 @@ class ALDocumentBundle(DAList):
2123
2138
  # Add a zip file row if included
2124
2139
  if include_zip and bundled_zip:
2125
2140
  if not zip_label:
2126
- zip_label = self._cached_zip_label
2141
+ zip_label = str(self.zip_label)
2127
2142
  filename_root = os.path.splitext(str(self.filename))[0]
2128
2143
  zip_button = action_button_html(
2129
2144
  bundled_zip.url_for(
@@ -2142,7 +2157,7 @@ class ALDocumentBundle(DAList):
2142
2157
 
2143
2158
  if include_full_pdf and bundled_pdf:
2144
2159
  if not full_pdf_label:
2145
- full_pdf_label = self._cached_full_pdf_label
2160
+ full_pdf_label = str(self.full_pdf_label)
2146
2161
  filename_root = os.path.splitext(str(self.filename))[0]
2147
2162
  full_pdf_button = action_button_html(
2148
2163
  bundled_pdf.url_for(
@@ -2239,12 +2254,17 @@ class ALDocumentBundle(DAList):
2239
2254
  return html
2240
2255
 
2241
2256
  def send_email_table_row(
2242
- self, key: str = "final", send_label: str = "Send", send_icon: str = "envelope"
2257
+ self,
2258
+ key: str = "final",
2259
+ send_label: Optional[str] = None,
2260
+ send_icon: str = "envelope",
2243
2261
  ) -> str:
2244
2262
  """
2245
2263
  Generate HTML doc table row for an input box and button that allows
2246
2264
  someone to send the bundle to the specified email address.
2247
2265
 
2266
+ This should normally only be called by download_list_html.
2267
+
2248
2268
  Args:
2249
2269
  key (str): A key used to identify which version of the ALDocument to send. Defaults to "final".
2250
2270
  send_label (str): Label for the 'send' button. Default is "Send".
@@ -2253,14 +2273,12 @@ class ALDocumentBundle(DAList):
2253
2273
  Returns:
2254
2274
  str: The generated HTML string for the table row.
2255
2275
  """
2276
+ if not send_label:
2277
+ send_label = str(self.send_label) or word("Send")
2278
+
2256
2279
  if not self.has_enabled_documents():
2257
2280
  return "" # Don't let people email an empty set of documents
2258
- if not hasattr(self, "_cached_get_email_copy"):
2259
- self._cached_get_email_copy = str(self.get_email_copy)
2260
- if not hasattr(self, "_cached_include_editable_documents"):
2261
- self._cached_include_editable_documents = str(
2262
- self.include_editable_documents
2263
- )
2281
+
2264
2282
  name = html_safe_str(self.instanceName) + random_suffix()
2265
2283
  al_wants_editable_input_id = "_ignore_al_wants_editable_" + name
2266
2284
  al_email_input_id = "_ignore_al_doc_email_" + name
@@ -2298,7 +2316,7 @@ class ALDocumentBundle(DAList):
2298
2316
  email: str,
2299
2317
  editable: Optional[bool] = None,
2300
2318
  template_name: str = "",
2301
- label: str = "Send",
2319
+ label: Optional[str] = None,
2302
2320
  icon: str = "envelope",
2303
2321
  color: str = "primary",
2304
2322
  key: str = "final",
@@ -2322,10 +2340,11 @@ class ALDocumentBundle(DAList):
2322
2340
  Returns:
2323
2341
  str: The generated HTML string for the button.
2324
2342
  """
2343
+ if label is None:
2344
+ label = str(self.send_label) or word("Send")
2345
+
2325
2346
  if not self.has_enabled_documents():
2326
2347
  return "" # Don't let people email an empty set of documents
2327
- if not hasattr(self, "_cached_get_email_copy"):
2328
- self._cached_get_email_copy = str(self.get_email_copy)
2329
2348
  name = html_safe_str(self.instanceName) + random_suffix()
2330
2349
  al_send_button_id = "al_send_email_to_button_" + name
2331
2350
 
@@ -2392,12 +2411,6 @@ class ALDocumentBundle(DAList):
2392
2411
  """
2393
2412
  if not self.has_enabled_documents():
2394
2413
  return "" # Don't let people email an empty set of documents
2395
- if not hasattr(self, "_cached_get_email_copy"):
2396
- self._cached_get_email_copy = str(self.get_email_copy)
2397
- if not hasattr(self, "_cached_include_editable_documents"):
2398
- self._cached_include_editable_documents = str(
2399
- self.include_editable_documents
2400
- )
2401
2414
 
2402
2415
  if isinstance(preferred_formats, str):
2403
2416
  preferred_formats = [preferred_formats]
@@ -2431,7 +2444,7 @@ class ALDocumentBundle(DAList):
2431
2444
  # Container of whole email section with header
2432
2445
  return_str = f"""
2433
2446
  <fieldset class="al_send_bundle al_send_section_alone {html_safe_str(self.instanceName)}" id="al_send_bundle_{name}" name="al_send_bundle_{name}">
2434
- <legend class="h4 al_doc_email_header">{self._cached_get_email_copy}</legend>
2447
+ <legend class="h4 al_doc_email_header">{str(self.get_email_copy)}</legend>
2435
2448
  """
2436
2449
  # "Editable" checkbox
2437
2450
  if (
@@ -2444,7 +2457,7 @@ class ALDocumentBundle(DAList):
2444
2457
  <div class="form-check-container">
2445
2458
  <div class="form-check">
2446
2459
  <input class="form-check-input al_wants_editable" type="checkbox" id="{al_wants_editable_input_id}">
2447
- <label class="al_wants_editable form-check-label" for="{al_wants_editable_input_id}">{self._cached_include_editable_documents}
2460
+ <label class="al_wants_editable form-check-label" for="{al_wants_editable_input_id}">{str(self.include_editable_documents)}
2448
2461
  </label>
2449
2462
  </div>
2450
2463
  </div>
@@ -2863,10 +2876,11 @@ class ALExhibitList(DAList):
2863
2876
 
2864
2877
  Attributes:
2865
2878
  maximum_size (int): The maximum allowed size in bytes of the entire document.
2879
+ maximum_size_per_doc (int): The maximum allowed size in bytes per document in the list
2866
2880
  auto_label (bool): If True, automatically numbers exhibits for cover page and table of contents. Defaults to True.
2867
2881
  auto_labeler (Callable): An optional function or lambda to transform the exhibit's index to a label.
2868
2882
  Uses A..Z labels by default.
2869
- auto_ocr (bool): If True, automatically starts OCR processing for uploaded exhibits. Defaults to True.
2883
+ auto_ocr (bool): If True, automatically starts OCR processing for uploaded exhibits. Defaults to False.
2870
2884
  """
2871
2885
 
2872
2886
  def init(self, *pargs, **kwargs) -> None:
@@ -3061,6 +3075,7 @@ class ALExhibitDocument(ALDocument):
3061
3075
  auto_ocr: bool
3062
3076
  bates_prefix: str
3063
3077
  maximum_size: int
3078
+ maximum_size_per_doc: int
3064
3079
  suffix_to_append: str
3065
3080
  exhibits: ALExhibitList
3066
3081
  table_of_contents: DAFile
@@ -3085,8 +3100,13 @@ class ALExhibitDocument(ALDocument):
3085
3100
  else:
3086
3101
  self.include_exhibit_cover_pages = True
3087
3102
  self.exhibits.include_exhibit_cover_pages = True
3103
+ if hasattr(self, "maximum_size_per_doc"):
3104
+ self.exhibits.maximum_size_per_doc = self.maximum_size_per_doc
3088
3105
  if hasattr(self, "maximum_size"):
3089
3106
  self.exhibits.maximum_size = self.maximum_size
3107
+ if not hasattr(self, "maximum_size_per_doc"):
3108
+ self.maximum_size_per_doc = self.maximum_size
3109
+ self.exhibits.maximum_size_per_doc = self.maximum_size
3090
3110
  if hasattr(self, "include_table_of_contents"):
3091
3111
  self.exhibits.include_table_of_contents = self.include_table_of_contents
3092
3112
  else:
@@ -28,7 +28,6 @@ from docassemble.base.util import (
28
28
  states_list,
29
29
  subdivision_type,
30
30
  their,
31
- this_thread,
32
31
  url_action,
33
32
  validation_error,
34
33
  value,
@@ -38,6 +37,7 @@ from docassemble.base.util import (
38
37
  value,
39
38
  )
40
39
  from docassemble.ALToolbox.misc import fa_icon
40
+ import docassemble.base.functions
41
41
  import random
42
42
  import re
43
43
  import pycountry
@@ -374,7 +374,7 @@ class ALAddress(Address):
374
374
  Returns:
375
375
  str: The one-line formatted address.
376
376
  """
377
- if this_thread.evaluation_context == "docx":
377
+ if docassemble.base.functions.this_thread.evaluation_context == "docx":
378
378
  line_breaker = '</w:t><w:br/><w:t xml:space="preserve">'
379
379
  else:
380
380
  line_breaker = " [NEWLINE] "
@@ -1701,7 +1701,7 @@ class ALIndividual(Individual):
1701
1701
  Returns:
1702
1702
  str: The formatted address block.
1703
1703
  """
1704
- if this_thread.evaluation_context == "docx":
1704
+ if docassemble.base.functions.this_thread.evaluation_context == "docx":
1705
1705
  if isinstance(self.address, ALAddress):
1706
1706
  return self.address.block(
1707
1707
  language=language,
@@ -1778,7 +1778,7 @@ class ALIndividual(Individual):
1778
1778
  else:
1779
1779
  pronouns = self.pronouns
1780
1780
 
1781
- if self == this_thread.global_vars.user:
1781
+ if self == docassemble.base.functions.this_thread.global_vars.user:
1782
1782
  output = word("you", **kwargs)
1783
1783
  elif hasattr(self, "pronouns") and self.pronouns:
1784
1784
  pronouns_to_use = []
@@ -1876,7 +1876,7 @@ class ALIndividual(Individual):
1876
1876
  else:
1877
1877
  default = self.name_full()
1878
1878
 
1879
- if self == this_thread.global_vars.user and (
1879
+ if self == docassemble.base.functions.this_thread.global_vars.user and (
1880
1880
  "thirdperson" not in kwargs or not kwargs["thirdperson"]
1881
1881
  ):
1882
1882
  output = your(target, **kwargs)
@@ -1963,7 +1963,7 @@ class ALIndividual(Individual):
1963
1963
  else:
1964
1964
  pronouns = self.pronouns
1965
1965
 
1966
- if self == this_thread.global_vars.user:
1966
+ if self == docassemble.base.functions.this_thread.global_vars.user:
1967
1967
  output = word("you", **kwargs)
1968
1968
  elif hasattr(self, "pronouns") and self.pronouns:
1969
1969
  pronouns_to_use = []
@@ -2042,7 +2042,7 @@ class ALIndividual(Individual):
2042
2042
  if person == "2p":
2043
2043
  return word("yourselves")
2044
2044
 
2045
- if self == this_thread.global_vars.user:
2045
+ if self == docassemble.base.functions.this_thread.global_vars.user:
2046
2046
  output = word("yourself", **kwargs)
2047
2047
 
2048
2048
  if "default" in kwargs:
@@ -2058,7 +2058,7 @@ class ALIndividual(Individual):
2058
2058
  else:
2059
2059
  pronouns = None
2060
2060
 
2061
- if self == this_thread.global_vars.user:
2061
+ if self == docassemble.base.functions.this_thread.global_vars.user:
2062
2062
  output = word("yourself", **kwargs)
2063
2063
  elif hasattr(self, "pronouns") and self.pronouns:
2064
2064
  pronouns_to_use = []
@@ -2188,10 +2188,10 @@ class ALIndividual(Individual):
2188
2188
 
2189
2189
  In order, it will try to use:
2190
2190
 
2191
- * just the first name
2192
- * the first name and suffix
2193
- * the first and middle name
2194
- * the first and last name
2191
+ * just the preferred name (if set) or first name
2192
+ * the preferred/first name and suffix
2193
+ * the preferred/first and middle name
2194
+ * the preferred/first and last name
2195
2195
  * the full name
2196
2196
  * the default value, e.g., "the minor", if provided
2197
2197
  * the full name
@@ -2221,33 +2221,42 @@ class ALIndividual(Individual):
2221
2221
  if unique_names is None:
2222
2222
  unique_names = []
2223
2223
 
2224
+ # Use preferred_name.first if it exists and is non-empty, otherwise use name.first
2225
+ first_name_to_use = self.name.first
2226
+ if (
2227
+ hasattr(self, "preferred_name")
2228
+ and hasattr(self.preferred_name, "first")
2229
+ and self.preferred_name.first
2230
+ ):
2231
+ first_name_to_use = self.preferred_name.first
2232
+
2224
2233
  first_name_candidates = [person.familiar() for person in unique_names]
2225
- if self.name.first not in first_name_candidates:
2226
- return self.name.first
2234
+ if first_name_to_use not in first_name_candidates:
2235
+ return first_name_to_use
2227
2236
 
2228
2237
  first_name_and_suffix_candidates = [
2229
2238
  f"{person.familiar()} {person.name.suffix if hasattr(person.name, 'suffix') else ''}"
2230
2239
  for person in unique_names
2231
2240
  ]
2232
2241
  if (
2233
- f"{self.name.first} {self.name.suffix if hasattr(self.name, 'suffix') else ''}"
2242
+ f"{first_name_to_use} {self.name.suffix if hasattr(self.name, 'suffix') else ''}"
2234
2243
  not in first_name_and_suffix_candidates
2235
2244
  ):
2236
2245
  if hasattr(self.name, "suffix") and self.name.suffix:
2237
- return f"{self.name.first} {self.name.suffix if hasattr(self.name, 'suffix') else ''}"
2238
- return self.name.first
2246
+ return f"{first_name_to_use} {self.name.suffix if hasattr(self.name, 'suffix') else ''}"
2247
+ return first_name_to_use
2239
2248
 
2240
2249
  first_and_middle_candidates = [
2241
2250
  f"{person.name.first} {person.name.middle if hasattr(person.name, 'middle') and person.name.middle else ''}"
2242
2251
  for person in unique_names
2243
2252
  ]
2244
2253
  if (
2245
- f"{self.name.first} {self.name.middle if hasattr(self.name, 'middle') and self.name.middle else ''}"
2254
+ f"{first_name_to_use} {self.name.middle if hasattr(self.name, 'middle') and self.name.middle else ''}"
2246
2255
  not in first_and_middle_candidates
2247
2256
  ):
2248
2257
  if hasattr(self.name, "middle") and self.name.middle:
2249
- return f"{self.name.first} {self.name.middle}"
2250
- return self.name.first
2258
+ return f"{first_name_to_use} {self.name.middle}"
2259
+ return first_name_to_use
2251
2260
 
2252
2261
  first_and_last_candidates = [
2253
2262
  (
@@ -26,6 +26,7 @@ initial: True
26
26
  code: |
27
27
  if enable_al_language:
28
28
  set_language(al_user_language)
29
+ process_action()
29
30
  ---
30
31
  code: |
31
32
  if enable_al_language:
@@ -1882,6 +1882,9 @@ validation code: |
1882
1882
  if hasattr(x, 'maximum_size'):
1883
1883
  if full_size > x.maximum_size:
1884
1884
  validation_error(f"Upload a file smaller than {humanize.naturalsize(x.maximum_size)}")
1885
+ if hasattr(x, 'maximum_size_per_doc'):
1886
+ if full_size > x.maximum_size_per_doc:
1887
+ validation_error(f"Upload a file smaller than {humanize.naturalsize(x.maximum_size)}")
1885
1888
  try:
1886
1889
  pdf_concatenate(x[0].pages)
1887
1890
  except:
@@ -1910,6 +1913,9 @@ fields:
1910
1913
  "image/png, image/jpeg, .doc,.docx,application/msword,application/vnd.openxmlformats-officedocument.wordprocessingml.document,application/pdf,.pdf"
1911
1914
  validation code: |
1912
1915
  this_doc_size = sum(a_page.size_in_bytes() for a_page in x[i].pages)
1916
+ if hasattr(x, 'maximum_size_per_doc'):
1917
+ if this_doc_size > x.maximum_size_per_doc:
1918
+ validation_error(f"This document should be smaller than {humanize.naturalsize(x.maximum_size_per_doc)}")
1913
1919
  if this_doc_size > (15 * 1024 * 1024):
1914
1920
  validation_error("Upload a file smaller than 15 MB.")
1915
1921
  if hasattr(x, 'maximum_size'):
@@ -1923,6 +1929,10 @@ validation code: |
1923
1929
  validation_error("Unable to convert this file. Please upload a new one.")
1924
1930
  x[i].pages.reset_gathered() # docassemble sets this attribute but we want to force gathering additional pages
1925
1931
  ---
1932
+ # Only necessary to ignore playground "undefined names" warning
1933
+ objects:
1934
+ - current_doc_size: DAEmpty()
1935
+ ---
1926
1936
  generic object: ALExhibitList
1927
1937
  id: exhibit i has additional pages
1928
1938
  question: |
@@ -1930,9 +1940,19 @@ question: |
1930
1940
  subquestion: |
1931
1941
  You have uploaded ${ x[i].pages.num_pages() } pages so far.
1932
1942
 
1943
+ <% current_doc_size = sum(ap.size_in_bytes() for ap in x[i].pages.complete_elements()) %>
1944
+ % if hasattr(x, 'maximum_size_per_doc'):
1945
+ This document must be smaller than ${ humanize.naturalsize(x.maximum_size_per_doc) }.
1946
+ % if not hasattr(x, 'maximum_size') or x.maximum_size_per_doc - current_doc_size < x.maximum_size - x.size_in_bytes() - current_doc_size:
1947
+ You can upload ${ humanize.naturalsize(x.maximum_size_per_doc - current_doc_size) } more.
1948
+ % else:
1949
+ You can upload ${ humanize.naturalsize(x.maximum_size - x.size_in_bytes() - current_doc_size) } more.
1950
+ % endif
1951
+ % endif
1952
+
1933
1953
  % if hasattr(x, 'maximum_size'):
1934
1954
  The total size of all exhibits must be less than ${ humanize.naturalsize(x.maximum_size) }.
1935
- You can upload ${ humanize.naturalsize(x.maximum_size - x.size_in_bytes() - sum(ap.size_in_bytes() for ap in x[i].pages.complete_elements()))} more.
1955
+ You can upload ${ humanize.naturalsize(x.maximum_size - x.size_in_bytes() - current_doc_size) } more.
1936
1956
  % endif
1937
1957
 
1938
1958
  ${ collapse_template(x[i].in_progress_template )}
@@ -1968,11 +1988,16 @@ fields:
1968
1988
  "image/png, image/jpeg, .doc,.docx,application/msword,application/vnd.openxmlformats-officedocument.wordprocessingml.document,application/pdf,.pdf"
1969
1989
  validation code: |
1970
1990
  page_size = x[i].pages[j].size_in_bytes()
1991
+ this_doc_size = sum(a_page.size_in_bytes() for a_page in x[i].pages.complete_elements()) + page_size
1992
+ log(f"length of completed elements: {len(x[i].pages.complete_elements())}")
1993
+ if hasattr(x, 'maximum_size_per_doc'):
1994
+ if this_doc_size > x.maximum_size_per_doc:
1995
+ suggested_size = x.maximum_size_per_doc - (this_doc_size - page_size)
1996
+ validation_error(f"This document must be smaller than {humanize.naturalsize(x.maximum_size_per_doc) }. Upload a file smaller than {humanize.naturalsize(suggested_size)}.")
1997
+
1971
1998
  if page_size > (15 * 1024 * 1024):
1972
1999
  validation_error("Upload a file smaller than 15 MB.")
1973
2000
  if hasattr(x, 'maximum_size'):
1974
- # this_doc_size already includes `page_size`
1975
- this_doc_size = sum(a_page.size_in_bytes() for a_page in x[i].pages.complete_elements())
1976
2001
  full_size = x.size_in_bytes() + this_doc_size
1977
2002
  if full_size > x.maximum_size:
1978
2003
  suggested_size = x.maximum_size - (full_size - page_size)
@@ -2593,4 +2618,20 @@ data:
2593
2618
  - Lt.
2594
2619
  - Sgt.
2595
2620
  - Fr.
2596
- - Sr.
2621
+ - Sr.
2622
+ ---
2623
+ generic object: ALDocumentBundle
2624
+ template: x.view_label
2625
+ content: "View"
2626
+ ---
2627
+ generic object: ALDocumentBundle
2628
+ template: x.download_label
2629
+ content: "Download"
2630
+ ---
2631
+ generic object: ALDocumentBundle
2632
+ template: x.send_label
2633
+ content: "Send"
2634
+ ---
2635
+ generic object: ALDocumentBundle
2636
+ template: x.send_button_to_label
2637
+ content: "Send"
@@ -1,6 +1,9 @@
1
1
  ---
2
2
  include:
3
- - al_package.yml
3
+ - assembly_line.yml
4
+ ---
5
+ code: |
6
+ al_interview_languages = ["en", "es", "ht", "pt"]
4
7
  ---
5
8
  metadata:
6
9
  title: |
@@ -10,7 +10,7 @@ objects:
10
10
  - exhibits_bundle_defaults_1: ALDocumentBundle.using(elements=[exhibit_doc_defaults_1], filename="exhibits_bundle_defaults", title="Exhibits with defaults")
11
11
  ---
12
12
  objects:
13
- - exhibit_doc_defaults_1: ALExhibitDocument.using(title="Exhibits doc defaults", filename="exhibits_doc_defaults", maximum_size=1*1024*1024 )
13
+ - exhibit_doc_defaults_1: ALExhibitDocument.using(title="Exhibits doc defaults", filename="exhibits_doc_defaults", maximum_size=3*1024*1024, maximum_size_per_doc=1*1024*1024)
14
14
  ---
15
15
  id: gather_main
16
16
  event: gather_main