Trigger immediate Cove import on link and enrich run details

This commit is contained in:
Ivo Oskamp 2026-02-23 11:57:39 +01:00
parent 06abd8c7a3
commit f68f92e63a
2 changed files with 107 additions and 13 deletions

View File

@ -59,6 +59,21 @@ STATUS_MAP: dict[int, str] = {
12: "Warning", # Restarted
}
# Mapping from Cove status code to readable label
STATUS_LABELS: dict[int, str] = {
1: "In process",
2: "Failed",
3: "Aborted",
5: "Completed",
6: "Interrupted",
7: "Not started",
8: "Completed with errors",
9: "In progress with faults",
10: "Over quota",
11: "No selection",
12: "Restarted",
}
# Datasource label mapping (column prefix → human-readable label)
DATASOURCE_LABELS: dict[str, str] = {
"D1": "Files & Folders",
@ -210,6 +225,16 @@ def _map_status(code: Any) -> str:
return "Warning"
def _status_label(code: Any) -> str:
"""Map a Cove status code (int) to a human-readable label."""
if code is None:
return "Unknown"
try:
return STATUS_LABELS.get(int(code), f"Code {int(code)}")
except (ValueError, TypeError):
return "Unknown"
def _ts_to_dt(value: Any) -> datetime | None:
"""Convert a Unix timestamp (int or str) to a naive UTC datetime."""
if value is None:
@ -223,6 +248,13 @@ def _ts_to_dt(value: Any) -> datetime | None:
return None
def _fmt_utc(dt: datetime | None) -> str:
"""Format a naive UTC datetime to readable text for run object messages."""
if not dt:
return "unknown"
return dt.strftime("%Y-%m-%d %H:%M UTC")
def run_cove_import(settings) -> tuple[int, int, int, int]:
"""Fetch Cove account statistics and update the staging table + JobRuns.
@ -381,13 +413,20 @@ def _process_account(account: dict) -> bool:
return False
status = _map_status(last_status_code)
run_remark = (
f"Cove account: {account_name or account_id} | "
f"Computer: {computer_name or '-'} | "
f"Customer: {customer_name or '-'} | "
f"Last status: {_status_label(last_status_code)} ({last_status_code if last_status_code is not None else '-'}) | "
f"Last run: {_fmt_utc(last_run_at)}"
)
run = JobRun(
job_id=job.id,
mail_message_id=None,
run_at=last_run_at,
status=status,
remark=None,
remark=run_remark,
missed=False,
override_applied=False,
source_type="cove_api",
@ -422,6 +461,11 @@ def _persist_datasource_objects(
continue
status = _map_status(status_code)
ds_last_ts = _ts_to_dt(flat.get(f"{ds_prefix}F15"))
status_msg = (
f"Cove datasource status: {_status_label(status_code)} "
f"({status_code}); last session: {_fmt_utc(ds_last_ts)}"
)
# Upsert customer_objects
customer_object_id = conn.execute(
@ -461,10 +505,11 @@ def _persist_datasource_objects(
text(
"""
INSERT INTO run_object_links (run_id, customer_object_id, status, error_message, observed_at)
VALUES (:run_id, :customer_object_id, :status, NULL, :observed_at)
VALUES (:run_id, :customer_object_id, :status, :error_message, :observed_at)
ON CONFLICT (run_id, customer_object_id)
DO UPDATE SET
status = EXCLUDED.status,
error_message = EXCLUDED.error_message,
observed_at = EXCLUDED.observed_at
"""
),
@ -472,6 +517,7 @@ def _persist_datasource_objects(
"run_id": run_id,
"customer_object_id": customer_object_id,
"status": status,
"observed_at": observed_at,
"error_message": status_msg,
"observed_at": ds_last_ts or observed_at,
},
)

View File

@ -9,6 +9,7 @@ import re
from .routes_shared import * # noqa: F401,F403
from .routes_shared import _log_admin_event
from ..cove_importer import CoveImportError, run_cove_import
from ..models import CoveAccount, Customer, Job, SystemSettings
@ -129,6 +130,8 @@ def cove_account_link(cove_account_db_id: int):
action = (request.form.get("action") or "").strip() # "create" or "link"
linked_job_name = ""
if action == "create":
# Create a new job from the Cove account data
customer_id_raw = (request.form.get("customer_id") or "").strip()
@ -171,11 +174,8 @@ def cove_account_link(cove_account_db_id: int):
f"Created job {job.id} and linked Cove account {cove_acc.account_id} ({cove_acc.account_name})",
details=f"customer={customer.name}, job_name={job_name}",
)
flash(
f"Job '{job_name}' created for customer '{customer.name}'. "
"Runs will appear after the next Cove import.",
"success",
)
linked_job_name = job_name
flash(f"Job '{job_name}' created for customer '{customer.name}'.", "success")
elif action == "link":
# Link to an existing job
@ -204,14 +204,62 @@ def cove_account_link(cove_account_db_id: int):
f"Linked Cove account {cove_acc.account_id} ({cove_acc.account_name}) to existing job {job.id}",
details=f"job_name={job.job_name}",
)
flash(
f"Cove account linked to job '{job.job_name}'. "
"Runs will appear after the next Cove import.",
"success",
)
linked_job_name = job.job_name or ""
flash(f"Cove account linked to job '{job.job_name}'.", "success")
else:
flash("Unknown action.", "warning")
return redirect(url_for("main.cove_accounts"))
# Trigger an immediate import so the latest Cove run appears right away
# after linking (instead of waiting for the next scheduled/manual import).
settings = SystemSettings.query.first()
if settings and getattr(settings, "cove_enabled", False):
try:
total, created, skipped, errors = run_cove_import(settings)
_log_admin_event(
"cove_import_after_link",
(
"Triggered immediate Cove import after account link. "
f"accounts={total}, created={created}, skipped={skipped}, errors={errors}"
),
)
if created > 0:
flash(
(
f"Immediate import complete for '{linked_job_name}'. "
f"New runs: {created} (accounts: {total}, skipped: {skipped}, errors: {errors})."
),
"success" if errors == 0 else "warning",
)
else:
flash(
(
f"Immediate import complete for '{linked_job_name}', but no new run was found yet. "
f"(accounts: {total}, skipped: {skipped}, errors: {errors})"
),
"info" if errors == 0 else "warning",
)
except CoveImportError as exc:
_log_admin_event(
"cove_import_after_link_error",
f"Immediate Cove import after account link failed: {exc}",
)
flash(
"Account linked, but immediate import failed. "
"You can run import again from Cove settings.",
"warning",
)
except Exception as exc:
_log_admin_event(
"cove_import_after_link_error",
f"Unexpected immediate Cove import error after account link: {exc}",
)
flash(
"Account linked, but immediate import encountered an unexpected error. "
"You can run import again from Cove settings.",
"warning",
)
return redirect(url_for("main.cove_accounts"))