chore: sync GovOPlaN module split state
This commit is contained in:
@@ -256,6 +256,99 @@ def _job_row(job: CampaignJob) -> dict[str, Any]:
|
||||
}
|
||||
|
||||
|
||||
def _address_summary(value: Any) -> str:
|
||||
if value is None:
|
||||
return ""
|
||||
if isinstance(value, str):
|
||||
return value
|
||||
if isinstance(value, dict):
|
||||
email = str(value.get("email") or "").strip()
|
||||
name = str(value.get("name") or "").strip()
|
||||
if name and email:
|
||||
return f"{name} <{email}>"
|
||||
return email or name
|
||||
if isinstance(value, list):
|
||||
return "; ".join(item for item in (_address_summary(item) for item in value) if item)
|
||||
return str(value)
|
||||
|
||||
|
||||
def _latest_by_job_id(attempts: list[Any]) -> dict[str, Any]:
|
||||
latest: dict[str, Any] = {}
|
||||
for attempt in attempts:
|
||||
current = latest.get(attempt.job_id)
|
||||
if current is None or (attempt.attempt_number or 0) >= (current.attempt_number or 0):
|
||||
latest[attempt.job_id] = attempt
|
||||
return latest
|
||||
|
||||
|
||||
def _attachment_names(attachments: list[dict[str, Any]] | None) -> str:
|
||||
names: list[str] = []
|
||||
for attachment in attachments or []:
|
||||
if not isinstance(attachment, dict):
|
||||
continue
|
||||
for key in ("message_filenames", "zip_entry_names"):
|
||||
values = attachment.get(key)
|
||||
if isinstance(values, list):
|
||||
names.extend(str(value) for value in values if value)
|
||||
zip_filename = attachment.get("zip_filename")
|
||||
if zip_filename:
|
||||
names.append(str(zip_filename))
|
||||
matches = attachment.get("matches")
|
||||
if isinstance(matches, list):
|
||||
for match in matches:
|
||||
if isinstance(match, dict):
|
||||
filename = match.get("filename") or match.get("name") or match.get("display_name")
|
||||
if filename:
|
||||
names.append(str(filename))
|
||||
elif match:
|
||||
names.append(str(match).rsplit("/", 1)[-1])
|
||||
seen: set[str] = set()
|
||||
deduplicated = []
|
||||
for name in names:
|
||||
if name and name not in seen:
|
||||
seen.add(name)
|
||||
deduplicated.append(name)
|
||||
return "; ".join(deduplicated)
|
||||
|
||||
|
||||
def _job_evidence_row(
|
||||
job: CampaignJob,
|
||||
*,
|
||||
latest_smtp: SendAttempt | None = None,
|
||||
latest_imap: ImapAppendAttempt | None = None,
|
||||
) -> dict[str, Any]:
|
||||
row = _job_row(job)
|
||||
recipients = job.resolved_recipients or {}
|
||||
row.update({
|
||||
"campaign_id": job.campaign_id,
|
||||
"campaign_version_id": job.campaign_version_id,
|
||||
"message_id_header": job.message_id_header,
|
||||
"eml_storage_key": job.eml_storage_key,
|
||||
"eml_local_path": job.eml_local_path,
|
||||
"from": _address_summary(recipients.get("from")),
|
||||
"to": _address_summary(recipients.get("to")),
|
||||
"cc": _address_summary(recipients.get("cc")),
|
||||
"bcc": _address_summary(recipients.get("bcc")),
|
||||
"reply_to": _address_summary(recipients.get("reply_to")),
|
||||
"attachment_names": _attachment_names(job.resolved_attachments),
|
||||
"latest_smtp_attempt_number": latest_smtp.attempt_number if latest_smtp else None,
|
||||
"latest_smtp_status": latest_smtp.status if latest_smtp else None,
|
||||
"latest_smtp_status_code": latest_smtp.smtp_status_code if latest_smtp else None,
|
||||
"latest_smtp_response": latest_smtp.smtp_response if latest_smtp else None,
|
||||
"latest_smtp_error_type": latest_smtp.error_type if latest_smtp else None,
|
||||
"latest_smtp_error_message": latest_smtp.error_message if latest_smtp else None,
|
||||
"latest_smtp_started_at": latest_smtp.started_at.isoformat() if latest_smtp and latest_smtp.started_at else None,
|
||||
"latest_smtp_finished_at": latest_smtp.finished_at.isoformat() if latest_smtp and latest_smtp.finished_at else None,
|
||||
"latest_imap_attempt_number": latest_imap.attempt_number if latest_imap else None,
|
||||
"latest_imap_status": latest_imap.status if latest_imap else None,
|
||||
"latest_imap_folder": latest_imap.folder if latest_imap else None,
|
||||
"latest_imap_error_message": latest_imap.error_message if latest_imap else None,
|
||||
"latest_imap_created_at": latest_imap.created_at.isoformat() if latest_imap and latest_imap.created_at else None,
|
||||
"latest_imap_updated_at": latest_imap.updated_at.isoformat() if latest_imap and latest_imap.updated_at else None,
|
||||
})
|
||||
return row
|
||||
|
||||
|
||||
def generate_campaign_report(
|
||||
session: Session,
|
||||
*,
|
||||
@@ -401,13 +494,47 @@ def generate_jobs_csv(
|
||||
.order_by(CampaignJob.entry_index.asc())
|
||||
.all()
|
||||
)
|
||||
rows = [_job_row(job) for job in jobs]
|
||||
job_ids = [job.id for job in jobs]
|
||||
smtp_attempts = (
|
||||
session.query(SendAttempt)
|
||||
.filter(SendAttempt.job_id.in_(job_ids))
|
||||
.order_by(SendAttempt.job_id.asc(), SendAttempt.attempt_number.asc())
|
||||
.all()
|
||||
if job_ids
|
||||
else []
|
||||
)
|
||||
imap_attempts = (
|
||||
session.query(ImapAppendAttempt)
|
||||
.filter(ImapAppendAttempt.job_id.in_(job_ids))
|
||||
.order_by(ImapAppendAttempt.job_id.asc(), ImapAppendAttempt.attempt_number.asc())
|
||||
.all()
|
||||
if job_ids
|
||||
else []
|
||||
)
|
||||
latest_smtp = _latest_by_job_id(smtp_attempts)
|
||||
latest_imap = _latest_by_job_id(imap_attempts)
|
||||
rows = [
|
||||
_job_evidence_row(
|
||||
job,
|
||||
latest_smtp=latest_smtp.get(job.id),
|
||||
latest_imap=latest_imap.get(job.id),
|
||||
)
|
||||
for job in jobs
|
||||
]
|
||||
fieldnames = [
|
||||
"job_id",
|
||||
"campaign_id",
|
||||
"campaign_version_id",
|
||||
"entry_index",
|
||||
"entry_id",
|
||||
"recipient_email",
|
||||
"from",
|
||||
"to",
|
||||
"cc",
|
||||
"bcc",
|
||||
"reply_to",
|
||||
"subject",
|
||||
"message_id_header",
|
||||
"build_status",
|
||||
"validation_status",
|
||||
"queue_status",
|
||||
@@ -422,9 +549,26 @@ def generate_jobs_csv(
|
||||
"last_error",
|
||||
"eml_size_bytes",
|
||||
"eml_sha256",
|
||||
"eml_storage_key",
|
||||
"eml_local_path",
|
||||
"issues_count",
|
||||
"attachment_config_count",
|
||||
"matched_file_count",
|
||||
"attachment_names",
|
||||
"latest_smtp_attempt_number",
|
||||
"latest_smtp_status",
|
||||
"latest_smtp_status_code",
|
||||
"latest_smtp_response",
|
||||
"latest_smtp_error_type",
|
||||
"latest_smtp_error_message",
|
||||
"latest_smtp_started_at",
|
||||
"latest_smtp_finished_at",
|
||||
"latest_imap_attempt_number",
|
||||
"latest_imap_status",
|
||||
"latest_imap_folder",
|
||||
"latest_imap_error_message",
|
||||
"latest_imap_created_at",
|
||||
"latest_imap_updated_at",
|
||||
]
|
||||
buffer = io.StringIO()
|
||||
writer = csv.DictWriter(buffer, fieldnames=fieldnames)
|
||||
|
||||
Reference in New Issue
Block a user