Coverage for portality/tasks/journal_in_out_doaj.py: 78%

87 statements  

« prev     ^ index     » next       coverage.py v6.4.2, created at 2022-07-22 15:59 +0100

1from flask_login import current_user 

2from portality import models, lock 

3from portality.bll import DOAJ 

4from portality.core import app 

5 

6from portality.tasks.redis_huey import main_queue 

7from portality.decorators import write_required 

8 

9from portality.background import BackgroundTask, BackgroundApi, BackgroundSummary 

10 

11import json 

12 

13from portality.ui.messages import Messages 

14 

15 

16def change_by_query(query, in_doaj_new_val, dry_run=True): 

17 ids = [] 

18 sane = {} 

19 sane["query"] = query["query"] 

20 job = None 

21 for j in models.Journal.iterate(sane, wrap=False): 

22 ids.append(j.get("id")) 

23 if not dry_run: 

24 job = change_in_doaj(ids, in_doaj_new_val, selection_query=sane) 

25 

26 affected = len(ids) 

27 job_id = None 

28 if job is not None: 

29 job_id = job.id 

30 return BackgroundSummary(job_id, affected={"journals" : affected}) 

31 

32 # return len(ids) 

33 

34def change_in_doaj(journal_ids, in_doaj_new_val, **kwargs): 

35 job = SetInDOAJBackgroundTask.prepare(current_user.id, journal_ids=journal_ids, in_doaj=in_doaj_new_val, **kwargs) 

36 SetInDOAJBackgroundTask.submit(job) 

37 return job 

38 

39 

40class SetInDOAJBackgroundTask(BackgroundTask): 

41 # ~~SetInDOAJBackgroundTask:Process->BackgroundTask:Process~~ 

42 __action__ = "set_in_doaj" 

43 

44 def run(self): 

45 """ 

46 Execute the task as specified by the background_jon 

47 :return: 

48 """ 

49 job = self.background_job 

50 params = job.params 

51 

52 journal_ids = self.get_param(params, "journal_ids") 

53 in_doaj = self.get_param(params, "in_doaj") 

54 

55 if journal_ids is None or len(journal_ids) == 0 or in_doaj is None: 

56 raise RuntimeError("SetInDOAJBackgroundTask.run run without sufficient parameters") 

57 

58 for journal_id in journal_ids: 

59 job.add_audit_message("Setting in_doaj to {x} for journal {y}".format(x=str(in_doaj), y=journal_id)) 

60 # ~~->Journal:Model~~ 

61 j = models.Journal.pull(journal_id) 

62 # ~~->Account:Model~~ 

63 account = models.Account.pull(job.user) 

64 if j is None: 

65 raise RuntimeError("Journal with id {} does not exist".format(journal_id)) 

66 if not in_doaj: 

67 # Rejecting associated update request 

68 # ~~->Application:Service~~ 

69 svc = DOAJ.applicationService() 

70 ur = svc.reject_update_request_of_journal(j.id, account) 

71 if ur: 

72 job.add_audit_message(Messages.AUTOMATICALLY_REJECTED_UPDATE_REQUEST_WITH_ID.format(urid=ur)) 

73 else: 

74 job.add_audit_message(Messages.NO_UPDATE_REQUESTS) 

75 

76 

77 j.bibjson().active = in_doaj 

78 j.set_in_doaj(in_doaj) 

79 j.save() 

80 j.propagate_in_doaj_status_to_articles() # will save each article, could take a while 

81 job.add_audit_message("Journal {x} set in_doaj to {y}, and all associated articles".format(x=journal_id, y=str(in_doaj))) 

82 

83 def cleanup(self): 

84 """ 

85 Cleanup after a successful OR failed run of the task 

86 :return: 

87 """ 

88 # remove the lock on the journal 

89 job = self.background_job 

90 params = job.params 

91 journal_ids = self.get_param(params, "journal_ids") 

92 username = job.user 

93 

94 lock.batch_unlock("journal", journal_ids, username) 

95 

96 @classmethod 

97 def prepare(cls, username, **kwargs): 

98 """ 

99 Take an arbitrary set of keyword arguments and return an instance of a BackgroundJob, 

100 or fail with a suitable exception 

101 

102 :param kwargs: arbitrary keyword arguments pertaining to this task type 

103 :return: a BackgroundJob instance representing this task 

104 """ 

105 

106 # first prepare a job record 

107 job = models.BackgroundJob() 

108 job.user = username 

109 job.action = cls.__action__ 

110 

111 journal_ids = kwargs.get("journal_ids") 

112 

113 params = {} 

114 cls.set_param(params, "journal_ids", journal_ids) 

115 cls.set_param(params, "in_doaj", kwargs.get("in_doaj")) 

116 

117 if journal_ids is None or len(journal_ids) == 0 or kwargs.get("in_doaj") is None: 

118 raise RuntimeError("SetInDOAJBackgroundTask.prepare run without sufficient parameters") 

119 

120 job.params = params 

121 

122 if "selection_query" in kwargs: 

123 refs = {} 

124 cls.set_reference(refs, "selection_query", json.dumps(kwargs.get('selection_query'))) 

125 job.reference = refs 

126 

127 # now ensure that we have the locks for this journal 

128 # will raise an exception if this fails 

129 lock.batch_lock("journal", journal_ids, username, timeout=app.config.get("BACKGROUND_TASK_LOCK_TIMEOUT", 3600)) 

130 

131 return job 

132 

133 @classmethod 

134 def submit(cls, background_job): 

135 """ 

136 Submit the specified BackgroundJob to the background queue 

137 

138 :param background_job: the BackgroundJob instance 

139 :return: 

140 """ 

141 background_job.save() 

142 set_in_doaj.schedule(args=(background_job.id,), delay=10) 

143 

144@main_queue.task() 

145@write_required(script=True) 

146def set_in_doaj(job_id): 

147 job = models.BackgroundJob.pull(job_id) 

148 task = SetInDOAJBackgroundTask(job) 

149 BackgroundApi.execute(task)