diff --git a/docassemble/AssemblyLine/al_document.py b/docassemble/AssemblyLine/al_document.py index 6cf647a8..5705efd8 100644 --- a/docassemble/AssemblyLine/al_document.py +++ b/docassemble/AssemblyLine/al_document.py @@ -2877,6 +2877,7 @@ class ALExhibitList(DAList): Attributes: maximum_size (int): The maximum allowed size in bytes of the entire document. + maximum_size_per_doc (int): The maximum allowed size in bytes per document in the list auto_label (bool): If True, automatically numbers exhibits for cover page and table of contents. Defaults to True. auto_labeler (Callable): An optional function or lambda to transform the exhibit's index to a label. Uses A..Z labels by default. @@ -3075,6 +3076,7 @@ class ALExhibitDocument(ALDocument): auto_ocr: bool bates_prefix: str maximum_size: int + maximum_size_per_doc: int suffix_to_append: str exhibits: ALExhibitList table_of_contents: DAFile @@ -3099,8 +3101,13 @@ def init(self, *pargs, **kwargs) -> None: else: self.include_exhibit_cover_pages = True self.exhibits.include_exhibit_cover_pages = True + if hasattr(self, "maximum_size_per_doc"): + self.exhibits.maximum_size_per_doc = self.maximum_size_per_doc if hasattr(self, "maximum_size"): self.exhibits.maximum_size = self.maximum_size + if not hasattr(self, "maximum_size_per_doc"): + self.maximum_size_per_doc = self.maximum_size + self.exhibits.maximum_size_per_doc = self.maximum_size if hasattr(self, "include_table_of_contents"): self.exhibits.include_table_of_contents = self.include_table_of_contents else: diff --git a/docassemble/AssemblyLine/data/questions/ql_baseline.yml b/docassemble/AssemblyLine/data/questions/ql_baseline.yml index 2d486d4f..5ec9fb10 100644 --- a/docassemble/AssemblyLine/data/questions/ql_baseline.yml +++ b/docassemble/AssemblyLine/data/questions/ql_baseline.yml @@ -1882,6 +1882,9 @@ validation code: | if hasattr(x, 'maximum_size'): if full_size > x.maximum_size: validation_error(f"Upload a file smaller than {humanize.naturalsize(x.maximum_size)}") + if hasattr(x, 'maximum_size_per_doc'): + if full_size > x.maximum_size_per_doc: + validation_error(f"Upload a file smaller than {humanize.naturalsize(x.maximum_size)}") try: pdf_concatenate(x[0].pages) except: @@ -1910,6 +1913,9 @@ fields: "image/png, image/jpeg, .doc,.docx,application/msword,application/vnd.openxmlformats-officedocument.wordprocessingml.document,application/pdf,.pdf" validation code: | this_doc_size = sum(a_page.size_in_bytes() for a_page in x[i].pages) + if hasattr(x, 'maximum_size_per_doc'): + if this_doc_size > x.maximum_size_per_doc: + validation_error(f"This document should be smaller than {humanize.naturalsize(x.maximum_size_per_doc)}") if this_doc_size > (15 * 1024 * 1024): validation_error("Upload a file smaller than 15 MB.") if hasattr(x, 'maximum_size'): @@ -1930,9 +1936,19 @@ question: | subquestion: | You have uploaded ${ x[i].pages.num_pages() } pages so far. + <% current_doc_size = sum(ap.size_in_bytes() for ap in x[i].pages.complete_elements()) %> + % if hasattr(x, 'maximum_size_per_doc'): + This document must be smaller than ${ humanize.naturalsize(x.maximum_size_per_doc) }. + % 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: + You can upload ${ humanize.naturalsize(x.maximum_size_per_doc - current_doc_size) } more. + % else: + You can upload ${ humanize.naturalsize(x.maximum_size - x.size_in_bytes() - current_doc_size) } more. + % endif + % endif + % if hasattr(x, 'maximum_size'): The total size of all exhibits must be less than ${ humanize.naturalsize(x.maximum_size) }. - 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. + You can upload ${ humanize.naturalsize(x.maximum_size - x.size_in_bytes() - current_doc_size) } more. % endif ${ collapse_template(x[i].in_progress_template )} @@ -1968,11 +1984,16 @@ fields: "image/png, image/jpeg, .doc,.docx,application/msword,application/vnd.openxmlformats-officedocument.wordprocessingml.document,application/pdf,.pdf" validation code: | page_size = x[i].pages[j].size_in_bytes() + this_doc_size = sum(a_page.size_in_bytes() for a_page in x[i].pages.complete_elements()) + page_size + log(f"length of completed elements: {len(x[i].pages.complete_elements())}") + if hasattr(x, 'maximum_size_per_doc'): + if this_doc_size > x.maximum_size_per_doc: + suggested_size = x.maximum_size_per_doc - (this_doc_size - page_size) + 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)}.") + if page_size > (15 * 1024 * 1024): validation_error("Upload a file smaller than 15 MB.") if hasattr(x, 'maximum_size'): - # this_doc_size already includes `page_size` - this_doc_size = sum(a_page.size_in_bytes() for a_page in x[i].pages.complete_elements()) full_size = x.size_in_bytes() + this_doc_size if full_size > x.maximum_size: suggested_size = x.maximum_size - (full_size - page_size) diff --git a/docassemble/AssemblyLine/data/questions/test_alexhibit_maxsize.yml b/docassemble/AssemblyLine/data/questions/test_alexhibit_maxsize.yml index 5c2b5e59..e3861156 100644 --- a/docassemble/AssemblyLine/data/questions/test_alexhibit_maxsize.yml +++ b/docassemble/AssemblyLine/data/questions/test_alexhibit_maxsize.yml @@ -10,7 +10,7 @@ objects: - exhibits_bundle_defaults_1: ALDocumentBundle.using(elements=[exhibit_doc_defaults_1], filename="exhibits_bundle_defaults", title="Exhibits with defaults") --- objects: - - exhibit_doc_defaults_1: ALExhibitDocument.using(title="Exhibits doc defaults", filename="exhibits_doc_defaults", maximum_size=1*1024*1024 ) + - 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) --- id: gather_main event: gather_main diff --git a/pyproject.toml b/pyproject.toml index 2c555218..978a1edc 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -36,6 +36,9 @@ extend-exclude = '(__init__.py|setup.py)' check-property-returns = false check-overridden = false check-class = true +disable = [ + "SIG305" +] [tool.mypy] # global options