Coverage for portality / view / editor.py: 46%

84 statements  

« prev     ^ index     » next       coverage.py v7.13.5, created at 2026-05-05 00:09 +0100

1from flask import Blueprint, request, flash, abort 

2from flask import render_template, redirect, url_for 

3from flask_login import current_user, login_required 

4 

5from portality.core import app 

6from portality.decorators import ssl_required, restrict_to_role, write_required 

7from portality import models 

8from portality.bll import DOAJ, exceptions 

9from portality.lcc import lcc_jstree 

10 

11from portality import lock 

12from portality.forms.application_forms import ApplicationFormFactory, JournalFormFactory 

13from portality import constants 

14from portality.crosswalks.application_form import ApplicationFormXWalk 

15 

16from portality.util import flash_with_url 

17from portality.view.view_helper import exparam_editing_user 

18from portality.ui import templates 

19 

20blueprint = Blueprint('editor', __name__) 

21 

22# restrict everything in admin to logged in users with the "admin" role 

23@blueprint.before_request 

24def restrict(): 

25 return restrict_to_role('editor_area') 

26 

27@blueprint.route("/") 

28@login_required 

29@ssl_required 

30def index(): 

31 # ~~-> Todo:Service~~ 

32 svc = DOAJ.todoService() 

33 todos = svc.top_todo(current_user._get_current_object(), size=app.config.get("TODO_LIST_SIZE"), update_requests=False) 

34 count = svc.user_finished_historical_counts(current_user._get_current_object()) 

35 # ~~-> Dashboard:Page~~ 

36 return render_template(templates.EDITOR_DASHBOARD, todos=todos, historical_count=count) 

37 

38 

39@blueprint.route('/group_applications') 

40@login_required 

41@ssl_required 

42def group_suggestions(): 

43 return render_template(templates.EDITOR_GROUP_APPLICATIONS_SEARCH) 

44 

45 

46@blueprint.route('/your_applications') 

47@login_required 

48@ssl_required 

49def associate_suggestions(): 

50 return render_template(templates.EDITOR_YOUR_APPLICATIONS_SEARCH) 

51 

52# Editors no longer manage journals, so this code is obsolete, but nonetheless 

53# it's useful to keep it around for reference 

54 

55# @blueprint.route('/journal/<journal_id>', methods=["GET", "POST"]) 

56# @login_required 

57# @ssl_required 

58# @write_required() 

59# def journal_page(journal_id): 

60# auth_svc = DOAJ.authorisationService() 

61# journal_svc = DOAJ.journalService() 

62# 

63# journal, _ = journal_svc.journal(journal_id) 

64# if journal is None: 

65# abort(404) 

66# 

67# try: 

68# auth_svc.can_edit_journal(current_user._get_current_object(), journal) 

69# except exceptions.AuthoriseException: 

70# abort(401) 

71# 

72# # # now check whether the user is the editor of the editor group 

73# role = "associate_editor" 

74# eg = models.EditorGroup.pull_by_key("name", journal.editor_group) 

75# if eg is not None and eg.editor == current_user.id: 

76# role = "editor" 

77# 

78# # attempt to get a lock on the object 

79# try: 

80# lockinfo = lock.lock(constants.LOCK_JOURNAL, journal_id, current_user.id) 

81# except lock.Locked as l: 

82# return render_template("editor/journal_locked.html", journal=journal, lock=l.lock, lcc_tree=lcc_jstree) 

83# 

84# fc = JournalFormFactory.context(role, extra_param=exparam_editing_user()) 

85# 

86# if request.method == "GET": 

87# fc.processor(source=journal) 

88# return fc.render_template(lock=lockinfo, obj=journal, lcc_tree=lcc_jstree) 

89# 

90# elif request.method == "POST": 

91# processor = fc.processor(formdata=request.form, source=journal) 

92# if processor.validate(): 

93# try: 

94# processor.finalise() 

95# flash('Journal updated.', 'success') 

96# for a in processor.alert: 

97# flash_with_url(a, "success") 

98# return redirect(url_for("editor.journal_page", journal_id=journal.id, _anchor='done')) 

99# except Exception as e: 

100# flash(str(e)) 

101# return redirect(url_for("editor.journal_page", journal_id=journal.id, _anchor='cannot_edit')) 

102# else: 

103# return fc.render_template(lock=lockinfo, obj=journal, lcc_tree=lcc_jstree) 

104 

105@blueprint.route("/journal/readonly/<journal_id>", methods=["GET"]) 

106@login_required 

107@ssl_required 

108def journal_readonly(journal_id): 

109 j = models.Journal.pull(journal_id) 

110 if j is None: 

111 abort(404) 

112 

113 fc = JournalFormFactory.context("editor_readonly") 

114 fc.processor(source=j) 

115 return fc.render_template(obj=j, lcc_tree=lcc_jstree, notabs=True) 

116 

117 

118@blueprint.route("/application/<application_id>", methods=["GET", "POST"]) 

119@write_required() 

120@login_required 

121@ssl_required 

122def application(application_id): 

123 ap = models.Application.pull(application_id) 

124 

125 if ap is None: 

126 abort(404) 

127 

128 auth_svc = DOAJ.authorisationService() 

129 try: 

130 auth_svc.can_edit_application(current_user._get_current_object(), ap) 

131 except exceptions.AuthoriseException: 

132 abort(401) 

133 

134 try: 

135 lockinfo = lock.lock(constants.LOCK_APPLICATION, application_id, current_user.id) 

136 except lock.Locked as l: 

137 return render_template(templates.EDITOR_APPLICATION_LOCKED, application=ap, lock=l.lock) 

138 

139 form_diff, current_journal = ApplicationFormXWalk.update_request_diff(ap) 

140 

141 # Edit role is either associate_editor or editor, depending whether the user is group leader 

142 eg = models.EditorGroup.pull_by_key("name", ap.editor_group) 

143 role = 'editor' if eg is not None and eg.editor == current_user.id else 'associate_editor' 

144 fc = ApplicationFormFactory.context(role, extra_param=exparam_editing_user()) 

145 

146 if request.method == "GET": 

147 fc.processor(source=ap) 

148 return fc.render_template(obj=ap, lock=lockinfo, form_diff=form_diff, current_journal=current_journal, 

149 lcc_tree=lcc_jstree) 

150 

151 elif request.method == "POST": 

152 processor = fc.processor(formdata=request.form, source=ap) 

153 if processor.validate(): 

154 try: 

155 processor.finalise() 

156 flash('Application updated.', 'success') 

157 for a in processor.alert: 

158 flash_with_url(a, "success") 

159 return redirect(url_for("editor.application", application_id=ap.id, _anchor='done')) 

160 except Exception as e: 

161 flash(str(e)) 

162 return fc.render_template(obj=ap, lock=lockinfo, form_diff=form_diff, current_journal=current_journal, 

163 lcc_tree=lcc_jstree) 

164 else: 

165 return fc.render_template(obj=ap, lock=lockinfo, form_diff=form_diff, current_journal=current_journal, 

166 lcc_tree=lcc_jstree)