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

120 statements  

« prev     ^ index     » next       coverage.py v6.4.2, created at 2022-07-22 15:59 +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 

17 

18blueprint = Blueprint('editor', __name__) 

19 

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

21@blueprint.before_request 

22def restrict(): 

23 return restrict_to_role('editor_area') 

24 

25# build an editor's page where things can be done 

26@blueprint.route('/') 

27@login_required 

28@ssl_required 

29def index(): 

30 editor_of = models.EditorGroup.groups_by_editor(current_user.id) 

31 associate_of = models.EditorGroup.groups_by_associate(current_user.id) 

32 return render_template('editor/index.html', editor_of=editor_of, associate_of=associate_of, managing_editor=app.config.get("MANAGING_EDITOR_EMAIL")) 

33 

34@blueprint.route('/group_journals') 

35@login_required 

36@ssl_required 

37def group_journals(): 

38 return render_template("editor/group_journals.html") 

39 

40@blueprint.route('/group_applications') 

41@login_required 

42@ssl_required 

43def group_suggestions(): 

44 return render_template("editor/group_applications.html") 

45 

46@blueprint.route('/your_journals') 

47@login_required 

48@ssl_required 

49def associate_journals(): 

50 return render_template("editor/associate_journals.html") 

51 

52@blueprint.route('/your_applications') 

53@login_required 

54@ssl_required 

55def associate_suggestions(): 

56 return render_template("editor/associate_applications.html") 

57 

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

59@login_required 

60@ssl_required 

61@write_required() 

62def journal_page(journal_id): 

63 auth_svc = DOAJ.authorisationService() 

64 journal_svc = DOAJ.journalService() 

65 

66 journal, _ = journal_svc.journal(journal_id) 

67 if journal is None: 

68 abort(404) 

69 

70 try: 

71 auth_svc.can_edit_journal(current_user._get_current_object(), journal) 

72 except exceptions.AuthoriseException: 

73 abort(401) 

74 

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

76 role = "associate_editor" 

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

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

79 role = "editor" 

80 

81 # attempt to get a lock on the object 

82 try: 

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

84 except lock.Locked as l: 

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

86 

87 fc = JournalFormFactory.context(role) 

88 

89 if request.method == "GET": 

90 fc.processor(source=journal) 

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

92 

93 elif request.method == "POST": 

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

95 if processor.validate(): 

96 try: 

97 processor.finalise() 

98 flash('Journal updated.', 'success') 

99 for a in processor.alert: 

100 flash_with_url(a, "success") 

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

102 except Exception as e: 

103 flash(str(e)) 

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

105 else: 

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

107 

108 

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

110@write_required() 

111@login_required 

112@ssl_required 

113def application(application_id): 

114 ap = models.Application.pull(application_id) 

115 

116 if ap is None: 

117 abort(404) 

118 

119 auth_svc = DOAJ.authorisationService() 

120 try: 

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

122 except exceptions.AuthoriseException: 

123 abort(401) 

124 

125 try: 

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

127 except lock.Locked as l: 

128 return render_template("editor/application_locked.html", application=ap, lock=l.lock) 

129 

130 form_diff, current_journal = ApplicationFormXWalk.update_request_diff(ap) 

131 

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

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

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

135 fc = ApplicationFormFactory.context(role) 

136 

137 if request.method == "GET": 

138 fc.processor(source=ap) 

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

140 lcc_tree=lcc_jstree) 

141 

142 elif request.method == "POST": 

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

144 if processor.validate(): 

145 try: 

146 processor.finalise() 

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

148 for a in processor.alert: 

149 flash_with_url(a, "success") 

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

151 except Exception as e: 

152 flash(str(e)) 

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

154 lcc_tree=lcc_jstree) 

155 else: 

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

157 lcc_tree=lcc_jstree)