docassemble.AssemblyLine 3.1.0__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.
- {docassemble_assemblyline-3.1.0/docassemble.AssemblyLine.egg-info → docassemble_assemblyline-3.2.0}/PKG-INFO +1 -1
- docassemble_assemblyline-3.2.0/docassemble/AssemblyLine/__init__.py +1 -0
- {docassemble_assemblyline-3.1.0 → docassemble_assemblyline-3.2.0}/docassemble/AssemblyLine/al_document.py +169 -55
- {docassemble_assemblyline-3.1.0 → docassemble_assemblyline-3.2.0}/docassemble/AssemblyLine/data/questions/al_document.yml +77 -1
- {docassemble_assemblyline-3.1.0 → docassemble_assemblyline-3.2.0}/docassemble/AssemblyLine/data/questions/al_visual.yml +21 -4
- {docassemble_assemblyline-3.1.0 → docassemble_assemblyline-3.2.0}/docassemble/AssemblyLine/data/questions/demo_search_sessions.yml +12 -1
- {docassemble_assemblyline-3.1.0 → docassemble_assemblyline-3.2.0}/docassemble/AssemblyLine/data/questions/interview_list.yml +39 -3
- docassemble_assemblyline-3.2.0/docassemble/AssemblyLine/data/questions/test_aldocument_background_assembly.yml +65 -0
- docassemble_assemblyline-3.2.0/docassemble/AssemblyLine/data/sources/translation_es_broken.xlsx +0 -0
- {docassemble_assemblyline-3.1.0 → docassemble_assemblyline-3.2.0}/docassemble/AssemblyLine/requirements.txt +2 -1
- {docassemble_assemblyline-3.1.0 → docassemble_assemblyline-3.2.0}/docassemble/AssemblyLine/sessions.py +184 -21
- {docassemble_assemblyline-3.1.0 → docassemble_assemblyline-3.2.0/docassemble.AssemblyLine.egg-info}/PKG-INFO +1 -1
- {docassemble_assemblyline-3.1.0 → docassemble_assemblyline-3.2.0}/docassemble.AssemblyLine.egg-info/SOURCES.txt +2 -0
- {docassemble_assemblyline-3.1.0 → docassemble_assemblyline-3.2.0}/setup.py +1 -1
- docassemble_assemblyline-3.1.0/docassemble/AssemblyLine/__init__.py +0 -1
- {docassemble_assemblyline-3.1.0 → docassemble_assemblyline-3.2.0}/LICENSE +0 -0
- {docassemble_assemblyline-3.1.0 → docassemble_assemblyline-3.2.0}/MANIFEST.in +0 -0
- {docassemble_assemblyline-3.1.0 → docassemble_assemblyline-3.2.0}/README.md +0 -0
- {docassemble_assemblyline-3.1.0 → docassemble_assemblyline-3.2.0}/docassemble/AssemblyLine/al_courts.py +0 -0
- {docassemble_assemblyline-3.1.0 → docassemble_assemblyline-3.2.0}/docassemble/AssemblyLine/al_general.py +0 -0
- {docassemble_assemblyline-3.1.0 → docassemble_assemblyline-3.2.0}/docassemble/AssemblyLine/data/questions/al_code.yml +0 -0
- {docassemble_assemblyline-3.1.0 → docassemble_assemblyline-3.2.0}/docassemble/AssemblyLine/data/questions/al_language.yml +0 -0
- {docassemble_assemblyline-3.1.0 → docassemble_assemblyline-3.2.0}/docassemble/AssemblyLine/data/questions/al_package.yml +0 -0
- {docassemble_assemblyline-3.1.0 → docassemble_assemblyline-3.2.0}/docassemble/AssemblyLine/data/questions/al_package_unstyled.yml +0 -0
- {docassemble_assemblyline-3.1.0 → docassemble_assemblyline-3.2.0}/docassemble/AssemblyLine/data/questions/al_question_test.yml +0 -0
- {docassemble_assemblyline-3.1.0 → docassemble_assemblyline-3.2.0}/docassemble/AssemblyLine/data/questions/al_reminders.yml +0 -0
- {docassemble_assemblyline-3.1.0 → docassemble_assemblyline-3.2.0}/docassemble/AssemblyLine/data/questions/al_saved_sessions.yml +0 -0
- {docassemble_assemblyline-3.1.0 → docassemble_assemblyline-3.2.0}/docassemble/AssemblyLine/data/questions/al_saved_sessions_store.yml +0 -0
- {docassemble_assemblyline-3.1.0 → docassemble_assemblyline-3.2.0}/docassemble/AssemblyLine/data/questions/al_settings.yml +0 -0
- {docassemble_assemblyline-3.1.0 → docassemble_assemblyline-3.2.0}/docassemble/AssemblyLine/data/questions/al_terms_of_use.yml +0 -0
- {docassemble_assemblyline-3.1.0 → docassemble_assemblyline-3.2.0}/docassemble/AssemblyLine/data/questions/assembly_line.yml +0 -0
- {docassemble_assemblyline-3.1.0 → docassemble_assemblyline-3.2.0}/docassemble/AssemblyLine/data/questions/assembly_line_unstyled.yml +0 -0
- {docassemble_assemblyline-3.1.0 → docassemble_assemblyline-3.2.0}/docassemble/AssemblyLine/data/questions/feedback.yml +0 -0
- {docassemble_assemblyline-3.1.0 → docassemble_assemblyline-3.2.0}/docassemble/AssemblyLine/data/questions/ql_baseline.yml +0 -0
- {docassemble_assemblyline-3.1.0 → docassemble_assemblyline-3.2.0}/docassemble/AssemblyLine/data/questions/ql_catchall.yml +0 -0
- {docassemble_assemblyline-3.1.0 → docassemble_assemblyline-3.2.0}/docassemble/AssemblyLine/data/questions/reserved_words.yml +0 -0
- {docassemble_assemblyline-3.1.0 → docassemble_assemblyline-3.2.0}/docassemble/AssemblyLine/data/questions/test_al_table_document.yml +0 -0
- {docassemble_assemblyline-3.1.0 → docassemble_assemblyline-3.2.0}/docassemble/AssemblyLine/data/questions/test_aladdendum.yml +0 -0
- {docassemble_assemblyline-3.1.0 → docassemble_assemblyline-3.2.0}/docassemble/AssemblyLine/data/questions/test_alcourts.yml +0 -0
- {docassemble_assemblyline-3.1.0 → docassemble_assemblyline-3.2.0}/docassemble/AssemblyLine/data/questions/test_aldocument.yml +0 -0
- {docassemble_assemblyline-3.1.0 → docassemble_assemblyline-3.2.0}/docassemble/AssemblyLine/data/questions/test_alexhibit.yml +0 -0
- {docassemble_assemblyline-3.1.0 → docassemble_assemblyline-3.2.0}/docassemble/AssemblyLine/data/questions/test_alexhibit_maxsize.yml +0 -0
- {docassemble_assemblyline-3.1.0 → docassemble_assemblyline-3.2.0}/docassemble/AssemblyLine/data/questions/test_bundle_parity.yml +0 -0
- {docassemble_assemblyline-3.1.0 → docassemble_assemblyline-3.2.0}/docassemble/AssemblyLine/data/questions/test_familiar_disambiguation.yml +0 -0
- {docassemble_assemblyline-3.1.0 → docassemble_assemblyline-3.2.0}/docassemble/AssemblyLine/data/questions/test_question_library.yml +0 -0
- {docassemble_assemblyline-3.1.0 → docassemble_assemblyline-3.2.0}/docassemble/AssemblyLine/data/sources/README.md +0 -0
- {docassemble_assemblyline-3.1.0 → docassemble_assemblyline-3.2.0}/docassemble/AssemblyLine/data/sources/es-words.yml +0 -0
- {docassemble_assemblyline-3.1.0 → docassemble_assemblyline-3.2.0}/docassemble/AssemblyLine/data/sources/languages.yml +0 -0
- {docassemble_assemblyline-3.1.0 → docassemble_assemblyline-3.2.0}/docassemble/AssemblyLine/data/sources/test_aldocument.feature +0 -0
- {docassemble_assemblyline-3.1.0 → docassemble_assemblyline-3.2.0}/docassemble/AssemblyLine/data/sources/test_alexhibit_docx_1.docx +0 -0
- {docassemble_assemblyline-3.1.0 → docassemble_assemblyline-3.2.0}/docassemble/AssemblyLine/data/sources/test_alexhibit_jpg_1.jpg +0 -0
- {docassemble_assemblyline-3.1.0 → docassemble_assemblyline-3.2.0}/docassemble/AssemblyLine/data/sources/test_alexhibit_pdf_1.pdf +0 -0
- {docassemble_assemblyline-3.1.0 → docassemble_assemblyline-3.2.0}/docassemble/AssemblyLine/data/sources/test_alexhibit_png_1.png +0 -0
- {docassemble_assemblyline-3.1.0 → docassemble_assemblyline-3.2.0}/docassemble/AssemblyLine/data/sources/test_question_library.feature +0 -0
- {docassemble_assemblyline-3.1.0 → docassemble_assemblyline-3.2.0}/docassemble/AssemblyLine/data/sources/translation_es.xlsx +0 -0
- {docassemble_assemblyline-3.1.0 → docassemble_assemblyline-3.2.0}/docassemble/AssemblyLine/data/sources/translation_ht.xlsx +0 -0
- {docassemble_assemblyline-3.1.0 → docassemble_assemblyline-3.2.0}/docassemble/AssemblyLine/data/sources/translation_pt.xlsx +0 -0
- {docassemble_assemblyline-3.1.0 → docassemble_assemblyline-3.2.0}/docassemble/AssemblyLine/data/static/README.md +0 -0
- {docassemble_assemblyline-3.1.0 → docassemble_assemblyline-3.2.0}/docassemble/AssemblyLine/data/static/al_audio.css +0 -0
- {docassemble_assemblyline-3.1.0 → docassemble_assemblyline-3.2.0}/docassemble/AssemblyLine/data/static/al_audio.js +0 -0
- {docassemble_assemblyline-3.1.0 → docassemble_assemblyline-3.2.0}/docassemble/AssemblyLine/data/static/aldocument.css +0 -0
- {docassemble_assemblyline-3.1.0 → docassemble_assemblyline-3.2.0}/docassemble/AssemblyLine/data/static/aldocument.js +0 -0
- {docassemble_assemblyline-3.1.0 → docassemble_assemblyline-3.2.0}/docassemble/AssemblyLine/data/static/interview_list.css +0 -0
- {docassemble_assemblyline-3.1.0 → docassemble_assemblyline-3.2.0}/docassemble/AssemblyLine/data/static/limit_upload_size.js +0 -0
- {docassemble_assemblyline-3.1.0 → docassemble_assemblyline-3.2.0}/docassemble/AssemblyLine/data/static/lt1-pullout-10-getting-organized.pdf +0 -0
- {docassemble_assemblyline-3.1.0 → docassemble_assemblyline-3.2.0}/docassemble/AssemblyLine/data/static/ma_logo.png +0 -0
- {docassemble_assemblyline-3.1.0 → docassemble_assemblyline-3.2.0}/docassemble/AssemblyLine/data/static/placeholder.png +0 -0
- {docassemble_assemblyline-3.1.0 → docassemble_assemblyline-3.2.0}/docassemble/AssemblyLine/data/static/seal.jpg +0 -0
- {docassemble_assemblyline-3.1.0 → docassemble_assemblyline-3.2.0}/docassemble/AssemblyLine/data/static/styles.css +0 -0
- {docassemble_assemblyline-3.1.0 → docassemble_assemblyline-3.2.0}/docassemble/AssemblyLine/data/templates/README.md +0 -0
- {docassemble_assemblyline-3.1.0 → docassemble_assemblyline-3.2.0}/docassemble/AssemblyLine/data/templates/al_basic_addendum.docx +0 -0
- {docassemble_assemblyline-3.1.0 → docassemble_assemblyline-3.2.0}/docassemble/AssemblyLine/data/templates/exhibit_cover_sheet.docx +0 -0
- {docassemble_assemblyline-3.1.0 → docassemble_assemblyline-3.2.0}/docassemble/AssemblyLine/data/templates/exhibit_table_of_contents.docx +0 -0
- {docassemble_assemblyline-3.1.0 → docassemble_assemblyline-3.2.0}/docassemble/AssemblyLine/data/templates/general_cover_sheet.docx +0 -0
- {docassemble_assemblyline-3.1.0 → docassemble_assemblyline-3.2.0}/docassemble/AssemblyLine/data/templates/sample_word_template.docx +0 -0
- {docassemble_assemblyline-3.1.0 → docassemble_assemblyline-3.2.0}/docassemble/AssemblyLine/data/templates/test_aldocument_docx_1.docx +0 -0
- {docassemble_assemblyline-3.1.0 → docassemble_assemblyline-3.2.0}/docassemble/AssemblyLine/data/templates/test_aldocument_pdf_1.pdf +0 -0
- {docassemble_assemblyline-3.1.0 → docassemble_assemblyline-3.2.0}/docassemble/AssemblyLine/language.py +0 -0
- {docassemble_assemblyline-3.1.0 → docassemble_assemblyline-3.2.0}/docassemble/AssemblyLine/project_maintenance.py +0 -0
- {docassemble_assemblyline-3.1.0 → docassemble_assemblyline-3.2.0}/docassemble/AssemblyLine/py.typed +0 -0
- {docassemble_assemblyline-3.1.0 → docassemble_assemblyline-3.2.0}/docassemble/AssemblyLine/test_al_document.py +0 -0
- {docassemble_assemblyline-3.1.0 → docassemble_assemblyline-3.2.0}/docassemble/AssemblyLine/test_al_general.py +0 -0
- {docassemble_assemblyline-3.1.0 → docassemble_assemblyline-3.2.0}/docassemble/AssemblyLine/test_language.py +0 -0
- {docassemble_assemblyline-3.1.0 → docassemble_assemblyline-3.2.0}/docassemble/__init__.py +0 -0
- {docassemble_assemblyline-3.1.0 → docassemble_assemblyline-3.2.0}/docassemble.AssemblyLine.egg-info/dependency_links.txt +0 -0
- {docassemble_assemblyline-3.1.0 → docassemble_assemblyline-3.2.0}/docassemble.AssemblyLine.egg-info/namespace_packages.txt +0 -0
- {docassemble_assemblyline-3.1.0 → docassemble_assemblyline-3.2.0}/docassemble.AssemblyLine.egg-info/not-zip-safe +0 -0
- {docassemble_assemblyline-3.1.0 → docassemble_assemblyline-3.2.0}/docassemble.AssemblyLine.egg-info/requires.txt +0 -0
- {docassemble_assemblyline-3.1.0 → docassemble_assemblyline-3.2.0}/docassemble.AssemblyLine.egg-info/top_level.txt +0 -0
- {docassemble_assemblyline-3.1.0 → docassemble_assemblyline-3.2.0}/pyproject.toml +0 -0
- {docassemble_assemblyline-3.1.0 → docassemble_assemblyline-3.2.0}/setup.cfg +0 -0
|
@@ -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
|
-
|
|
1868
|
-
|
|
1869
|
-
|
|
1870
|
-
|
|
1871
|
-
|
|
1872
|
-
|
|
1873
|
-
|
|
1874
|
-
|
|
1875
|
-
|
|
1876
|
-
|
|
1877
|
-
|
|
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
|
|
1882
|
-
|
|
1883
|
-
|
|
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
|
-
|
|
1899
|
-
|
|
1900
|
-
|
|
1901
|
-
|
|
1902
|
-
|
|
1903
|
-
|
|
1904
|
-
|
|
1905
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
1942
|
-
|
|
1943
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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(
|
|
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(
|
|
@@ -88,9 +88,85 @@ template: x.zip_label
|
|
|
88
88
|
content: |
|
|
89
89
|
Download all
|
|
90
90
|
---
|
|
91
|
+
generic object: ALDocumentBundle
|
|
92
|
+
template: x.full_pdf_label
|
|
93
|
+
content: |
|
|
94
|
+
Download as one PDF
|
|
95
|
+
---
|
|
91
96
|
id: al exhibit ocr pages bg
|
|
92
97
|
event: al_exhibit_ocr_pages
|
|
93
98
|
code: |
|
|
94
99
|
to_pdf = action_argument('to_pdf')
|
|
95
100
|
from_file = action_argument('from_file')
|
|
96
|
-
background_response(ocrmypdf_task(from_file, to_pdf))
|
|
101
|
+
background_response(ocrmypdf_task(from_file, to_pdf))
|
|
102
|
+
---
|
|
103
|
+
############## Background document assembly #################
|
|
104
|
+
---
|
|
105
|
+
generic object: ALDocumentBundle
|
|
106
|
+
code: |
|
|
107
|
+
x.generate_downloads_task = background_action(x.attr_name('create_downloads'))
|
|
108
|
+
---
|
|
109
|
+
generic object: ALDocumentBundle
|
|
110
|
+
event: x.create_downloads
|
|
111
|
+
code: |
|
|
112
|
+
download_response = x.get_cacheable_documents(key="final", pdf=True, include_full_pdf=True)
|
|
113
|
+
background_response_action(x.attr_name('save_downloads'), download_response=download_response)
|
|
114
|
+
---
|
|
115
|
+
generic object: ALDocumentBundle
|
|
116
|
+
code: |
|
|
117
|
+
x.generate_downloads_with_docx_task = background_action(x.attr_name('create_downloads_with_docx'))
|
|
118
|
+
---
|
|
119
|
+
generic object: ALDocumentBundle
|
|
120
|
+
event: x.create_downloads_with_docx
|
|
121
|
+
code: |
|
|
122
|
+
download_response = x.get_cacheable_documents(key="final", pdf=True, docx=True, include_full_pdf=True)
|
|
123
|
+
background_response_action(x.attr_name('save_downloads'), download_response=download_response)
|
|
124
|
+
---
|
|
125
|
+
generic object: ALDocumentBundle
|
|
126
|
+
event: x.save_downloads
|
|
127
|
+
code: |
|
|
128
|
+
x._downloadable_files = action_argument('download_response')
|
|
129
|
+
|
|
130
|
+
background_response()
|
|
131
|
+
---
|
|
132
|
+
id: waiting screen
|
|
133
|
+
question: |
|
|
134
|
+
Please wait while we make your documents
|
|
135
|
+
subquestion: |
|
|
136
|
+
This can take a few minutes.
|
|
137
|
+
|
|
138
|
+
<div class="spinner-border text-primary d-flex justify-content-center" role="status">
|
|
139
|
+
<span class="sr-only">Making documents...</span>
|
|
140
|
+
</div>
|
|
141
|
+
event: al_download_waiting_screen
|
|
142
|
+
reload: True
|
|
143
|
+
---
|
|
144
|
+
########## Background preview assembly ################
|
|
145
|
+
---
|
|
146
|
+
generic object: ALDocumentBundle
|
|
147
|
+
code: |
|
|
148
|
+
x.generate_preview_task = background_action(x.attr_name('generate_preview_event'))
|
|
149
|
+
---
|
|
150
|
+
generic object: ALDocumentBundle
|
|
151
|
+
event: x.generate_preview_event
|
|
152
|
+
code: |
|
|
153
|
+
preview_response = x.as_pdf(key="preview")
|
|
154
|
+
background_response_action(x.attr_name('save_preview'), preview_response=preview_response)
|
|
155
|
+
---
|
|
156
|
+
generic object: ALDocumentBundle
|
|
157
|
+
event: x.save_preview
|
|
158
|
+
code: |
|
|
159
|
+
x._preview_file = action_argument('preview_response')
|
|
160
|
+
background_response()
|
|
161
|
+
---
|
|
162
|
+
id: preview waiting screen
|
|
163
|
+
question: |
|
|
164
|
+
Please wait while we generate a preview of your document
|
|
165
|
+
subquestion: |
|
|
166
|
+
This can take a few minutes.
|
|
167
|
+
|
|
168
|
+
<div class="spinner-border text-primary d-flex justify-content-center" role="status">
|
|
169
|
+
<span class="sr-only">Generating preview...</span>
|
|
170
|
+
</div>
|
|
171
|
+
event: al_preview_waiting_screen
|
|
172
|
+
reload: True
|
|
@@ -163,17 +163,34 @@ code: |
|
|
|
163
163
|
package_name = str(user_info().package)
|
|
164
164
|
---
|
|
165
165
|
code: |
|
|
166
|
+
# github_repo_name is used to direct issue feedback to the right repository
|
|
167
|
+
# Normally you will customize this in your package
|
|
166
168
|
if package_name and not "playground" in package_name:
|
|
167
169
|
github_repo_name = package_name.replace('.','-')
|
|
168
170
|
else:
|
|
169
171
|
github_repo_name = "docassemble-AssemblyLine"
|
|
170
172
|
---
|
|
171
173
|
code: |
|
|
172
|
-
#
|
|
173
|
-
#
|
|
174
|
-
|
|
174
|
+
# github_about_repo_name is used to lookup the last commit date on the default about page
|
|
175
|
+
# defaults to the same value as github_repo_name
|
|
176
|
+
github_about_repo_name = github_repo_name
|
|
177
|
+
---
|
|
178
|
+
code: |
|
|
179
|
+
# github_user is the `username` or `organization name` part of the URL
|
|
180
|
+
# on github where you want the feedback form to create issues. I.e., the owner of that repository.
|
|
181
|
+
|
|
182
|
+
# Example: if you want issues to appear on a repository at https://github.com/suffolklitlab/docassemble-AssemblyLine,
|
|
183
|
+
# then `github_user` should be `suffolklitlab`
|
|
184
|
+
|
|
185
|
+
# defaults to the "default repository owner" value in the global configuration, under the "github issues" section
|
|
186
|
+
|
|
175
187
|
github_user = get_config("github issues",{}).get("default repository owner","").strip() or "suffolklitlab"
|
|
176
188
|
---
|
|
189
|
+
code: |
|
|
190
|
+
# github_about_user is used to lookup the last commit date on the default about page
|
|
191
|
+
# defaults to the same value as github_user
|
|
192
|
+
github_about_user = github_user
|
|
193
|
+
---
|
|
177
194
|
code: |
|
|
178
195
|
feedback_form = "docassemble.AssemblyLine:feedback.yml"
|
|
179
196
|
---
|
|
@@ -347,7 +364,7 @@ code: |
|
|
|
347
364
|
github_url = "https://github.com/" + github_user + "/" + github_repo_name
|
|
348
365
|
---
|
|
349
366
|
code: |
|
|
350
|
-
res = github_modified_date(
|
|
367
|
+
res = github_modified_date(github_about_user, github_about_repo_name)
|
|
351
368
|
if res:
|
|
352
369
|
package_updated_on = res.format('yyyy-MM-dd')
|
|
353
370
|
else:
|
|
@@ -25,9 +25,20 @@ subquestion: |
|
|
|
25
25
|
Searching is not case sensitive.
|
|
26
26
|
fields:
|
|
27
27
|
- Keyword: search_keyword
|
|
28
|
+
- Limit metadata column: limit_column_name
|
|
29
|
+
required: False
|
|
30
|
+
- To value: limit_column_value
|
|
31
|
+
required: False
|
|
28
32
|
---
|
|
29
33
|
code: |
|
|
30
|
-
|
|
34
|
+
if limit_column_name:
|
|
35
|
+
matching_results = find_matching_sessions(
|
|
36
|
+
search_keyword, user_id="all", metadata_filters = {
|
|
37
|
+
limit_column_name: (limit_column_value, "ILIKE")
|
|
38
|
+
}
|
|
39
|
+
)
|
|
40
|
+
else:
|
|
41
|
+
matching_results = find_matching_sessions(search_keyword, user_id="all")
|
|
31
42
|
---
|
|
32
43
|
event: no_matches
|
|
33
44
|
question: |
|
|
@@ -132,6 +132,7 @@ code: |
|
|
|
132
132
|
sections:
|
|
133
133
|
- section_in_progress_forms: In progress forms
|
|
134
134
|
- section_answer_sets: Answer sets
|
|
135
|
+
- section_search: Search
|
|
135
136
|
progressive: False
|
|
136
137
|
---
|
|
137
138
|
# A code block is the only way to show navigation with custom labels (mako isn't allowed in `sections`)
|
|
@@ -144,7 +145,10 @@ code: |
|
|
|
144
145
|
},
|
|
145
146
|
{
|
|
146
147
|
"section_answer_sets": ANSWER_SETS_TITLE or word("Answer sets")
|
|
147
|
-
}
|
|
148
|
+
},
|
|
149
|
+
{
|
|
150
|
+
"section_search": word("Search")
|
|
151
|
+
},
|
|
148
152
|
]
|
|
149
153
|
)
|
|
150
154
|
---
|
|
@@ -261,6 +265,10 @@ subquestion: |
|
|
|
261
265
|
documents.
|
|
262
266
|
% endif
|
|
263
267
|
|
|
268
|
+
% if showifdef("limit_filename") or showifdef("search_keyword"):
|
|
269
|
+
${ session_list_html(answers = find_matching_sessions(filenames={limit_filename} if limit_filename else None, keyword=search_keyword), filename=None, limit=20, offset=session_page*20, exclude_filenames=al_sessions_to_exclude_from_interview_list, exclude_newly_started_sessions=True) }
|
|
270
|
+
|
|
271
|
+
% else:
|
|
264
272
|
${ session_list_html(filename=None, limit=20, offset=session_page*20, exclude_filenames=al_sessions_to_exclude_from_interview_list, exclude_newly_started_sessions=True) }
|
|
265
273
|
|
|
266
274
|
<nav aria-label="Page navigation">
|
|
@@ -273,8 +281,12 @@ subquestion: |
|
|
|
273
281
|
% endif
|
|
274
282
|
</ul>
|
|
275
283
|
</nav>
|
|
276
|
-
%
|
|
277
|
-
|
|
284
|
+
% endif
|
|
285
|
+
|
|
286
|
+
% endif
|
|
287
|
+
|
|
288
|
+
% if showifdef("limit_filename") or showifdef("search_keyword"):
|
|
289
|
+
${ action_button_html(url_action("delete_results_action"), label=word("Clear search results"), size="md", color="secondary", icon="times-circle", id_tag="al-clear-search-results") }
|
|
278
290
|
% endif
|
|
279
291
|
# TODO: might be able to save some DB queries here but performance is good
|
|
280
292
|
section: section_in_progress_forms
|
|
@@ -304,6 +316,25 @@ script:
|
|
|
304
316
|
});
|
|
305
317
|
</script>
|
|
306
318
|
---
|
|
319
|
+
continue button field: section_search
|
|
320
|
+
section: section_search
|
|
321
|
+
question: |
|
|
322
|
+
Search
|
|
323
|
+
% if PAGE_QUESTION:
|
|
324
|
+
${ str(PAGE_QUESTION).lower() }
|
|
325
|
+
% else:
|
|
326
|
+
in progress forms
|
|
327
|
+
% endif
|
|
328
|
+
subquestion: |
|
|
329
|
+
Use a keyword to find results that match the title or description of the session.
|
|
330
|
+
fields:
|
|
331
|
+
- Limit by form title (optional): limit_filename
|
|
332
|
+
required: False
|
|
333
|
+
code: |
|
|
334
|
+
get_combined_filename_list()
|
|
335
|
+
- Search term (optional): search_keyword
|
|
336
|
+
required: False
|
|
337
|
+
---
|
|
307
338
|
event: section_answer_sets
|
|
308
339
|
id: answer set list
|
|
309
340
|
question: |
|
|
@@ -441,3 +472,8 @@ code: |
|
|
|
441
472
|
),
|
|
442
473
|
)
|
|
443
474
|
)
|
|
475
|
+
---
|
|
476
|
+
event: delete_results_action
|
|
477
|
+
code: |
|
|
478
|
+
undefine("limit_filename")
|
|
479
|
+
undefine("search_keyword")
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
---
|
|
2
|
+
include:
|
|
3
|
+
- assembly_line.yml
|
|
4
|
+
---
|
|
5
|
+
metadata:
|
|
6
|
+
title: ALDocument Background Processing
|
|
7
|
+
---
|
|
8
|
+
mandatory: True
|
|
9
|
+
code: |
|
|
10
|
+
intro_screen
|
|
11
|
+
if not al_user_bundle.generate_preview_task.ready():
|
|
12
|
+
al_preview_waiting_screen
|
|
13
|
+
preview_screen
|
|
14
|
+
# if not al_user_bundle.generate_downloads_task.ready(): # Without DOCX
|
|
15
|
+
if not al_user_bundle.generate_downloads_with_docx_task.ready(): # With DOCX
|
|
16
|
+
al_download_waiting_screen
|
|
17
|
+
download_screen
|
|
18
|
+
---
|
|
19
|
+
continue button field: intro_screen
|
|
20
|
+
question: |
|
|
21
|
+
Intro screen
|
|
22
|
+
---
|
|
23
|
+
id: preview_screen
|
|
24
|
+
continue button field: preview_screen
|
|
25
|
+
question: |
|
|
26
|
+
Preview the documents
|
|
27
|
+
subquestion: |
|
|
28
|
+
Your documents are ready for preview.
|
|
29
|
+
|
|
30
|
+
Click the thumbnail below to view the preview of your documents. It will open in a new tab.
|
|
31
|
+
|
|
32
|
+
${ al_user_bundle._preview_file }
|
|
33
|
+
---
|
|
34
|
+
id: download
|
|
35
|
+
event: download_screen
|
|
36
|
+
question: |
|
|
37
|
+
Download the documents
|
|
38
|
+
subquestion: |
|
|
39
|
+
Your documents are ready for download.
|
|
40
|
+
|
|
41
|
+
${ al_user_bundle.download_list_html(use_previously_cached_files=True, include_full_pdf=True) }
|
|
42
|
+
---
|
|
43
|
+
objects:
|
|
44
|
+
- al_user_bundle: ALDocumentBundle.using(
|
|
45
|
+
elements = [pdf_1, docx_1],
|
|
46
|
+
title = "Background processed bundle",
|
|
47
|
+
enabled = True,
|
|
48
|
+
filename = "background_processed_bundle",
|
|
49
|
+
)
|
|
50
|
+
---
|
|
51
|
+
objects:
|
|
52
|
+
- pdf_1: ALDocument.using( title="PDF 1 with a lot of text for the title of this document", filename="pdf_doc_1", enabled=True, has_addendum=False )
|
|
53
|
+
- docx_1: ALDocument.using( title="Docx 1 also with a lot of text for the title of this document", filename="docx_doc_1", enabled=True, has_addendum=False )
|
|
54
|
+
---
|
|
55
|
+
attachment:
|
|
56
|
+
variable name: pdf_1[i]
|
|
57
|
+
pdf template file: test_aldocument_pdf_1.pdf
|
|
58
|
+
filename: pdf_1
|
|
59
|
+
fields:
|
|
60
|
+
- "sample_field": "Sample input"
|
|
61
|
+
---
|
|
62
|
+
attachment:
|
|
63
|
+
variable name: docx_1[i]
|
|
64
|
+
docx template file: test_aldocument_docx_1.docx
|
|
65
|
+
filename: docx_1
|
docassemble_assemblyline-3.2.0/docassemble/AssemblyLine/data/sources/translation_es_broken.xlsx
ADDED
|
Binary file
|