docassemble.AssemblyLine 3.0.1__tar.gz → 3.2.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 (91) hide show
  1. {docassemble_assemblyline-3.0.1/docassemble.AssemblyLine.egg-info → docassemble_assemblyline-3.2.0}/PKG-INFO +1 -1
  2. docassemble_assemblyline-3.2.0/docassemble/AssemblyLine/__init__.py +1 -0
  3. {docassemble_assemblyline-3.0.1 → docassemble_assemblyline-3.2.0}/docassemble/AssemblyLine/al_document.py +169 -55
  4. {docassemble_assemblyline-3.0.1 → docassemble_assemblyline-3.2.0}/docassemble/AssemblyLine/al_general.py +310 -118
  5. {docassemble_assemblyline-3.0.1 → docassemble_assemblyline-3.2.0}/docassemble/AssemblyLine/data/questions/al_document.yml +77 -1
  6. {docassemble_assemblyline-3.0.1 → docassemble_assemblyline-3.2.0}/docassemble/AssemblyLine/data/questions/al_visual.yml +21 -4
  7. {docassemble_assemblyline-3.0.1 → docassemble_assemblyline-3.2.0}/docassemble/AssemblyLine/data/questions/demo_search_sessions.yml +12 -1
  8. {docassemble_assemblyline-3.0.1 → docassemble_assemblyline-3.2.0}/docassemble/AssemblyLine/data/questions/interview_list.yml +55 -4
  9. docassemble_assemblyline-3.2.0/docassemble/AssemblyLine/data/questions/test_aldocument_background_assembly.yml +65 -0
  10. docassemble_assemblyline-3.2.0/docassemble/AssemblyLine/data/sources/translation_es_broken.xlsx +0 -0
  11. {docassemble_assemblyline-3.0.1 → docassemble_assemblyline-3.2.0}/docassemble/AssemblyLine/requirements.txt +2 -1
  12. {docassemble_assemblyline-3.0.1 → docassemble_assemblyline-3.2.0}/docassemble/AssemblyLine/sessions.py +274 -83
  13. {docassemble_assemblyline-3.0.1 → docassemble_assemblyline-3.2.0}/docassemble/AssemblyLine/test_al_general.py +3 -3
  14. {docassemble_assemblyline-3.0.1 → docassemble_assemblyline-3.2.0/docassemble.AssemblyLine.egg-info}/PKG-INFO +1 -1
  15. {docassemble_assemblyline-3.0.1 → docassemble_assemblyline-3.2.0}/docassemble.AssemblyLine.egg-info/SOURCES.txt +2 -0
  16. {docassemble_assemblyline-3.0.1 → docassemble_assemblyline-3.2.0}/setup.py +1 -1
  17. docassemble_assemblyline-3.0.1/docassemble/AssemblyLine/__init__.py +0 -1
  18. {docassemble_assemblyline-3.0.1 → docassemble_assemblyline-3.2.0}/LICENSE +0 -0
  19. {docassemble_assemblyline-3.0.1 → docassemble_assemblyline-3.2.0}/MANIFEST.in +0 -0
  20. {docassemble_assemblyline-3.0.1 → docassemble_assemblyline-3.2.0}/README.md +0 -0
  21. {docassemble_assemblyline-3.0.1 → docassemble_assemblyline-3.2.0}/docassemble/AssemblyLine/al_courts.py +0 -0
  22. {docassemble_assemblyline-3.0.1 → docassemble_assemblyline-3.2.0}/docassemble/AssemblyLine/data/questions/al_code.yml +0 -0
  23. {docassemble_assemblyline-3.0.1 → docassemble_assemblyline-3.2.0}/docassemble/AssemblyLine/data/questions/al_language.yml +0 -0
  24. {docassemble_assemblyline-3.0.1 → docassemble_assemblyline-3.2.0}/docassemble/AssemblyLine/data/questions/al_package.yml +0 -0
  25. {docassemble_assemblyline-3.0.1 → docassemble_assemblyline-3.2.0}/docassemble/AssemblyLine/data/questions/al_package_unstyled.yml +0 -0
  26. {docassemble_assemblyline-3.0.1 → docassemble_assemblyline-3.2.0}/docassemble/AssemblyLine/data/questions/al_question_test.yml +0 -0
  27. {docassemble_assemblyline-3.0.1 → docassemble_assemblyline-3.2.0}/docassemble/AssemblyLine/data/questions/al_reminders.yml +0 -0
  28. {docassemble_assemblyline-3.0.1 → docassemble_assemblyline-3.2.0}/docassemble/AssemblyLine/data/questions/al_saved_sessions.yml +0 -0
  29. {docassemble_assemblyline-3.0.1 → docassemble_assemblyline-3.2.0}/docassemble/AssemblyLine/data/questions/al_saved_sessions_store.yml +0 -0
  30. {docassemble_assemblyline-3.0.1 → docassemble_assemblyline-3.2.0}/docassemble/AssemblyLine/data/questions/al_settings.yml +0 -0
  31. {docassemble_assemblyline-3.0.1 → docassemble_assemblyline-3.2.0}/docassemble/AssemblyLine/data/questions/al_terms_of_use.yml +0 -0
  32. {docassemble_assemblyline-3.0.1 → docassemble_assemblyline-3.2.0}/docassemble/AssemblyLine/data/questions/assembly_line.yml +0 -0
  33. {docassemble_assemblyline-3.0.1 → docassemble_assemblyline-3.2.0}/docassemble/AssemblyLine/data/questions/assembly_line_unstyled.yml +0 -0
  34. {docassemble_assemblyline-3.0.1 → docassemble_assemblyline-3.2.0}/docassemble/AssemblyLine/data/questions/feedback.yml +0 -0
  35. {docassemble_assemblyline-3.0.1 → docassemble_assemblyline-3.2.0}/docassemble/AssemblyLine/data/questions/ql_baseline.yml +0 -0
  36. {docassemble_assemblyline-3.0.1 → docassemble_assemblyline-3.2.0}/docassemble/AssemblyLine/data/questions/ql_catchall.yml +0 -0
  37. {docassemble_assemblyline-3.0.1 → docassemble_assemblyline-3.2.0}/docassemble/AssemblyLine/data/questions/reserved_words.yml +0 -0
  38. {docassemble_assemblyline-3.0.1 → docassemble_assemblyline-3.2.0}/docassemble/AssemblyLine/data/questions/test_al_table_document.yml +0 -0
  39. {docassemble_assemblyline-3.0.1 → docassemble_assemblyline-3.2.0}/docassemble/AssemblyLine/data/questions/test_aladdendum.yml +0 -0
  40. {docassemble_assemblyline-3.0.1 → docassemble_assemblyline-3.2.0}/docassemble/AssemblyLine/data/questions/test_alcourts.yml +0 -0
  41. {docassemble_assemblyline-3.0.1 → docassemble_assemblyline-3.2.0}/docassemble/AssemblyLine/data/questions/test_aldocument.yml +0 -0
  42. {docassemble_assemblyline-3.0.1 → docassemble_assemblyline-3.2.0}/docassemble/AssemblyLine/data/questions/test_alexhibit.yml +0 -0
  43. {docassemble_assemblyline-3.0.1 → docassemble_assemblyline-3.2.0}/docassemble/AssemblyLine/data/questions/test_alexhibit_maxsize.yml +0 -0
  44. {docassemble_assemblyline-3.0.1 → docassemble_assemblyline-3.2.0}/docassemble/AssemblyLine/data/questions/test_bundle_parity.yml +0 -0
  45. {docassemble_assemblyline-3.0.1 → docassemble_assemblyline-3.2.0}/docassemble/AssemblyLine/data/questions/test_familiar_disambiguation.yml +0 -0
  46. {docassemble_assemblyline-3.0.1 → docassemble_assemblyline-3.2.0}/docassemble/AssemblyLine/data/questions/test_question_library.yml +0 -0
  47. {docassemble_assemblyline-3.0.1 → docassemble_assemblyline-3.2.0}/docassemble/AssemblyLine/data/sources/README.md +0 -0
  48. {docassemble_assemblyline-3.0.1 → docassemble_assemblyline-3.2.0}/docassemble/AssemblyLine/data/sources/es-words.yml +0 -0
  49. {docassemble_assemblyline-3.0.1 → docassemble_assemblyline-3.2.0}/docassemble/AssemblyLine/data/sources/languages.yml +0 -0
  50. {docassemble_assemblyline-3.0.1 → docassemble_assemblyline-3.2.0}/docassemble/AssemblyLine/data/sources/test_aldocument.feature +0 -0
  51. {docassemble_assemblyline-3.0.1 → docassemble_assemblyline-3.2.0}/docassemble/AssemblyLine/data/sources/test_alexhibit_docx_1.docx +0 -0
  52. {docassemble_assemblyline-3.0.1 → docassemble_assemblyline-3.2.0}/docassemble/AssemblyLine/data/sources/test_alexhibit_jpg_1.jpg +0 -0
  53. {docassemble_assemblyline-3.0.1 → docassemble_assemblyline-3.2.0}/docassemble/AssemblyLine/data/sources/test_alexhibit_pdf_1.pdf +0 -0
  54. {docassemble_assemblyline-3.0.1 → docassemble_assemblyline-3.2.0}/docassemble/AssemblyLine/data/sources/test_alexhibit_png_1.png +0 -0
  55. {docassemble_assemblyline-3.0.1 → docassemble_assemblyline-3.2.0}/docassemble/AssemblyLine/data/sources/test_question_library.feature +0 -0
  56. {docassemble_assemblyline-3.0.1 → docassemble_assemblyline-3.2.0}/docassemble/AssemblyLine/data/sources/translation_es.xlsx +0 -0
  57. {docassemble_assemblyline-3.0.1 → docassemble_assemblyline-3.2.0}/docassemble/AssemblyLine/data/sources/translation_ht.xlsx +0 -0
  58. {docassemble_assemblyline-3.0.1 → docassemble_assemblyline-3.2.0}/docassemble/AssemblyLine/data/sources/translation_pt.xlsx +0 -0
  59. {docassemble_assemblyline-3.0.1 → docassemble_assemblyline-3.2.0}/docassemble/AssemblyLine/data/static/README.md +0 -0
  60. {docassemble_assemblyline-3.0.1 → docassemble_assemblyline-3.2.0}/docassemble/AssemblyLine/data/static/al_audio.css +0 -0
  61. {docassemble_assemblyline-3.0.1 → docassemble_assemblyline-3.2.0}/docassemble/AssemblyLine/data/static/al_audio.js +0 -0
  62. {docassemble_assemblyline-3.0.1 → docassemble_assemblyline-3.2.0}/docassemble/AssemblyLine/data/static/aldocument.css +0 -0
  63. {docassemble_assemblyline-3.0.1 → docassemble_assemblyline-3.2.0}/docassemble/AssemblyLine/data/static/aldocument.js +0 -0
  64. {docassemble_assemblyline-3.0.1 → docassemble_assemblyline-3.2.0}/docassemble/AssemblyLine/data/static/interview_list.css +0 -0
  65. {docassemble_assemblyline-3.0.1 → docassemble_assemblyline-3.2.0}/docassemble/AssemblyLine/data/static/limit_upload_size.js +0 -0
  66. {docassemble_assemblyline-3.0.1 → docassemble_assemblyline-3.2.0}/docassemble/AssemblyLine/data/static/lt1-pullout-10-getting-organized.pdf +0 -0
  67. {docassemble_assemblyline-3.0.1 → docassemble_assemblyline-3.2.0}/docassemble/AssemblyLine/data/static/ma_logo.png +0 -0
  68. {docassemble_assemblyline-3.0.1 → docassemble_assemblyline-3.2.0}/docassemble/AssemblyLine/data/static/placeholder.png +0 -0
  69. {docassemble_assemblyline-3.0.1 → docassemble_assemblyline-3.2.0}/docassemble/AssemblyLine/data/static/seal.jpg +0 -0
  70. {docassemble_assemblyline-3.0.1 → docassemble_assemblyline-3.2.0}/docassemble/AssemblyLine/data/static/styles.css +0 -0
  71. {docassemble_assemblyline-3.0.1 → docassemble_assemblyline-3.2.0}/docassemble/AssemblyLine/data/templates/README.md +0 -0
  72. {docassemble_assemblyline-3.0.1 → docassemble_assemblyline-3.2.0}/docassemble/AssemblyLine/data/templates/al_basic_addendum.docx +0 -0
  73. {docassemble_assemblyline-3.0.1 → docassemble_assemblyline-3.2.0}/docassemble/AssemblyLine/data/templates/exhibit_cover_sheet.docx +0 -0
  74. {docassemble_assemblyline-3.0.1 → docassemble_assemblyline-3.2.0}/docassemble/AssemblyLine/data/templates/exhibit_table_of_contents.docx +0 -0
  75. {docassemble_assemblyline-3.0.1 → docassemble_assemblyline-3.2.0}/docassemble/AssemblyLine/data/templates/general_cover_sheet.docx +0 -0
  76. {docassemble_assemblyline-3.0.1 → docassemble_assemblyline-3.2.0}/docassemble/AssemblyLine/data/templates/sample_word_template.docx +0 -0
  77. {docassemble_assemblyline-3.0.1 → docassemble_assemblyline-3.2.0}/docassemble/AssemblyLine/data/templates/test_aldocument_docx_1.docx +0 -0
  78. {docassemble_assemblyline-3.0.1 → docassemble_assemblyline-3.2.0}/docassemble/AssemblyLine/data/templates/test_aldocument_pdf_1.pdf +0 -0
  79. {docassemble_assemblyline-3.0.1 → docassemble_assemblyline-3.2.0}/docassemble/AssemblyLine/language.py +0 -0
  80. {docassemble_assemblyline-3.0.1 → docassemble_assemblyline-3.2.0}/docassemble/AssemblyLine/project_maintenance.py +0 -0
  81. {docassemble_assemblyline-3.0.1 → docassemble_assemblyline-3.2.0}/docassemble/AssemblyLine/py.typed +0 -0
  82. {docassemble_assemblyline-3.0.1 → docassemble_assemblyline-3.2.0}/docassemble/AssemblyLine/test_al_document.py +0 -0
  83. {docassemble_assemblyline-3.0.1 → docassemble_assemblyline-3.2.0}/docassemble/AssemblyLine/test_language.py +0 -0
  84. {docassemble_assemblyline-3.0.1 → docassemble_assemblyline-3.2.0}/docassemble/__init__.py +0 -0
  85. {docassemble_assemblyline-3.0.1 → docassemble_assemblyline-3.2.0}/docassemble.AssemblyLine.egg-info/dependency_links.txt +0 -0
  86. {docassemble_assemblyline-3.0.1 → docassemble_assemblyline-3.2.0}/docassemble.AssemblyLine.egg-info/namespace_packages.txt +0 -0
  87. {docassemble_assemblyline-3.0.1 → docassemble_assemblyline-3.2.0}/docassemble.AssemblyLine.egg-info/not-zip-safe +0 -0
  88. {docassemble_assemblyline-3.0.1 → docassemble_assemblyline-3.2.0}/docassemble.AssemblyLine.egg-info/requires.txt +0 -0
  89. {docassemble_assemblyline-3.0.1 → docassemble_assemblyline-3.2.0}/docassemble.AssemblyLine.egg-info/top_level.txt +0 -0
  90. {docassemble_assemblyline-3.0.1 → docassemble_assemblyline-3.2.0}/pyproject.toml +0 -0
  91. {docassemble_assemblyline-3.0.1 → docassemble_assemblyline-3.2.0}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: docassemble.AssemblyLine
