|
11 | 11 | from invenio_administration.views.base import AdminResourceListView
|
12 | 12 | from invenio_i18n import lazy_gettext as _
|
13 | 13 |
|
| 14 | +from invenio_jobs.administration.jobs import JobsAdminMixin |
| 15 | +from flask import g |
| 16 | +from invenio_jobs.proxies import current_app_log_service, current_runs_service |
| 17 | +from dateutil import parser |
14 | 18 |
|
15 |
| -class RunsListView(AdminResourceListView): |
16 |
| - """Configuration for System Runs sets list view.""" |
17 |
| - |
18 |
| - api_endpoint = "/runs" |
19 |
| - name = "Runs" |
20 |
| - search_request_headers = {"Accept": "application/vnd.inveniordm.v1+json"} |
21 |
| - title = "Runs" |
22 |
| - category = "System" |
23 |
| - resource_config = "jobs_resource" |
24 |
| - icon = "signal" |
25 |
| - extension_name = "invenio-rdm-records" |
26 |
| - display_search = False |
27 |
| - display_delete = False |
28 |
| - display_edit = False |
29 |
| - display_create = False |
30 |
| - actions = None |
| 19 | +class RunsDetailsView(JobsAdminMixin, AdminResourceListView): |
| 20 | + """Configuration for System Runs details view.""" |
| 21 | + |
| 22 | + url = "/runs/<pid_value>" |
| 23 | + search_request_headers = {"Accept": "application/json"} |
| 24 | + request_headers = {"Accept": "application/json"} |
| 25 | + name = "run-details" |
| 26 | + resource_config = "runs_resource" |
| 27 | + title = "Run Details" |
| 28 | + disabled = lambda _: True |
| 29 | + |
| 30 | + template = "invenio_jobs/system/runs/runs-details.html" |
| 31 | + |
| 32 | + list_view_name = "jobs" |
| 33 | + pid_value = "<pid_value>" |
| 34 | + |
| 35 | + def get_context(self, **kwargs): |
| 36 | + """Compute admin view context.""" |
| 37 | + pid_value = kwargs.get("pid_value", "") |
| 38 | + logs = self._get_logs(pid_value) |
| 39 | + job_id = logs[0]["resource"]["id"] |
| 40 | + run_dict = self._get_run_dict(job_id, pid_value) |
| 41 | + |
| 42 | + ctx = super().get_context(**kwargs) |
| 43 | + ctx["logs"] = logs |
| 44 | + ctx["run"] = run_dict |
| 45 | + ctx["run_duration"] = self.get_duration_in_minutes(run_dict.get("started_at"), run_dict.get("finished_at")) |
| 46 | + return ctx |
| 47 | + |
| 48 | + def _get_logs(self, pid_value): |
| 49 | + """Retrieve and format logs.""" |
| 50 | + params = dict(q=pid_value) |
| 51 | + logs_result = current_app_log_service.search(g.identity, params) |
| 52 | + logs = logs_result.to_dict()["hits"]["hits"] |
| 53 | + |
| 54 | + for log in logs: |
| 55 | + log["formatted_timestamp"] = self._format_datetime(log["timestamp"]) |
| 56 | + |
| 57 | + return logs |
| 58 | + |
| 59 | + def _get_run_dict(self, job_id, pid_value): |
| 60 | + """Retrieve and format run dictionary.""" |
| 61 | + run_dict = current_runs_service.read(g.identity, job_id, pid_value).to_dict() |
| 62 | + run_dict["formatted_started_at"] = self._format_datetime(run_dict["started_at"]) |
| 63 | + return run_dict |
| 64 | + |
| 65 | + def _format_datetime(self, timestamp): |
| 66 | + """Format ISO datetime to a user-friendly string.""" |
| 67 | + dt = parser.isoparse(timestamp) |
| 68 | + return dt.strftime("%Y-%m-%d %H:%M") |
| 69 | + |
| 70 | + def get_duration_in_minutes(self, started_at, finished_at): |
| 71 | + """Calculate duration in minutes.""" |
| 72 | + start_time = parser.isoparse(started_at) |
| 73 | + end_time = parser.isoparse(finished_at) |
| 74 | + |
| 75 | + duration = (end_time - start_time).total_seconds() / 60 |
| 76 | + return int(duration) |
0 commit comments