Coverage for portality / tasks / admin_reports.py: 26%
85 statements
« prev ^ index » next coverage.py v7.13.5, created at 2026-05-05 00:09 +0100
« prev ^ index » next coverage.py v7.13.5, created at 2026-05-05 00:09 +0100
1from portality import models
2from portality.background import BackgroundTask, BackgroundApi
3from portality.bll.doaj import DOAJ
4from portality.core import app
5from portality.tasks.helpers import background_helper
6from portality.tasks.redis_huey import events_queue as queue
7from portality import constants
8from portality.util import url_for
10import json
13class AdminReportsBackgroundTask(BackgroundTask):
15 __action__ = "admin_reports"
17 MODELS = {
18 "journal": models.Journal,
19 "application": models.Application
20 }
22 def __init__(self, background_job):
23 super(AdminReportsBackgroundTask, self).__init__(background_job)
24 self.filename = None
26 def run(self):
27 """
28 Execute the task as specified by the background_job
29 :return:
30 """
31 job = self.background_job
33 params = job.params
34 model_type = self.get_param(params, "model", "journal")
35 query_raw = self.get_param(params, "query", None)
36 ui_query_raw = self.get_param(params, "ui_query", None)
37 name = self.get_param(params, "name", None)
38 notes = self.get_param(params, "notes", False)
40 model = self.MODELS.get(model_type, models.Journal)
41 query = json.loads(query_raw) if query_raw is not None else None
43 def serialise_notes(obj):
44 """
45 Serialise the notes for a journal or application object
46 :param obj: a models.Journal or models.Application
47 :return: a list of notes in the order they were added
48 """
49 out = ""
50 if hasattr(obj, "ordered_notes"):
51 notes = obj.ordered_notes
52 for n in notes:
53 d = n.get("date", "unknown date")
54 a = n.get("author_id", "unknown author")
55 note = n.get("note", "")
56 out += f"[{d}] {a}: {note}\n\n"
57 return ("Notes", out.strip())
59 custom_columns = []
60 if notes:
61 job.add_audit_message("Export requested with notes")
62 custom_columns.append(serialise_notes)
64 # generate the admin csv in the temp store
65 export_svc = DOAJ.exportService()
66 filepath, filename = export_svc.csv(model, query,
67 admin_fieldset=True,
68 obscure_accounts=False,
69 add_sensitive_account_info=True,
70 exclude_no_issn=False,
71 custom_columns=custom_columns,
72 )
73 self.filename = filename
75 # publish it to the main store and record its existence
76 export = export_svc.publish(filepath, filename, requester=job.user, request_date=job.created_date, name=name, query=ui_query_raw, model=model_type)
77 job.add_audit_message("Export generated with id {id}".format(id=export.id))
79 # send a notification to the requesting user
80 notify_svc = DOAJ.notificationsService()
82 # note we're using the doaj url_for wrapper, not the flask url_for directly, due to the request context hack required
83 url = url_for("admin.get_report", report_id=export.id)
85 source_id = "bg:job:" + self.__action__ + ":export_available"
87 notification = models.Notification()
88 notification.who = job.user
89 notification.created_by = source_id
90 notification.classification = constants.NOTIFICATION_CLASSIFICATION_FINISHED
91 notification.long = notify_svc.long_notification(source_id).format(name=name)
92 notification.short = notify_svc.short_notification(source_id).format(name=name)
93 notification.action = url
94 notify_svc.notify(notification)
96 def cleanup(self):
97 """
98 Cleanup after a successful OR failed run of the task
99 :return:
100 """
101 if self.filename is not None:
102 export_svc = DOAJ.exportService()
103 export_svc.delete_tmp_csv(self.filename)
104 self.filename = None
106 @classmethod
107 def prepare(cls, username, **kwargs):
108 """
109 Take an arbitrary set of keyword arguments and return an instance of a BackgroundJob,
110 or fail with a suitable exception
112 :param kwargs: arbitrary keyword arguments pertaining to this task type
113 :return: a BackgroundJob instance representing this task
114 """
115 # prepare a job record
116 model = kwargs.get("model", "journal")
117 query = kwargs.get("true_query", None)
118 ui_query = kwargs.get("ui_query", None)
119 name = kwargs.get("name", None)
120 notes = kwargs.get("notes", False)
122 params = {}
123 cls.set_param(params, "model", model)
124 cls.set_param(params, "query", json.dumps(query))
125 cls.set_param(params, "ui_query", json.dumps(ui_query))
126 cls.set_param(params, "name", name)
127 cls.set_param(params, "notes", notes)
129 # first prepare a job record
130 job = background_helper.create_job(username=username,
131 action=cls.__action__,
132 params=params,
133 queue_id=huey_helper.queue_id, )
135 return job
137 @classmethod
138 def submit(cls, background_job):
139 """
140 Submit the specified BackgroundJob to the background queue
142 :param background_job: the BackgroundJob instance
143 :return:
144 """
145 background_job.save()
146 admin_reports.schedule(args=(background_job.id,), delay=app.config.get('HUEY_ASYNC_DELAY', 10))
149huey_helper = AdminReportsBackgroundTask.create_huey_helper(queue)
152@huey_helper.register_execute(is_load_config=False)
153def admin_reports(job_id):
154 job = models.BackgroundJob.pull(job_id)
155 task = AdminReportsBackgroundTask(job)
156 BackgroundApi.execute(task)