3
- Version: 3.0.1
3
+ Version: 3.2.0
4
4
  Home-page: https://courtformsonline.org
5
5
  Author: Suffolk Legal Innovation and Technology Lab
6
6
  Author-email: qsteenhuis@suffolk.edu
@@ -0,0 +1 @@
1
+ __version__ = '3.2.0'
@@ -35,6 +35,7 @@ from math import floor
35
35
  import subprocess
36
36
  from collections import ChainMap
37
37
  import pikepdf
38
+ from typing import Tuple
38
39
 
39
40
  __all__ = [
40
41
  "ALAddendumField",
@@ -1822,6 +1823,107 @@ class ALDocumentBundle(DAList):
1822
1823
  editable.append(doc)
1823
1824
  return editable
1824
1825
 
1826
+ def get_cacheable_documents(
1827
+ self,
1828
+ key: str = "final",
1829
+ pdf: bool = True,
1830
+ docx: bool = False,
1831
+ original: bool = False,
1832
+ refresh: bool = True,
1833
+ pdfa: bool = False,
1834
+ include_zip: bool = True,
1835
+ include_full_pdf: bool = False,
1836
+ append_matching_suffix: bool = True,
1837
+ ) -> Tuple[List[Dict[str, DAFile]], Optional[DAFile], Optional[DAFile]]:
1838
+ """
1839
+ Generates a cache of all enabled documents in the bundle, and returns it in a structure that can be cached
1840
+ and returned for use in a background process.
1841
+
1842
+ The result looks like this:
1843
+
1844
+ [
1845
+ {"title": "Document 1", "pdf": DAFile, "docx": DAFile, download_filename: str},
1846
+ ],
1847
+ DAFile, # Zip of whole bundle
1848
+ DAFile # PDF of whole bundle
1849
+
1850
+ Args:
1851
+ key (str): Identifier for the document version, default is "final".
1852
+ pdf (bool): Flag to include a PDF version of each file, default is True.
1853
+ docx (bool): Flag to include a DOCX version of each file, default is False.
1854
+ original (bool): Flag to include the original version of each file, default is False.
1855
+ refresh (bool): Flag to reconsider the 'enabled' attribute, default is True.
1856
+ pdfa (bool): Flag to return documents in PDF/A format, default is False.
1857
+ include_zip (bool): Flag to include a zip option, default is True.
1858
+ include_full_pdf (bool): Flag to include a PDF version of the whole bundle, default is False.
1859
+ append_matching_suffix (bool): Flag to determine if matching suffix should be appended to file name, default is True.
1860
+
1861
+ Returns:
1862
+ Tuple[List[Dict[str, DAFile]], Optional[DAFile], Optional[DAFile]]: A list of dictionaries containing the enabled documents, a zip file of the whole bundle, and a PDF of the whole
1863
+ """
1864
+ # reduce idempotency delays
1865
+ enabled_docs = self.enabled_documents(refresh=refresh)
1866
+ for doc in enabled_docs:
1867
+ doc.title
1868
+
1869
+ results = []
1870
+
1871
+ for doc in enabled_docs:
1872
+ result = {"title": doc.title}
1873
+ filename_root = os.path.splitext(str(doc.filename))[0]
1874
+ if pdf:
1875
+ result["pdf"] = doc.as_pdf(
1876
+ key=key,
1877
+ refresh=refresh,
1878
+ pdfa=pdfa,
1879
+ append_matching_suffix=append_matching_suffix,
1880
+ )
1881
+ result["download_filename"] = filename_root + ".pdf"
1882
+ if docx and doc._is_docx(key=key):
1883
+ result["docx"] = doc.as_docx(
1884
+ key=key,
1885
+ refresh=refresh,
1886
+ append_matching_suffix=append_matching_suffix,
1887
+ )
1888
+ result["download_filename"] = filename_root + ".docx"
1889
+ if original:
1890
+ result["original"] = doc[key]
1891
+ result["download_filename"] = doc.filename
1892
+
1893
+ try:
1894
+ # If it's possible, set the file extension to the actual filetype
1895
+ # This is mostly necessary if people omit the file extension in attachment block
1896
+ # for filetype="original"
1897
+ if original:
1898
+ download_doc = result["original"]
1899
+ else:
1900
+ download_doc = result["docx"]
1901
+ ext = next(
1902
+ iter(
1903
+ mimetypes.guess_all_extensions(
1904
+ download_doc.mimetype, strict=True
1905
+ )
1906
+ )
1907
+ )
1908
+ result["download_filename"] = filename_root + ext
1909
+ except:
1910
+ pass
1911
+ results.append(result)
1912
+
1913
+ if len(enabled_docs) > 1 and include_zip:
1914
+ bundled_zip = self.as_zip(
1915
+ key=key, format="original" if original else "docx" if docx else "pdf"
1916
+ )
1917
+ else:
1918
+ bundled_zip = None
1919
+
1920
+ if len(enabled_docs) > 1 and include_full_pdf:
1921
+ bundled_pdf = self.as_pdf(key=key, pdfa=pdfa)
1922
+ else:
1923
+ bundled_pdf = None
1924
+
1925
+ return results, bundled_zip, bundled_pdf
1926
+
1825
1927
  def download_list_html(
1826
1928
  self,
1827
1929
  key: str = "final",
@@ -1838,6 +1940,9 @@ class ALDocumentBundle(DAList):
1838
1940
  zip_icon: str = "file-archive",
1839
1941
  append_matching_suffix: bool = True,
1840
1942
  include_email: bool = False,
1943
+ use_previously_cached_files: bool = False,
1944
+ include_full_pdf: bool = False,
1945
+ full_pdf_label: Optional[str] = None,
1841
1946
  ) -> str:
1842
1947
  """
1843
1948
  Constructs an HTML table displaying a list of documents with 'view' and 'download' buttons.
@@ -1857,6 +1962,9 @@ class ALDocumentBundle(DAList):
1857
1962
  zip_icon (str): Icon for the zip option, default is "file-archive".
1858
1963
  append_matching_suffix (bool): Flag to determine if matching suffix should be appended to file name, default is True.
1859
1964
  include_email (bool): Flag to include an email option, default is False.
1965
+ use_previously_cached_files (bool): Flag to use previously cached files (e.g., made in background) if defined. default is False.
1966
+ include_full_pdf (bool): Flag to include a full PDF option, default is False.
1967
+ full_pdf_label (Optional[str]): Label for the full PDF option. If not provided, uses the generic template for `self.full_pdf_label` ("Download all").
1860
1968
 
1861
1969
  Returns:
1862
1970
  str: HTML representation of a table with documents and their associated actions.
@@ -1864,52 +1972,40 @@ class ALDocumentBundle(DAList):
1864
1972
  if not hasattr(self, "_cached_zip_label"):
1865
1973
  self._cached_zip_label = str(self.zip_label)
1866
1974
 
1867
- # Trigger some variables up top to avoid idempotency issues
1868
- enabled_docs = self.enabled_documents(refresh=refresh)
1869
- for doc in enabled_docs:
1870
- doc.title
1871
- if format == "pdf":
1872
- doc.as_pdf(
1873
- key=key,
1874
- refresh=refresh,
1875
- pdfa=pdfa,
1876
- append_matching_suffix=append_matching_suffix,
1877
- ) # Generate cached file for this session
1975
+ if not hasattr(self, "_cached_full_pdf_label"):
1976
+ self._cached_full_pdf_label = str(self.full_pdf_label)
1977
+
1978
+ if use_previously_cached_files and hasattr(self, "_downloadable_files"):
1979
+ downloadable_files, bundled_zip, bundled_pdf = self._downloadable_files
1980
+ else:
1981
+ downloadable_files, bundled_zip, bundled_pdf = self.get_cacheable_documents(
1982
+ key=key,
1983
+ pdf=(format == "pdf" or view == True),
1984
+ docx=format == "docx",
1985
+ original=format == "original",
1986
+ refresh=refresh,
1987
+ pdfa=pdfa,
1988
+ include_zip=include_zip,
1989
+ include_full_pdf=include_full_pdf,
1990
+ append_matching_suffix=append_matching_suffix,
1991
+ )
1878
1992
 
1879
1993
  html = f'<div class="container al_table al_doc_table" id="{ html_safe_str(self.instanceName) }">'
1880
1994
 
1881
- for doc in enabled_docs:
1882
- filename_root = os.path.splitext(str(doc.filename))[0]
1883
- # Do our best to use the provided filename + the extension from requested filetype
1884
- if format == "original":
1885
- download_doc = doc[key]
1886
- download_filename = doc.filename
1887
- if format == "docx" and doc._is_docx(key=key):
1888
- download_doc = doc.as_docx(
1889
- key=key, append_matching_suffix=append_matching_suffix
1890
- )
1891
- download_filename = filename_root + ".docx"
1892
- else:
1893
- download_doc = doc.as_pdf(
1894
- key=key, append_matching_suffix=append_matching_suffix
1895
- )
1896
- download_filename = filename_root + ".pdf"
1995
+ for result in downloadable_files:
1996
+ title = result["title"]
1997
+ download_filename = result.get("download_filename", "document")
1897
1998
 
1898
- try:
1899
- # If it's possible, set the file extension to the actual filetype
1900
- # This is mostly necessary if people omit the file extension in attachment block
1901
- # for filetype="original"
1902
- ext = next(
1903
- iter(
1904
- mimetypes.guess_all_extensions(
1905
- download_doc.mimetype, strict=True
1906
- )
1907
- )
1908
- )
1909
- download_filename = filename_root + ext
1910
- except:
1911
- pass
1999
+ if format == "original" and "original" in result:
2000
+ download_doc = result["original"]
2001
+ elif format == "docx" and "docx" in result:
2002
+ download_doc = result["docx"]
2003
+ elif "pdf" in result:
2004
+ download_doc = result["pdf"]
2005
+ else:
2006
+ continue # Skip if the desired format is not available
1912
2007
 
2008
+ # Construct the download button
1913
2009
  doc_download_button = action_button_html(
1914
2010
  download_doc.url_for(
1915
2011
  attachment=True, display_filename=download_filename
@@ -1920,12 +2016,14 @@ class ALDocumentBundle(DAList):
1920
2016
  size="md",
1921
2017
  classname="al_download al_button",
1922
2018
  )
1923
- if view and doc.as_pdf().url_for().endswith(".pdf"):
2019
+
2020
+ # Construct the view button if needed
2021
+ if view and "pdf" in result and result["pdf"].url_for().endswith(".pdf"):
2022
+ # Use .pdf as the filename extension
2023
+ view_filename = os.path.splitext(download_filename)[0] + ".pdf"
1924
2024
  doc_view_button = action_button_html(
1925
- doc.as_pdf(key=key).url_for(
1926
- attachment=False,
1927
- display_filename=filename_root + ".pdf",
1928
- append_matching_suffix=append_matching_suffix,
2025
+ result["pdf"].url_for(
2026
+ attachment=False, display_filename=view_filename
1929
2027
  ),
1930
2028
  label=view_label,
1931
2029
  icon=view_icon,
@@ -1936,31 +2034,47 @@ class ALDocumentBundle(DAList):
1936
2034
  buttons = [doc_view_button, doc_download_button]
1937
2035
  else:
1938
2036
  buttons = [doc_download_button]
1939
- html += table_row(doc.title, buttons)
1940
2037
 
1941
- # Add a zip file row if there's more than one doc
1942
- filename_root = os.path.splitext(str(self.filename))[0]
1943
- if len(enabled_docs) > 1 and include_zip:
2038
+ html += table_row(title, buttons)
2039
+
2040
+ # Add a zip file row if included
2041
+ if include_zip and bundled_zip:
1944
2042
  if not zip_label:
1945
2043
  zip_label = self._cached_zip_label
1946
- # Zip file will match the format of the download table
1947
- zip = self.as_zip(key=key, format=format, include_pdf=view)
2044
+ filename_root = os.path.splitext(str(self.filename))[0]
1948
2045
  zip_button = action_button_html(
1949
- zip.url_for(attachment=False, display_filename=filename_root + ".zip"),
2046
+ bundled_zip.url_for(
2047
+ attachment=False, display_filename=filename_root + ".zip"
2048
+ ),
1950
2049
  label=zip_label,
1951
2050
  icon=zip_icon,
1952
2051
  color="primary",
1953
2052
  size="md",
1954
2053
  classname="al_zip al_button",
1955
2054
  )
1956
- html += table_row(zip.title, zip_button)
2055
+ html += table_row(zip_label, zip_button)
2056
+
2057
+ if include_full_pdf and bundled_pdf:
2058
+ if not full_pdf_label:
2059
+ full_pdf_label = self._cached_full_pdf_label
2060
+ filename_root = os.path.splitext(str(self.filename))[0]
2061
+ full_pdf_button = action_button_html(
2062
+ bundled_pdf.url_for(
2063
+ attachment=False, display_filename=filename_root + ".pdf"
2064
+ ),
2065
+ label=full_pdf_label,
2066
+ icon="file-pdf",
2067
+ color="primary",
2068
+ size="md",
2069
+ classname="al_full_pdf al_button",
2070
+ )
2071
+ html += table_row(full_pdf_label, full_pdf_button)
1957
2072
 
1958
2073
  if include_email:
1959
2074
  html += self.send_email_table_row(key=key)
1960
2075
 
1961
2076
  html += "\n</div>"
1962
2077
 
1963
- # Discuss: Do we want a table with the ability to have a merged pdf row?
1964
2078
  return html
1965
2079
 
1966
2080
  def download_html(