style: fix all flake8 linter errors across app/ directory
- Run Black formatter and isort on all app/ files - Remove unused imports (F401) across multiple files - Add # noqa: F401 for intentional re-exports in celery_worker.py, tasks/__init__.py, utils.py, frontend.py, views/base.py - Fix f-strings without placeholders (F541) in azure.py, notification.py, check_credentials.py, upload_to_onedrive.py, settings.py - Fix bare except (E722) in upload_to_sftp.py - Fix block comment format (E265) in models.py - Move imports to top of file to fix E402 in celery_app.py, celery_worker.py - Fix line-too-long (E501) by wrapping strings in multiple files - Remove unused variable (F841) in upload_to_nextcloud.py Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
This commit is contained in:
@@ -1,23 +1,24 @@
|
||||
import os
|
||||
import logging
|
||||
import PyPDF2
|
||||
import math
|
||||
import json
|
||||
import logging
|
||||
import os
|
||||
|
||||
import PyPDF2
|
||||
|
||||
from app.config import settings
|
||||
from app.tasks.retry_config import BaseTaskWithRetry
|
||||
from app.tasks.extract_metadata_with_gpt import extract_metadata_with_gpt
|
||||
from app.celery_app import celery
|
||||
from app.config import settings
|
||||
from app.tasks.extract_metadata_with_gpt import extract_metadata_with_gpt
|
||||
from app.tasks.retry_config import BaseTaskWithRetry
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def determine_rotation_angle(detected_angle):
|
||||
"""
|
||||
Determine the optimal rotation angle based on detected angle.
|
||||
|
||||
|
||||
Args:
|
||||
detected_angle: The angle detected by Azure Document Intelligence
|
||||
|
||||
|
||||
Returns:
|
||||
int: The angle to rotate the page in PyPDF2 (must be multiple of 90 degrees)
|
||||
"""
|
||||
@@ -25,11 +26,11 @@ def determine_rotation_angle(detected_angle):
|
||||
normalized_angle = detected_angle % 360
|
||||
if normalized_angle < 0:
|
||||
normalized_angle += 360
|
||||
|
||||
|
||||
# If angle is very small (< 1 degree), don't rotate
|
||||
if abs(normalized_angle) < 1 or abs(normalized_angle - 360) < 1:
|
||||
return 0
|
||||
|
||||
|
||||
# For angles close to 90, 180, or 270 degrees (±5°), round to nearest 90° increment
|
||||
for target in [90, 180, 270]:
|
||||
if abs(normalized_angle - target) < 5:
|
||||
@@ -37,7 +38,7 @@ def determine_rotation_angle(detected_angle):
|
||||
rotation_value = (360 - target) % 360
|
||||
logger.info(f"Detected angle {detected_angle}° is close to {target}°, will rotate by {rotation_value}°")
|
||||
return rotation_value
|
||||
|
||||
|
||||
# For other significant angles, round to nearest 90° increment
|
||||
# (PyPDF2 only supports rotations in 90-degree increments)
|
||||
closest_90_multiple = round(normalized_angle / 90) * 90
|
||||
@@ -46,11 +47,12 @@ def determine_rotation_angle(detected_angle):
|
||||
logger.info(f"Detected angle {detected_angle}° rounded to {closest_90_multiple}°, will rotate by {rotation_value}°")
|
||||
return rotation_value
|
||||
|
||||
|
||||
@celery.task(base=BaseTaskWithRetry)
|
||||
def rotate_pdf_pages(filename: str, extracted_text: str, rotation_data=None, file_id: int = None):
|
||||
"""
|
||||
Rotates pages in a PDF document based on detected rotation angles.
|
||||
|
||||
|
||||
Args:
|
||||
filename: The name of the file to rotate
|
||||
extracted_text: The extracted text from the document
|
||||
@@ -61,7 +63,7 @@ def rotate_pdf_pages(filename: str, extracted_text: str, rotation_data=None, fil
|
||||
pdf_path = os.path.join(settings.workdir, "tmp", filename)
|
||||
if not os.path.exists(pdf_path):
|
||||
raise FileNotFoundError(f"PDF file not found: {pdf_path}")
|
||||
|
||||
|
||||
# Skip rotation if no rotation data provided
|
||||
if not rotation_data:
|
||||
logger.info(f"No rotation data provided for {filename}, proceeding with metadata extraction")
|
||||
@@ -80,53 +82,62 @@ def rotate_pdf_pages(filename: str, extracted_text: str, rotation_data=None, fil
|
||||
logger.info(f"No significant rotations detected in {filename}, proceeding with metadata extraction")
|
||||
extract_metadata_with_gpt.delay(filename, extracted_text, file_id)
|
||||
return {"file": filename, "status": "no_rotation_needed"}
|
||||
|
||||
|
||||
logger.info(f"Rotating {len(normalized_rotation_data)} pages in {filename}")
|
||||
applied_rotations = {}
|
||||
|
||||
|
||||
# Load the PDF
|
||||
with open(pdf_path, 'rb') as file:
|
||||
with open(pdf_path, "rb") as file:
|
||||
pdf_reader = PyPDF2.PdfReader(file)
|
||||
pdf_writer = PyPDF2.PdfWriter()
|
||||
|
||||
|
||||
# Process each page
|
||||
for page_idx in range(len(pdf_reader.pages)):
|
||||
page = pdf_reader.pages[page_idx]
|
||||
|
||||
|
||||
# Apply rotation if this page has rotation data
|
||||
if page_idx in normalized_rotation_data and abs(normalized_rotation_data[page_idx]) > 0:
|
||||
detected_angle = normalized_rotation_data[page_idx]
|
||||
rotation_angle = determine_rotation_angle(detected_angle)
|
||||
|
||||
|
||||
if rotation_angle > 0:
|
||||
# PyPDF2 uses clockwise rotation in 90-degree increments
|
||||
page.rotate(rotation_angle)
|
||||
logger.info(f"Page {page_idx+1} rotated by {rotation_angle}° (from detected {detected_angle}°)")
|
||||
logger.info(
|
||||
f"Page {page_idx+1} rotated by {rotation_angle}° "
|
||||
f"(from detected {detected_angle}°)"
|
||||
)
|
||||
applied_rotations[str(page_idx)] = rotation_angle
|
||||
else:
|
||||
logger.info(f"Page {page_idx+1} had detected angle {detected_angle}° but determined it doesn't need rotation")
|
||||
|
||||
logger.info(
|
||||
f"Page {page_idx+1} had detected angle {detected_angle}° "
|
||||
"but determined it doesn't need rotation"
|
||||
)
|
||||
|
||||
pdf_writer.add_page(page)
|
||||
|
||||
|
||||
# Save the rotated PDF
|
||||
with open(pdf_path, 'wb') as output_file:
|
||||
with open(pdf_path, "wb") as output_file:
|
||||
pdf_writer.write(output_file)
|
||||
|
||||
|
||||
if applied_rotations:
|
||||
logger.info(f"Successfully rotated PDF: {filename} with rotations: {json.dumps(applied_rotations)}")
|
||||
else:
|
||||
logger.info(f"Detected rotations in {filename} but no rotations were actually applied (angles too small or not multiples of 90°)")
|
||||
|
||||
logger.info(
|
||||
f"Detected rotations in {filename} but no rotations were actually applied "
|
||||
"(angles too small or not multiples of 90°)"
|
||||
)
|
||||
|
||||
# Continue with metadata extraction
|
||||
extract_metadata_with_gpt.delay(filename, extracted_text, file_id)
|
||||
|
||||
|
||||
return {
|
||||
"file": filename,
|
||||
"file": filename,
|
||||
"status": "rotated" if applied_rotations else "no_rotation_needed",
|
||||
"detected_rotations": rotation_data,
|
||||
"applied_rotations": applied_rotations
|
||||
"applied_rotations": applied_rotations,
|
||||
}
|
||||
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Error rotating PDF {filename}: {e}")
|
||||
# Continue with metadata extraction despite rotation failure
|
||||
|
||||
Reference in New Issue
Block a user