Skip to content

Commit

Permalink
Added a max size feature to the ExhibitDocument (#604)
Browse files Browse the repository at this point in the history
* Added a max size feature to the ExhibitDocument

Also give suggested remaining upload size in human readable file sizes in
errors and in between upload screens.
  • Loading branch information
BryceStevenWilley authored Nov 3, 2022
1 parent 364fa1f commit 57df4ab
Show file tree
Hide file tree
Showing 3 changed files with 84 additions and 17 deletions.
13 changes: 13 additions & 0 deletions docassemble/AssemblyLine/al_document.py
Original file line number Diff line number Diff line change
Expand Up @@ -1598,6 +1598,7 @@ def __str__(self):
class ALExhibitList(DAList):
"""
Attributes:
maximum_size (int): the maximum size in bytes that the whole document is allowed to be
auto_label (bool): Set to True if you want exhibits to be automatically numbered for purposes of cover page
and table of contents. Defaults to True.
auto_labeler (Callable): (optional) a function or lambda to transform the index for each exhibit to a label.
Expand Down Expand Up @@ -1642,6 +1643,9 @@ def as_pdf(
Returns:
A DAfile containing the rendered exhibit list as a single file.
"""
if self.include_exhibit_cover_pages:
for exhibit in self:
exhibit.cover_page
if self.include_table_of_contents and toc_pages != 1:
self._update_page_numbers(toc_guess_pages=toc_pages)
return pdf_concatenate(
Expand All @@ -1657,6 +1661,13 @@ def as_pdf(
pdfa=pdfa,
)

def size_in_bytes(self):
"""Gets the total size in bytes of each of the exhibit documents."""
full_size = 0
for exhibit in self.complete_elements():
full_size += sum((a_page.size_in_bytes() for a_page in exhibit.pages))
return full_size

def _update_labels(self, auto_labeler: Callable = None) -> None:
"""
Private method to refresh labels on all exhibits.
Expand Down Expand Up @@ -1763,6 +1774,8 @@ def init(self, *pargs, **kwargs):
else:
self.include_exhibit_cover_pages = True
self.exhibits.include_exhibit_cover_pages = True
if hasattr(self, "maximum_size"):
self.exhibits.maximum_size = self.maximum_size
if hasattr(self, "include_table_of_contents"):
self.exhibits.include_table_of_contents = self.include_table_of_contents
else:
Expand Down
65 changes: 48 additions & 17 deletions docassemble/AssemblyLine/data/questions/ql_baseline.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ objects:
- attorneys: ALPeopleList
- translators: ALPeopleList
- debt_collectors: ALPeopleList
- creditors: ALPeopleList
- creditors: ALPeopleList
- spouses: ALPeopleList
- parents: ALPeopleList
- decedents: ALPeopleList.using(ask_number=True, target_number=1)
Expand All @@ -41,8 +41,8 @@ subquestion: |
% endif
Step 1. Answer questions that will fill in your form for you.
Step 2. Preview the completed form.
% if form_approved_for_email_filing:
Step 2. Preview the completed form.
% if form_approved_for_email_filing:
Step 3. Email the form to the court using this secure website and save copies
for yourself for later reference.
% elif al_form_type in ['starts_case','existing_case','appeal']:
Expand Down Expand Up @@ -1555,6 +1555,9 @@ code: |
#########################################################
# ALExhibitDocument questions
---
imports:
- humanize
---
generic object: ALExhibitDocument
code: |
x.enabled = x.exhibits.has_exhibits
Expand All @@ -1576,22 +1579,26 @@ fields:
show if: x.has_exhibits
- First document title: x[0].title
maxlength: 60 # longer might break TOC
show if: x.has_exhibits
show if: x.has_exhibits
- Upload the first document: x[0].pages
show if: x.has_exhibits
show if: x.has_exhibits
datatype: files
maximum image size: 1024
image upload type: jpeg
image upload type: jpeg
accept: |
"image/png, image/jpeg, .doc,.docx,application/msword,application/vnd.openxmlformats-officedocument.wordprocessingml.document,application/pdf,.pdf"
validation code: |
if x.has_exhibits:
if sum(exhibit.size_in_bytes() for exhibit in x[0].pages) > (15 * 1024 * 1024):
full_size = sum(a_page.size_in_bytes() for a_page in x[0].pages)
if full_size > (15 * 1024 * 1024):
validation_error("Upload a file smaller than 15 MB.")
if hasattr(x, 'maximum_size'):
if full_size > x.maximum_size:
validation_error(f"Upload a file smaller than {humanize.naturalsize(x.maximum_size)}")
try:
pdf_concatenate(x[0].pages)
except:
validation_error("Unable to convert this file. Please upload a new one.", field="x[0].pages")
validation_error("Unable to convert this file. Please upload a new one.")
x[0].pages.reset_gathered() # docassemble sets this attribute but we want to force gathering additional pages
---
generic object: ALExhibitList
Expand All @@ -1603,31 +1610,42 @@ id: exhibit i
question: |
Upload the ${ ordinal(i) } document
subquestion: |
You will have a chance to upload additional pages for this document later.
You will have a chance to upload additional pages for this document later.
fields:
- Document title: x[i].title
maxlength: 60 # longer might break TOC
- Upload the first exhibit: x[i].pages
- Upload the exhibit: x[i].pages
datatype: files
maximum image size: 1024
image upload type: jpeg
image upload type: jpeg
accept: |
"image/png, image/jpeg, .doc,.docx,application/msword,application/vnd.openxmlformats-officedocument.wordprocessingml.document,application/pdf,.pdf"
validation code: |
if sum(exhibit.size_in_bytes() for exhibit in x[i].pages) > (15 * 1024 * 1024):
this_doc_size = sum(a_page.size_in_bytes() for a_page in x[i].pages)
if this_doc_size > (15 * 1024 * 1024):
validation_error("Upload a file smaller than 15 MB.")
if hasattr(x, 'maximum_size'):
full_size = x.size_in_bytes()
if full_size > x.maximum_size:
suggested_size = x.maximum_size - (full_size - this_doc_size)
validation_error(f"All exhibits combined must be smaller than {humanize.naturalsize(x.maximum_size)}. Upload a file smaller than {humanize.naturalsize(suggested_size)}.")
try:
pdf_concatenate(x[i].pages)
except:
validation_error("Unable to convert this file. Please upload a new one.", field="x[i].pages")
validation_error("Unable to convert this file. Please upload a new one.")
x[i].pages.reset_gathered() # docassemble sets this attribute but we want to force gathering additional pages
---
generic object: ALExhibitList
id: exhibit i has additional pages
question: |
Does "**${ x[i] }**" have any additional pages?
subquestion: |
You have uploaded ${ x[i].pages.num_pages() } pages so far.
You have uploaded ${ x[i].pages.num_pages() } pages so far.
% 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.
% endif
${ collapse_template(x[i].in_progress_template )}
Expand All @@ -1653,16 +1671,24 @@ fields:
- Upload a PDF, Word, or image file: x[i].pages[j]
datatype: file
maximum image size: 1024
image upload type: jpeg
image upload type: jpeg
accept: |
"image/png, image/jpeg, .doc,.docx,application/msword,application/vnd.openxmlformats-officedocument.wordprocessingml.document,application/pdf,.pdf"
validation code: |
if x[i].pages[j].size_in_bytes() > (15 * 1024 * 1024):
page_size = x[i].pages[j].size_in_bytes()
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)
validation_error(f"All exhibits combined must be smaller than {humanize.naturalsize(x.maximum_size)}. Upload a file smaller than {humanize.naturalsize(suggested_size)}.")
try:
pdf_concatenate(x[i].pages[j])
except:
validation_error("Unable to convert this file. Please upload a new one.", field="x[i].pages[j]")
validation_error("Unable to convert this file. Please upload a new one.")
x[i].pages[j] = unpack_dafilelist(x[i].pages[j])
---
Expand All @@ -1672,6 +1698,11 @@ question: |
You have ${ x.number_gathered() } document(s) so far. Do you have another document
you want to upload?
subquestion: |
% 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())} more.
% endif
${ collapse_template(x.in_progress_exhibits) }
field: x.there_is_another
buttons:
Expand Down
23 changes: 23 additions & 0 deletions docassemble/AssemblyLine/data/questions/test_alexhibit_maxsize.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
---
include:
- al_package.yml
---
mandatory: True
code: |
gather_main
---
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 )
---
id: gather_main
event: gather_main
question: Default ALDocumentBundle thumbnail method args
subquestion: |
exhibits_bundle_defaults_1.as_pdf()
${ exhibits_bundle_defaults_1.as_pdf() }
${ exhibits_bundle_defaults_1.as_pdf().size_in_bytes() }

0 comments on commit 57df4ab

Please sign in to comment.