Preeeeet commited on
Commit
b2a7f1a
·
verified ·
1 Parent(s): fd21ec3

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +71 -70
app.py CHANGED
@@ -16,7 +16,13 @@ from datetime import datetime
16
  pillow_heif.register_heif_opener()
17
 
18
  # --- CONSTANTS & LAYOUT ---
19
- CONTENT_WIDTH_IN = 8.5 - (0.5 + 0.5) # 7.5" total content width
 
 
 
 
 
 
20
 
21
  JOB_MAP = {
22
  "WM 3155 SSM Parking": "T250014 Walmart 3155 Sault Ste. Marie FY26 Parking Lot Refresh\n446 Great Northern Rd.\nSault Ste. Marie, Ontario, P6B 4Z9",
@@ -159,88 +165,82 @@ def generate_report(image_items, job_details, compress_images, quality, progress
159
  footer = section.footer
160
  add_page_number(footer.paragraphs[0])
161
 
162
- # --- LAYOUT FIX: TRUE 2x2 GRID (4 PHOTOS PER PAGE) ---
163
  num_images = len(image_items)
164
  processed = 0
165
 
166
- for start in range(0, num_images, 4): # Process 4 images per page
167
  if start > 0:
168
  doc.add_page_break()
169
 
170
- page_items = image_items[start:start + 4]
171
 
172
- # Create a true 2x2 table for the grid
173
  page_table = doc.add_table(rows=2, cols=2)
174
  page_table.width = Inches(CONTENT_WIDTH_IN)
175
  set_table_fixed_layout(page_table)
176
  page_table.style = 'Table Grid'
177
  page_table.alignment = WD_TABLE_ALIGNMENT.CENTER
178
 
179
- # Define dimensions for each cell in the 2x2 grid
180
- COL_WIDTH_GRID_IN = CONTENT_WIDTH_IN / 2.0
181
- ROW_HEIGHT_GRID_IN = 4.4 # Height for each of the two rows
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
182
 
183
- # Set column widths and row heights
184
- for col in page_table.columns:
185
- col.width = Inches(COL_WIDTH_GRID_IN)
186
- for row in page_table.rows:
187
- row.height = Inches(ROW_HEIGHT_GRID_IN)
188
- row.height_rule = WD_ROW_HEIGHT_RULE.EXACTLY
 
189
 
190
- # Loop through the grid cells and populate them
191
- item_idx_on_page = 0
192
- for row_idx in range(2):
193
- for col_idx in range(2):
194
- # Check if there is an image for this cell
195
- if item_idx_on_page < len(page_items):
196
- item = page_items[item_idx_on_page]
197
- cell = page_table.cell(row_idx, col_idx)
198
- ensure_cell_has_one_empty_paragraph(cell)
199
- cell.vertical_alignment = WD_ALIGN_VERTICAL.TOP
200
-
201
- # Add description to the first paragraph
202
- p_desc = cell.paragraphs[0]
203
- p_desc.paragraph_format.space_after = Pt(6) # Add space after description
204
- run_label = p_desc.add_run("Description:\n")
205
- run_label.bold = True
206
- p_desc.add_run(item.get('description', '') or '')
207
-
208
- # Photo Sizing and Placement
209
- PHOTO_MAX_W_IN_GRID = COL_WIDTH_GRID_IN - 0.2
210
- # Roughly account for description text height
211
- PHOTO_MAX_H_IN_GRID = ROW_HEIGHT_GRID_IN - 0.8
212
-
213
- rotation = item.get('rotation', 0) or 0
214
- try:
215
- item['file'].seek(0)
216
- im = Image.open(item['file'])
217
- if rotation:
218
- im = im.rotate(rotation, expand=True)
219
- w_px, h_px = im.size
220
- except Exception:
221
- w_px, h_px = (1000, 1000)
222
-
223
- img_ratio = (w_px / h_px) if h_px else 1.0
224
- box_ratio = PHOTO_MAX_W_IN_GRID / PHOTO_MAX_H_IN_GRID
225
-
226
- img_stream = process_image(
227
- item['file'], compress=compress_images, quality=quality, rotation=rotation
228
- )
229
-
230
- if img_stream:
231
- # Add a new paragraph in the same cell for the photo
232
- p_photo = cell.add_paragraph()
233
- p_photo.alignment = WD_ALIGN_PARAGRAPH.CENTER
234
- if img_ratio >= box_ratio:
235
- p_photo.add_run().add_picture(img_stream, width=Inches(PHOTO_MAX_W_IN_GRID))
236
- else:
237
- p_photo.add_run().add_picture(img_stream, height=Inches(PHOTO_MAX_H_IN_GRID))
238
-
239
- processed += 1
240
- if num_images:
241
- progress_bar.progress(processed / num_images)
242
-
243
- item_idx_on_page += 1
244
 
245
  # Save DOCX
246
  doc_io = io.BytesIO()
@@ -305,7 +305,7 @@ with st.sidebar:
305
  st.rerun()
306
 
307
  st.header("Upload, Arrange, Rotate, and Describe Images")
308
- st.info("Arrange photos in the desired order. The report will be generated with a 2x2 grid (4 photos per page).")
309
  uploaded_files = st.file_uploader(
310
  "Upload all your photos here",
311
  accept_multiple_files=True,
@@ -378,4 +378,5 @@ if generate_button:
378
  c2.download_button("⬇️ Download PDF (.pdf)", pdf_io, f"{file_base}.pdf", use_container_width=True)
379
  except Exception as e:
380
  st.error(f"A critical error occurred: {e}")
381
- progress_bar.empty()
 
 
16
  pillow_heif.register_heif_opener()
17
 
18
  # --- CONSTANTS & LAYOUT ---
19
+ CONTENT_WIDTH_IN = 8.5 - (0.5 + 0.5) # 7.5"
20
+ # --- STRICT 1:4 RATIO ---
21
+ DESC_COL_IN = CONTENT_WIDTH_IN * (1 / 5.0) # 1 part = 1.5"
22
+ PHOTO_COL_IN = CONTENT_WIDTH_IN * (4 / 5.0) # 4 parts = 6.0"
23
+ ROW_HEIGHT_IN = 4.5 # Two rows per page
24
+ PHOTO_MAX_W_IN = PHOTO_COL_IN - 0.20 # Padding
25
+ PHOTO_MAX_H_IN = ROW_HEIGHT_IN - 0.20
26
 
27
  JOB_MAP = {
28
  "WM 3155 SSM Parking": "T250014 Walmart 3155 Sault Ste. Marie FY26 Parking Lot Refresh\n446 Great Northern Rd.\nSault Ste. Marie, Ontario, P6B 4Z9",
 
165
  footer = section.footer
166
  add_page_number(footer.paragraphs[0])
167
 
168
+ # --- LAYOUT FIX: Reverted to the original 2-photo-per-page layout ---
169
  num_images = len(image_items)
170
  processed = 0
171
 
172
+ for start in range(0, num_images, 2): # Process 2 images per page
173
  if start > 0:
174
  doc.add_page_break()
175
 
176
+ page_items = image_items[start:start + 2]
177
 
178
+ # A 2x2 table: Row 1 is for Photo 1, Row 2 is for Photo 2
179
  page_table = doc.add_table(rows=2, cols=2)
180
  page_table.width = Inches(CONTENT_WIDTH_IN)
181
  set_table_fixed_layout(page_table)
182
  page_table.style = 'Table Grid'
183
  page_table.alignment = WD_TABLE_ALIGNMENT.CENTER
184
 
185
+ # Set column widths to the strict 1:4 ratio
186
+ page_table.columns[0].width = Inches(DESC_COL_IN)
187
+ page_table.columns[1].width = Inches(PHOTO_COL_IN)
188
+ for r in page_table.rows:
189
+ r.height = Inches(ROW_HEIGHT_IN)
190
+ r.height_rule = WD_ROW_HEIGHT_RULE.EXACTLY
191
+ # Explicitly set cell widths as well for compatibility
192
+ r.cells[0].width = Inches(DESC_COL_IN)
193
+ r.cells[1].width = Inches(PHOTO_COL_IN)
194
+
195
+ # Fill the two rows
196
+ for row_idx in range(2):
197
+ # Only proceed if there is an item for this row
198
+ if row_idx < len(page_items):
199
+ item = page_items[row_idx]
200
+ desc_cell = page_table.cell(row_idx, 0)
201
+ photo_cell = page_table.cell(row_idx, 1)
202
+
203
+ ensure_cell_has_one_empty_paragraph(desc_cell)
204
+ ensure_cell_has_one_empty_paragraph(photo_cell)
205
+
206
+ desc_cell.vertical_alignment = WD_ALIGN_VERTICAL.TOP
207
+ photo_cell.vertical_alignment = WD_ALIGN_VERTICAL.CENTER
208
+
209
+ # Description
210
+ p_desc = desc_cell.paragraphs[0]
211
+ run_label = p_desc.add_run("Description:\n")
212
+ run_label.bold = True
213
+ p_desc.add_run(item.get('description', '') or '')
214
+
215
+ # Image processing and placement
216
+ rotation = item.get('rotation', 0) or 0
217
+ try:
218
+ item['file'].seek(0)
219
+ im = Image.open(item['file'])
220
+ if rotation:
221
+ im = im.rotate(rotation, expand=True)
222
+ w_px, h_px = im.size
223
+ except Exception:
224
+ w_px, h_px = (1000, 1000)
225
+
226
+ img_ratio = (w_px / h_px) if h_px else 1.0
227
+ box_ratio = PHOTO_MAX_W_IN / PHOTO_MAX_H_IN
228
+
229
+ img_stream = process_image(
230
+ item['file'], compress=compress_images, quality=quality, rotation=rotation
231
+ )
232
 
233
+ if img_stream:
234
+ p_photo = photo_cell.paragraphs[0]
235
+ p_photo.alignment = WD_ALIGN_PARAGRAPH.CENTER
236
+ if img_ratio >= box_ratio:
237
+ p_photo.add_run().add_picture(img_stream, width=Inches(PHOTO_MAX_W_IN))
238
+ else:
239
+ p_photo.add_run().add_picture(img_stream, height=Inches(PHOTO_MAX_H_IN))
240
 
241
+ processed += 1
242
+ if num_images:
243
+ progress_bar.progress(processed / num_images)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
244
 
245
  # Save DOCX
246
  doc_io = io.BytesIO()
 
305
  st.rerun()
306
 
307
  st.header("Upload, Arrange, Rotate, and Describe Images")
308
+ st.info("Arrange photos in the desired order. The report will have 2 photos per page.")
309
  uploaded_files = st.file_uploader(
310
  "Upload all your photos here",
311
  accept_multiple_files=True,
 
378
  c2.download_button("⬇️ Download PDF (.pdf)", pdf_io, f"{file_base}.pdf", use_container_width=True)
379
  except Exception as e:
380
  st.error(f"A critical error occurred: {e}")
381
+ progress_bar.empty()
382
+