コード例 #1
0
ファイル: test_bll_getters.py プロジェクト: mauromsl/doaj
    def test_02_get_application(self, name, application, application_id, account, lock_application, raises=None):
        if lock_application:
            lock.lock(constants.LOCK_APPLICATION, application.id, "someoneelse", blocking=True)

        svc = DOAJ.applicationService()

        if application is not None:
            application.save(blocking=True)

        if raises is not None:
            with self.assertRaises(raises):
                if account is None:
                    retrieved, _ = svc.application(application_id)
                else:
                    retrieved, jlock = svc.application(application_id, lock_application=True, lock_account=account)
        else:
            if account is None:
                retrieved, _ = svc.application(application_id)
                if retrieved is not None:
                    assert retrieved.data == application.data
                else:
                    assert retrieved is None
            else:
                retrieved, jlock = svc.application(application_id, lock_application=True, lock_account=account)
                if retrieved is not None:
                    assert retrieved.data == application.data
                else:
                    assert retrieved is None

                time.sleep(2)

                assert lock.has_lock(constants.LOCK_APPLICATION, application_id, account.id)
コード例 #2
0
ファイル: test_bll_getters.py プロジェクト: mauromsl/doaj
    def test_01_get_journal(self, name, journal, journal_id, account, lock_journal, raises=None):

        if lock_journal:
            lock.lock("journal", journal.id, "someoneelse", blocking=True)

        svc = DOAJ.journalService()

        if journal is not None:
            journal.save(blocking=True)

        if raises is not None:
            with self.assertRaises(raises):
                if account is None:
                    retrieved, _ = svc.journal(journal_id)
                else:
                    retrieved, jlock = svc.journal(journal_id, lock_journal=True, lock_account=account)
        else:
            if account is None:
                retrieved, _ = svc.journal(journal_id)
                if retrieved is not None:
                    assert retrieved.data == journal.data
                else:
                    assert retrieved is None
            else:
                retrieved, jlock = svc.journal(journal_id, lock_journal=True, lock_account=account)
                if retrieved is not None:
                    assert retrieved.data == journal.data
                else:
                    assert retrieved is None

                time.sleep(2)

                assert lock.has_lock("journal", journal_id, account.id)
コード例 #3
0
ファイル: application.py プロジェクト: DOAJ/doaj
    def application(self, application_id, lock_application=False, lock_account=None, lock_timeout=None):
        """
        Function to retrieve an application by its id

        :param application_id: the id of the application
        :param: lock_application: should we lock the resource on retrieval
        :param: lock_account: which account is doing the locking?  Must be present if lock_journal=True
        :param: lock_timeout: how long to lock the resource for.  May be none, in which case it will default
        :return: Tuple of (Suggestion Object, Lock Object)
        """
        # first validate the incoming arguments to ensure that we've got the right thing
        argvalidate("application", [
            {"arg": application_id, "allow_none" : False, "arg_name" : "application_id"},
            {"arg": lock_application, "instance" : bool, "allow_none" : False, "arg_name" : "lock_journal"},
            {"arg": lock_account, "instance" : models.Account, "allow_none" : True, "arg_name" : "lock_account"},
            {"arg": lock_timeout, "instance" : int, "allow_none" : True, "arg_name" : "lock_timeout"}
        ], exceptions.ArgumentException)

        # pull the application from the database
        application = models.Suggestion.pull(application_id)

        # if we've retrieved the journal, and a lock is requested, request it
        the_lock = None
        if application is not None and lock_application:
            if lock_account is not None:
                the_lock = lock.lock(constants.LOCK_APPLICATION, application_id, lock_account.id, lock_timeout)
            else:
                raise exceptions.ArgumentException("If you specify lock_application on application retrieval, you must also provide lock_account")

        return application, the_lock
コード例 #4
0
ファイル: journal.py プロジェクト: katrinleinweber/doaj
    def journal(self, journal_id, lock_journal=False, lock_account=None, lock_timeout=None):
        """
        Function to retrieve a journal by its id, and to optionally lock the resource

        May raise a Locked exception, if a lock is requested but can't be obtained.

        :param journal_id: the id of the journal
        :param: lock_journal: should we lock the resource on retrieval
        :param: lock_account: which account is doing the locking?  Must be present if lock_journal=True
        :param: lock_timeout: how long to lock the resource for.  May be none, in which case it will default
        :return: Tuple of (Journal Object, Lock Object)
        """
        # first validate the incoming arguments to ensure that we've got the right thing
        argvalidate("journal", [
            {"arg": journal_id, "allow_none" : False, "arg_name" : "journal_id"},
            {"arg": lock_journal, "instance" : bool, "allow_none" : False, "arg_name" : "lock_journal"},
            {"arg": lock_account, "instance" : models.Account, "allow_none" : True, "arg_name" : "lock_account"},
            {"arg": lock_timeout, "instance" : int, "allow_none" : True, "arg_name" : "lock_timeout"}
        ], exceptions.ArgumentException)

        # retrieve the journal
        journal = models.Journal.pull(journal_id)

        # if we've retrieved the journal, and a lock is requested, request it
        the_lock = None
        if journal is not None and lock_journal:
            if lock_account is not None:
                the_lock = lock.lock("journal", journal_id, lock_account.id, lock_timeout)
            else:
                raise exceptions.ArgumentException("If you specify lock_journal on journal retrieval, you must also provide lock_account")

        return journal, the_lock
コード例 #5
0
ファイル: application.py プロジェクト: katrinleinweber/doaj
    def application(self,
                    application_id,
                    lock_application=False,
                    lock_account=None,
                    lock_timeout=None):
        """
        Function to retrieve an application by its id

        :param application_id: the id of the application
        :param: lock_application: should we lock the resource on retrieval
        :param: lock_account: which account is doing the locking?  Must be present if lock_journal=True
        :param: lock_timeout: how long to lock the resource for.  May be none, in which case it will default
        :return: Tuple of (Suggestion Object, Lock Object)
        """
        # first validate the incoming arguments to ensure that we've got the right thing
        argvalidate("application", [{
            "arg": application_id,
            "allow_none": False,
            "arg_name": "application_id"
        }, {
            "arg": lock_application,
            "instance": bool,
            "allow_none": False,
            "arg_name": "lock_journal"
        }, {
            "arg": lock_account,
            "instance": models.Account,
            "allow_none": True,
            "arg_name": "lock_account"
        }, {
            "arg": lock_timeout,
            "instance": int,
            "allow_none": True,
            "arg_name": "lock_timeout"
        }], exceptions.ArgumentException)

        # pull the application from the database
        application = models.Suggestion.pull(application_id)

        # if we've retrieved the journal, and a lock is requested, request it
        the_lock = None
        if application is not None and lock_application:
            if lock_account is not None:
                the_lock = lock.lock(constants.LOCK_APPLICATION,
                                     application_id, lock_account.id,
                                     lock_timeout)
            else:
                raise exceptions.ArgumentException(
                    "If you specify lock_application on application retrieval, you must also provide lock_account"
                )

        return application, the_lock
コード例 #6
0
    def test_04_timeout(self):
        source = JournalFixtureFactory.make_journal_source()
        j = models.Journal(**source)
        j.save()

        time.sleep(2)

        after = datetime.utcnow() + timedelta(seconds=2300)

        # set a lock with a longer timout
        l = lock.lock("journal", j.id, "testuser", 2400)

        assert dates.parse(l.expires) > after
コード例 #7
0
ファイル: test_lock.py プロジェクト: DOAJ/doaj
    def test_04_timeout(self):
        source = JournalFixtureFactory.make_journal_source()
        j = models.Journal(**source)
        j.save()

        time.sleep(2)

        after = datetime.utcnow() + timedelta(seconds=2300)

        # set a lock with a longer timout
        l = lock.lock("journal", j.id, "testuser", 2400)

        assert dates.parse(l.expires) > after
コード例 #8
0
ファイル: editor.py プロジェクト: DOAJ/doaj
def journal_page(journal_id):
    # user must have the role "edit_journal"
    if not current_user.has_role("edit_journal"):
        abort(401)

    # get the journal, so we can check our permissions against it
    j = models.Journal.pull(journal_id)
    if j is None:
        abort(404)

    # user must be either the "admin.editor" of the journal, or the editor of the "admin.editor_group"

    # is the user the currently assigned editor of the journal?
    passed = False
    if j.editor == current_user.id:
        passed = True

    # now check whether the user is the editor of the editor group
    role = "associate_editor"
    eg = models.EditorGroup.pull_by_key("name", j.editor_group)
    if eg is not None and eg.editor == current_user.id:
        passed = True
        role = "editor"

    # if the user wasn't the editor or the owner of the editor group, unauthorised
    if not passed:
        abort(401)

    # attempt to get a lock on the object
    try:
        lockinfo = lock.lock("journal", journal_id, current_user.id)
    except lock.Locked as l:
        return render_template("editor/journal_locked.html", journal=j, lock=l.lock, edit_journal_page=True)

    if request.method == "GET":
        fc = formcontext.JournalFormFactory.get_form_context(role=role, source=j)
        return fc.render_template(edit_journal_page=True, lock=lockinfo)
    elif request.method == "POST":
        fc = formcontext.JournalFormFactory.get_form_context(role=role, form_data=request.form, source=j)
        if fc.validate():
            try:
                fc.finalise()
                flash('Journal updated.', 'success')
                for a in fc.alert:
                    flash_with_url(a, "success")
                return redirect(url_for("editor.journal_page", journal_id=j.id, _anchor='done'))
            except formcontext.FormContextException as e:
                flash(e.message)
                return redirect(url_for("editor.journal_page", journal_id=j.id, _anchor='cannot_edit'))
        else:
            return fc.render_template(edit_journal_page=True, lock=lockinfo)
コード例 #9
0
ファイル: editor.py プロジェクト: mauromsl/doaj
def journal_page(journal_id):
    # user must have the role "edit_journal"
    if not current_user.has_role("edit_journal"):
        abort(401)

    # get the journal, so we can check our permissions against it
    j = models.Journal.pull(journal_id)
    if j is None:
        abort(404)

    # user must be either the "admin.editor" of the journal, or the editor of the "admin.editor_group"

    # is the user the currently assigned editor of the journal?
    passed = False
    if j.editor == current_user.id:
        passed = True

    # now check whether the user is the editor of the editor group
    role = "associate_editor"
    eg = models.EditorGroup.pull_by_key("name", j.editor_group)
    if eg is not None and eg.editor == current_user.id:
        passed = True
        role = "editor"

    # if the user wasn't the editor or the owner of the editor group, unauthorised
    if not passed:
        abort(401)

    # attempt to get a lock on the object
    try:
        lockinfo = lock.lock("journal", journal_id, current_user.id)
    except lock.Locked as l:
        return render_template("editor/journal_locked.html", journal=j, lock=l.lock, edit_journal_page=True)

    if request.method == "GET":
        fc = formcontext.JournalFormFactory.get_form_context(role=role, source=j)
        return fc.render_template(edit_journal_page=True, lock=lockinfo)
    elif request.method == "POST":
        fc = formcontext.JournalFormFactory.get_form_context(role=role, form_data=request.form, source=j)
        if fc.validate():
            try:
                fc.finalise()
                flash('Journal updated.', 'success')
                for a in fc.alert:
                    flash_with_url(a, "success")
                return redirect(url_for("editor.journal_page", journal_id=j.id, _anchor='done'))
            except formcontext.FormContextException as e:
                flash(str(e))
                return redirect(url_for("editor.journal_page", journal_id=j.id, _anchor='cannot_edit'))
        else:
            return fc.render_template(edit_journal_page=True, lock=lockinfo)
コード例 #10
0
ファイル: test_lock.py プロジェクト: DOAJ/doaj
    def test_03_batch_lock_unlock(self):
        source = JournalFixtureFactory.make_journal_source()
        ids = []

        # create a bunch of journals that we can play with
        j = models.Journal(**deepcopy(source))
        j.save()
        ids.append(j.id)

        j = models.Journal(**deepcopy(source))
        j.save()
        ids.append(j.id)

        j = models.Journal(**deepcopy(source))
        j.save()
        ids.append(j.id)

        j = models.Journal(**deepcopy(source))
        j.save()
        ids.append(j.id)

        j = models.Journal(**deepcopy(source))
        j.save()
        ids.append(j.id)

        time.sleep(2)

        ls = lock.batch_lock("journal", ids, "testuser")
        assert len(ls) == 5

        time.sleep(2)

        report = lock.batch_unlock("journal", ids, "testuser")
        assert len(report["success"]) == 5
        assert len(report["fail"]) == 0

        time.sleep(2)

        # now lock an individual record by a different user and check that no locks are set
        # in batch
        l = lock.lock("journal", ids[3], "otheruser")

        time.sleep(2)

        with self.assertRaises(lock.Locked):
            ls = lock.batch_lock("journal", ids, "testuser")

        for id in ids:
            assert lock.has_lock("journal", id, "testuser") is False
コード例 #11
0
    def test_03_batch_lock_unlock(self):
        source = JournalFixtureFactory.make_journal_source()
        ids = []

        # create a bunch of journals that we can play with
        j = models.Journal(**deepcopy(source))
        j.save()
        ids.append(j.id)

        j = models.Journal(**deepcopy(source))
        j.save()
        ids.append(j.id)

        j = models.Journal(**deepcopy(source))
        j.save()
        ids.append(j.id)

        j = models.Journal(**deepcopy(source))
        j.save()
        ids.append(j.id)

        j = models.Journal(**deepcopy(source))
        j.save()
        ids.append(j.id)

        time.sleep(2)

        ls = lock.batch_lock("journal", ids, "testuser")
        assert len(ls) == 5

        time.sleep(2)

        report = lock.batch_unlock("journal", ids, "testuser")
        assert len(report["success"]) == 5
        assert len(report["fail"]) == 0

        time.sleep(2)

        # now lock an individual record by a different user and check that no locks are set
        # in batch
        l = lock.lock("journal", ids[3], "otheruser")

        time.sleep(2)

        with self.assertRaises(lock.Locked):
            ls = lock.batch_lock("journal", ids, "testuser")

        for id in ids:
            assert lock.has_lock("journal", id, "testuser") is False
コード例 #12
0
    def test_01_lock_success_fail(self):
        source = JournalFixtureFactory.make_journal_source()
        j = models.Journal(**source)
        j.save()

        time.sleep(2)

        # first set a lock
        l = lock.lock("journal", j.id, "testuser")
        assert l.about == j.id
        assert l.type == "journal"
        assert l.username == "testuser"
        assert not l.is_expired()

        time.sleep(2)

        # now try and set the lock again for the same thing by the same user
        l2 = lock.lock("journal", j.id, "testuser")
        assert l2 is not None
        assert l2.id == l.id

        # now try and set the lock as another user
        with self.assertRaises(lock.Locked):
            l3 = lock.lock("journal", j.id, "otheruser")
コード例 #13
0
ファイル: test_lock.py プロジェクト: DOAJ/doaj
    def test_01_lock_success_fail(self):
        source = JournalFixtureFactory.make_journal_source()
        j = models.Journal(**source)
        j.save()

        time.sleep(2)

        # first set a lock
        l = lock.lock("journal", j.id, "testuser")
        assert l.about == j.id
        assert l.type == "journal"
        assert l.username == "testuser"
        assert not l.is_expired()

        time.sleep(2)

        # now try and set the lock again for the same thing by the same user
        l2 = lock.lock("journal", j.id, "testuser")
        assert l2 is not None
        assert l2.id == l.id

        # now try and set the lock as another user
        with self.assertRaises(lock.Locked):
            l3 = lock.lock("journal", j.id, "otheruser")
コード例 #14
0
ファイル: admin.py プロジェクト: mauromsl/doaj
def journal_page(journal_id):
    if not current_user.has_role("edit_journal"):
        abort(401)
    ap = models.Journal.pull(journal_id)
    if ap is None:
        abort(404)

    # attempt to get a lock on the object
    try:
        lockinfo = lock.lock("journal", journal_id, current_user.id)
    except lock.Locked as l:
        return render_template("admin/journal_locked.html",
                               journal=ap,
                               lock=l.lock,
                               edit_journal_page=True)

    if request.method == "GET":
        job = None
        job_id = request.values.get("job")
        if job_id is not None and job_id != "":
            job = models.BackgroundJob.pull(job_id)
        fc = formcontext.JournalFormFactory.get_form_context(role="admin",
                                                             source=ap)
        return fc.render_template(edit_journal_page=True,
                                  lock=lockinfo,
                                  job=job)
    elif request.method == "POST":
        fc = formcontext.JournalFormFactory.get_form_context(
            role="admin", form_data=request.form, source=ap)
        if fc.validate():
            try:
                fc.finalise()
                flash('Journal updated.', 'success')
                for a in fc.alert:
                    flash_with_url(a, "success")
                return redirect(
                    url_for("admin.journal_page",
                            journal_id=ap.id,
                            _anchor='done'))
            except formcontext.FormContextException as e:
                flash(str(e))
                return redirect(
                    url_for("admin.journal_page",
                            journal_id=ap.id,
                            _anchor='cannot_edit'))
        else:
            return fc.render_template(edit_journal_page=True, lock=lockinfo)
コード例 #15
0
ファイル: admin.py プロジェクト: mauromsl/doaj
def suggestion_page(suggestion_id):
    if not current_user.has_role("edit_suggestion"):
        abort(401)
    ap = models.Suggestion.pull(suggestion_id)
    if ap is None:
        abort(404)

    # attempt to get a lock on the object
    try:
        lockinfo = lock.lock("suggestion", suggestion_id, current_user.id)
    except lock.Locked as l:
        return render_template("admin/suggestion_locked.html",
                               suggestion=ap,
                               lock=l.lock,
                               edit_suggestion_page=True)

    if request.method == "GET":
        fc = formcontext.ApplicationFormFactory.get_form_context(role="admin",
                                                                 source=ap)
        return fc.render_template(edit_suggestion_page=True, lock=lockinfo)
    elif request.method == "POST":
        fc = formcontext.ApplicationFormFactory.get_form_context(
            role="admin", form_data=request.form, source=ap)
        if fc.validate():
            try:
                fc.finalise()
                flash('Application updated.', 'success')
                for a in fc.alert:
                    flash_with_url(a, "success")
                return redirect(
                    url_for("admin.suggestion_page",
                            suggestion_id=ap.id,
                            _anchor='done'))
            except formcontext.FormContextException as e:
                flash(str(e))
                return redirect(
                    url_for("admin.suggestion_page",
                            suggestion_id=ap.id,
                            _anchor='cannot_edit'))
        else:
            return fc.render_template(edit_suggestion_page=True, lock=lockinfo)
コード例 #16
0
ファイル: test_lock.py プロジェクト: DOAJ/doaj
    def test_02_unlock(self):
        unlocked = lock.unlock("journal", "qojoiwjreiqwefoijqwiefjw", "testuser")
        assert unlocked is True

        source = JournalFixtureFactory.make_journal_source()
        j = models.Journal(**source)
        j.save()

        time.sleep(2)

        # first set a lock
        l = lock.lock("journal", j.id, "testuser")

        time.sleep(2)

        # try and unlock as a different user
        unlocked = lock.unlock("journal", j.id, "otheruser")
        assert unlocked is False

        # now unlock for real
        unlocked = lock.unlock("journal", j.id, "testuser")
        assert unlocked is True
コード例 #17
0
    def test_02_unlock(self):
        unlocked = lock.unlock("journal", "qojoiwjreiqwefoijqwiefjw",
                               "testuser")
        assert unlocked is True

        source = JournalFixtureFactory.make_journal_source()
        j = models.Journal(**source)
        j.save()

        time.sleep(2)

        # first set a lock
        l = lock.lock("journal", j.id, "testuser")

        time.sleep(2)

        # try and unlock as a different user
        unlocked = lock.unlock("journal", j.id, "otheruser")
        assert unlocked is False

        # now unlock for real
        unlocked = lock.unlock("journal", j.id, "testuser")
        assert unlocked is True
コード例 #18
0
ファイル: journal.py プロジェクト: jbarnsby/doaj
def request_handler(request, journal_id, redirect_route="admin.journal_page", template="admin/journal.html", locked_template="admin/journal_locked.html",
                    activate_deactivate=False, group_editable=False, editors=None, editorial_available=False):
    # check our permissions
    if not current_user.has_role("edit_journal"):
        abort(401)
    j = get_journal(journal_id)
    if j is None:
        abort(404)

    # attempt to get a lock on the object
    try:
        lockinfo = lock.lock("journal", journal_id, current_user.id)
    except lock.Locked as l:
        return render_template(locked_template, journal=j, lock=l.lock, edit_journal_page=True)

    current_info = models.ObjectDict(JournalFormXWalk.obj2form(j))
    form = JournalForm(request.form, current_info)

    current_country = xwalk.get_country_code(j.bibjson().country)

    if current_country not in country_options_two_char_code_index:
        # couldn't find it, better warn the user to look for it
        # themselves
        country_help_text = "This journal's country has been recorded as \"{country}\". Please select it in the Country menu.".format(country=current_country)
    else:
        country_help_text = ''

    form.country.description = '<span class="red">' + country_help_text + '</span>'

    # add the contents of a few fields to their descriptions since select2 autocomplete
    # would otherwise obscure the full values
    if form.publisher.data:
        if not form.publisher.description:
            form.publisher.description = 'Full contents: ' + form.publisher.data
        else:
            form.publisher.description += '<br><br>Full contents: ' + form.publisher.data

    if form.society_institution.data:
        if not form.society_institution.description:
            form.society_institution.description = 'Full contents: ' + form.society_institution.data
        else:
            form.society_institution.description += '<br><br>Full contents: ' + form.society_institution.data

    if form.platform.data:
        if not form.platform.description:
            form.platform.description = 'Full contents: ' + form.platform.data
        else:
            form.platform.description += '<br><br>Full contents: ' + form.platform.data

    first_field_with_error = ''

    if editors is not None:
        form.editor.choices = [("", "Choose an editor")] + [(editor, editor) for editor in editors]
    else:
        if j.editor is not None:
            form.editor.choices = [(j.editor, j.editor)]
        else:
            form.editor.choices = [("", "")]

    if request.method == 'POST':
        if form.make_all_fields_optional.data:
            valid = True
        else:
            valid = form.validate()
        if valid:
            # even though you can only edit journals right now, keeping the same
            # method as editing suggestions (i.e. creating a new object
            # and editing its properties)

            email_editor = False
            if group_editable:
                email_editor = JournalFormXWalk.is_new_editor_group(form, j)

            email_associate = False
            if editorial_available:
                email_associate = JournalFormXWalk.is_new_editor(form, j)

            # do the core crosswalk
            journal = JournalFormXWalk.form2obj(form, existing_journal=j)

            # some of the properties (id, in_doaj, etc.) have to be carried over
            # otherwise they implicitly end up getting changed to their defaults
            # when a journal gets edited (e.g. it always gets taken out of DOAJ)
            # if we don't copy over the in_doaj attribute to the new journal object
            journal['id'] = j['id']
            created_date = j.created_date if j.created_date else datetime.now().strftime("%Y-%m-%dT%H:%M:%SZ")
            journal.set_created(created_date)
            journal.bibjson().active = j.is_in_doaj()
            journal.set_in_doaj(j.is_in_doaj())
            if ((journal.owner is None or journal.owner == "") and (j.owner is not None)) or not current_user.has_role("admin"):
                journal.set_owner(j.owner)

            if not group_editable or not editorial_available:
                journal.set_editor_group(j.editor_group)

            if not editorial_available:
                journal.set_editor(j.editor)

            # FIXME: probably should check that the editor is in the editor_group and remove if not

            journal.save()
            flash('Journal updated.', 'success')

            # only actually send the email when we've successfully processed the form
            if email_editor:
                send_editor_group_email(journal)

            if email_associate:
                send_editor_email(journal)

            return redirect(url_for(redirect_route, journal_id=journal_id, _anchor='done'))
                # meaningless anchor to replace #first_problem used on the form
                # anchors persist between 3xx redirects to the same resource
        else:
            for field in form:  # in order of definition of fields, so the order of rendering should be (manually) kept the same as the order of definition for this to work
                if field.errors:
                    first_field_with_error = field.short_name
                    break

    return render_template(
            template,
            form=form,
            first_field_with_error=first_field_with_error,
            q_numbers=xrange(1, 10000).__iter__(),  # a generator for the purpose of displaying numbered questions
            other_val=other_val,
            digital_archiving_policy_specific_library_value=digital_archiving_policy_specific_library_value,
            edit_journal_page=True,
            admin_page=True,
            journal=j,
            subjectstr=subjects2str(j.bibjson().subjects()),
            lcc_jstree=json.dumps(lcc_jstree),
            activate_deactivate=activate_deactivate,
            group_editable=group_editable,
            editorial_available=editorial_available,
            lock=lockinfo
    )
コード例 #19
0
def request_handler(request,
                    journal_id,
                    redirect_route="admin.journal_page",
                    template="admin/journal.html",
                    locked_template="admin/journal_locked.html",
                    activate_deactivate=False,
                    group_editable=False,
                    editors=None,
                    editorial_available=False):
    # check our permissions
    if not current_user.has_role("edit_journal"):
        abort(401)
    j = get_journal(journal_id)
    if j is None:
        abort(404)

    # attempt to get a lock on the object
    try:
        lockinfo = lock.lock("journal", journal_id, current_user.id)
    except lock.Locked as l:
        return render_template(locked_template,
                               journal=j,
                               lock=l.lock,
                               edit_journal_page=True)

    current_info = models.ObjectDict(JournalFormXWalk.obj2form(j))
    form = JournalForm(request.form, current_info)

    current_country = xwalk.get_country_code(j.bibjson().country)

    if current_country not in country_options_two_char_code_index:
        # couldn't find it, better warn the user to look for it
        # themselves
        country_help_text = "This journal's country has been recorded as \"{country}\". Please select it in the Country menu.".format(
            country=current_country)
    else:
        country_help_text = ''

    form.country.description = '<span class="red">' + country_help_text + '</span>'

    # add the contents of a few fields to their descriptions since select2 autocomplete
    # would otherwise obscure the full values
    if form.publisher.data:
        if not form.publisher.description:
            form.publisher.description = 'Full contents: ' + form.publisher.data
        else:
            form.publisher.description += '<br><br>Full contents: ' + form.publisher.data

    if form.society_institution.data:
        if not form.society_institution.description:
            form.society_institution.description = 'Full contents: ' + form.society_institution.data
        else:
            form.society_institution.description += '<br><br>Full contents: ' + form.society_institution.data

    if form.platform.data:
        if not form.platform.description:
            form.platform.description = 'Full contents: ' + form.platform.data
        else:
            form.platform.description += '<br><br>Full contents: ' + form.platform.data

    first_field_with_error = ''

    if editors is not None:
        form.editor.choices = [("", "Choose an editor")
                               ] + [(editor, editor) for editor in editors]
    else:
        if j.editor is not None:
            form.editor.choices = [(j.editor, j.editor)]
        else:
            form.editor.choices = [("", "")]

    if request.method == 'POST':
        if form.make_all_fields_optional.data:
            valid = True
        else:
            valid = form.validate()
        if valid:
            # even though you can only edit journals right now, keeping the same
            # method as editing suggestions (i.e. creating a new object
            # and editing its properties)

            email_editor = False
            if group_editable:
                email_editor = JournalFormXWalk.is_new_editor_group(form, j)

            email_associate = False
            if editorial_available:
                email_associate = JournalFormXWalk.is_new_editor(form, j)

            # do the core crosswalk
            journal = JournalFormXWalk.form2obj(form, existing_journal=j)

            # some of the properties (id, in_doaj, etc.) have to be carried over
            # otherwise they implicitly end up getting changed to their defaults
            # when a journal gets edited (e.g. it always gets taken out of DOAJ)
            # if we don't copy over the in_doaj attribute to the new journal object
            journal['id'] = j['id']
            created_date = j.created_date if j.created_date else datetime.now(
            ).strftime("%Y-%m-%dT%H:%M:%SZ")
            journal.set_created(created_date)
            journal.bibjson().active = j.is_in_doaj()
            journal.set_in_doaj(j.is_in_doaj())
            if ((journal.owner is None or journal.owner == "") and
                (j.owner is not None)) or not current_user.has_role("admin"):
                journal.set_owner(j.owner)

            if not group_editable or not editorial_available:
                journal.set_editor_group(j.editor_group)

            if not editorial_available:
                journal.set_editor(j.editor)

            # FIXME: probably should check that the editor is in the editor_group and remove if not

            journal.save()
            flash('Journal updated.', 'success')

            # only actually send the email when we've successfully processed the form
            if email_editor:
                send_editor_group_email(journal)

            if email_associate:
                send_editor_email(journal)

            return redirect(
                url_for(redirect_route, journal_id=journal_id, _anchor='done'))
            # meaningless anchor to replace #first_problem used on the form
            # anchors persist between 3xx redirects to the same resource
        else:
            for field in form:  # in order of definition of fields, so the order of rendering should be (manually) kept the same as the order of definition for this to work
                if field.errors:
                    first_field_with_error = field.short_name
                    break

    return render_template(
        template,
        form=form,
        first_field_with_error=first_field_with_error,
        q_numbers=xrange(1, 10000).__iter__(
        ),  # a generator for the purpose of displaying numbered questions
        other_val=other_val,
        digital_archiving_policy_specific_library_value=
        digital_archiving_policy_specific_library_value,
        edit_journal_page=True,
        admin_page=True,
        journal=j,
        subjectstr=subjects2str(j.bibjson().subjects()),
        lcc_jstree=json.dumps(lcc_jstree),
        activate_deactivate=activate_deactivate,
        group_editable=group_editable,
        editorial_available=editorial_available,
        lock=lockinfo)
コード例 #20
0
ファイル: application.py プロジェクト: DOAJ/doaj
    def update_request_for_journal(self, journal_id, account=None, lock_timeout=None):
        """
        Obtain an update request application object for the journal with the given journal_id

        An update request may either be loaded from the database, if it already exists, or created
        in-memory if it has not previously been created.

        If an account is provided, this will validate that the account holder is allowed to make
        the conversion from journal to application, if a conversion is required.

        When this request runs, the journal will be locked to the provided account if an account is
        given.  If the application is loaded from the database, this will also be locked for the account
        holder.

        :param journal_id:
        :param account:
        :return: a tuple of (Application Object, Journal Lock, Application Lock)
        """
        # first validate the incoming arguments to ensure that we've got the right thing
        argvalidate("update_request_for_journal", [
            {"arg": journal_id, "instance" : basestring, "allow_none" : False, "arg_name" : "journal_id"},
            {"arg" : account, "instance" : models.Account, "allow_none" : True, "arg_name" : "account"},
            {"arg" : lock_timeout, "instance" : int, "allow_none" : True, "arg_name" : "lock_timeout"}
        ], exceptions.ArgumentException)

        if app.logger.isEnabledFor("debug"): app.logger.debug("Entering update_request_for_journal")

        journalService = DOAJ.journalService()
        authService = DOAJ.authorisationService()

        # first retrieve the journal, and return empty if there isn't one.
        # We don't attempt to obtain a lock at this stage, as we want to check that the user is authorised first
        journal_lock = None
        journal, _ = journalService.journal(journal_id)
        if journal is None:
            app.logger.info("Request for journal {x} did not find anything in the database".format(x=journal_id))
            return None, None, None

        # if the journal is not in_doaj, we won't create an update request for it
        if not journal.is_in_doaj():
            app.logger.info("Request for journal {x} found it is not in_doaj; will not create update request".format(x=journal_id))
            return None, None, None

        # retrieve the latest application attached to this journal
        application_lock = None
        application = models.Suggestion.find_latest_by_current_journal(journal_id)

        # if no such application exists, create one in memory (this will check that the user is permitted to create one)
        # at the same time, create the lock for the journal.  This will throw an AuthorisedException or a Locked exception
        # (in that order of preference) if any problems arise.
        if application is None:
            app.logger.info("No existing update request for journal {x}; creating one".format(x=journal.id))
            application = journalService.journal_2_application(journal, account=account)
            lra_id = journal.latest_related_application_id()
            if lra_id is not None:
                lra, _ = self.application(lra_id)
                if lra is not None:
                    self.patch_application(application, lra)
            if account is not None:
                journal_lock = lock.lock("journal", journal_id, account.id)

        # otherwise check that the user (if given) has the rights to edit the application
        # then lock the application and journal to the account.
        # If a lock cannot be obtained, unlock the journal and application before we return
        elif account is not None:
            try:
                authService.can_edit_application(account, application)
                application_lock = lock.lock("suggestion", application.id, account.id)
                journal_lock = lock.lock("journal", journal_id, account.id)
            except lock.Locked as e:
                if application_lock is not None: application_lock.delete()
                if journal_lock is not None: journal_lock.delete()
                raise
            except exceptions.AuthoriseException as e:
                msg = "Account {x} is not permitted to edit the current update request on journal {y}".format(x=account.id, y=journal.id)
                app.logger.info(msg)
                e.message = msg
                raise

            app.logger.info("Using existing application {y} as update request for journal {x}".format(y=application.id, x=journal.id))

        if app.logger.isEnabledFor("debug"): app.logger.debug("Completed update_request_for_journal; return application object")

        return application, journal_lock, application_lock
コード例 #21
0
ファイル: application.py プロジェクト: DOAJ/doaj
    def delete_application(self, application_id, account):
        """
        Function to delete an application, and all references to it in other objects (current and related journals)

        The application and all related journals need to be locked before this process can proceed, so you may get a
        lock.Locked exception

        :param application_id:
        :param account:
        :return:
        """
        # first validate the incoming arguments to ensure that we've got the right thing
        argvalidate("delete_application", [
            {"arg": application_id, "instance" : unicode, "allow_none" : False, "arg_name" : "application_id"},
            {"arg" : account, "instance" : models.Account, "allow_none" : False, "arg_name" : "account"}
        ], exceptions.ArgumentException)

        journalService = DOAJ.journalService()
        authService = DOAJ.authorisationService()

        # get hold of a copy of the application.  If there isn't one, our work here is done
        # (note the application could be locked, in which case this will raise a lock.Locked exception)

        # get the application
        application, _ = self.application(application_id)
        if application is None:
            raise exceptions.NoSuchObjectException

        # determine if the user can edit the application
        authService.can_edit_application(account, application)

        # attempt to lock the record (this may raise a Locked exception)
        alock = lock.lock(constants.LOCK_APPLICATION, application_id, account.id)

        # obtain the current journal, with associated lock
        current_journal = None
        cjlock = None
        if application.current_journal is not None:
            try:
                current_journal, cjlock = journalService.journal(application.current_journal, lock_journal=True, lock_account=account)
            except lock.Locked as e:
                # if the resource is locked, we have to back out
                if alock is not None: alock.delete()
                raise

        # obtain the related journal, with associated lock
        related_journal = None
        rjlock = None
        if application.related_journal is not None:
            try:
                related_journal, rjlock = journalService.journal(application.related_journal, lock_journal=True, lock_account=account)
            except lock.Locked as e:
                # if the resource is locked, we have to back out
                if alock is not None: alock.delete()
                if cjlock is not None: cjlock.delete()
                raise

        try:
            if current_journal is not None:
                current_journal.remove_current_application()
                saved = current_journal.save()
                if saved is None:
                    raise exceptions.SaveException("Unable to save journal record")

            if related_journal is not None:
                relation_record = related_journal.related_application_record(application_id)
                if relation_record is None:
                    relation_record = {}
                related_journal.add_related_application(application_id, relation_record.get("date_accepted"), "deleted")
                saved = related_journal.save()
                if saved is None:
                    raise exceptions.SaveException("Unable to save journal record")

            application.delete()

        finally:
            if alock is not None: alock.delete()
            if cjlock is not None: cjlock.delete()
            if rjlock is not None: rjlock.delete()

        return
コード例 #22
0
    def test_01_delete_application(self, name, application_type, account_type,
                                   current_journal, related_journal, raises):

        ###############################################
        ## set up

        # create the test application (if needed), and the associated current_journal and related_journal in suitable states
        application = None
        cj = None
        rj = None
        if application_type == "found" or application_type == "locked":
            application = Suggestion(
                **ApplicationFixtureFactory.make_application_source())

            if current_journal == "none":
                application.remove_current_journal()
            elif current_journal == "not_found":
                application.set_current_journal("123456789987654321")
            elif current_journal == "found":
                cj = Journal(**JournalFixtureFactory.make_journal_source())
                cj.set_id(cj.makeid())
                cj.save(blocking=True)
                application.set_current_journal(cj.id)
            elif current_journal == "locked":
                cj = Journal(**JournalFixtureFactory.make_journal_source())
                cj.set_id(cj.makeid())
                cj.save(blocking=True)
                application.set_current_journal(cj.id)
                lock.lock(constants.LOCK_JOURNAL, cj.id, "otheruser")

            if related_journal == "none":
                application.remove_related_journal()
            elif related_journal == "not_found":
                application.set_related_journal("123456789987654321")
            elif related_journal == "found":
                rj = Journal(**JournalFixtureFactory.make_journal_source())
                rj.set_id(rj.makeid())
                rj.save(blocking=True)
                application.set_related_journal(rj.id)
            elif related_journal == "locked":
                rj = Journal(**JournalFixtureFactory.make_journal_source())
                rj.set_id(rj.makeid())
                rj.save(blocking=True)
                application.set_related_journal(rj.id)
                lock.lock(constants.LOCK_JOURNAL, rj.id, "otheruser")

        acc = None
        if account_type != "none":
            acc = Account(**AccountFixtureFactory.make_publisher_source())
            if account_type == "not_permitted":
                acc.remove_role("publisher")
            if application_type == "locked":
                thelock = lock.lock(constants.LOCK_APPLICATION, application.id,
                                    "otheruser")
                # we can't explicitly block on the lock, but we can halt until we confirm it is saved
                thelock.blockall([(thelock.id, thelock.last_updated)])

        application_id = None
        if application is not None:
            if acc is not None:
                application.set_owner(acc.id)
            application.save(blocking=True)
            application_id = application.id
        elif application_type == "not_found":
            application_id = "sdjfasofwefkwflkajdfasjd"

        ###########################################################
        # Execution

        svc = DOAJ.applicationService()
        if raises != "":
            with self.assertRaises(EXCEPTIONS[raises]):
                svc.delete_application(application_id, acc)
            time.sleep(1)
            check_locks(application, cj, rj, acc)
        else:
            svc.delete_application(application_id, acc)

            # we need to sleep, so the index catches up
            time.sleep(1)

            # check that no locks remain set for this user
            check_locks(application, cj, rj, acc)

            # check that the application actually is gone
            if application is not None:
                assert Suggestion.pull(application.id) is None

            # check that the current journal no longer has a reference to the application
            if cj is not None:
                cj = Journal.pull(cj.id)
                assert cj.current_application is None

            # check that the related journal has a record that the application was deleted
            if rj is not None:
                rj = Journal.pull(rj.id)
                record = rj.related_application_record(application.id)
                assert "status" in record
                assert record["status"] == "deleted"
コード例 #23
0
ファイル: application.py プロジェクト: katrinleinweber/doaj
    def delete_application(self, application_id, account):
        """
        Function to delete an application, and all references to it in other objects (current and related journals)

        The application and all related journals need to be locked before this process can proceed, so you may get a
        lock.Locked exception

        :param application_id:
        :param account:
        :return:
        """
        # first validate the incoming arguments to ensure that we've got the right thing
        argvalidate("delete_application", [{
            "arg": application_id,
            "instance": unicode,
            "allow_none": False,
            "arg_name": "application_id"
        }, {
            "arg": account,
            "instance": models.Account,
            "allow_none": False,
            "arg_name": "account"
        }], exceptions.ArgumentException)

        journalService = DOAJ.journalService()
        authService = DOAJ.authorisationService()

        # get hold of a copy of the application.  If there isn't one, our work here is done
        # (note the application could be locked, in which case this will raise a lock.Locked exception)

        # get the application
        application, _ = self.application(application_id)
        if application is None:
            raise exceptions.NoSuchObjectException

        # determine if the user can edit the application
        authService.can_edit_application(account, application)

        # attempt to lock the record (this may raise a Locked exception)
        alock = lock.lock(constants.LOCK_APPLICATION, application_id,
                          account.id)

        # obtain the current journal, with associated lock
        current_journal = None
        cjlock = None
        if application.current_journal is not None:
            try:
                current_journal, cjlock = journalService.journal(
                    application.current_journal,
                    lock_journal=True,
                    lock_account=account)
            except lock.Locked as e:
                # if the resource is locked, we have to back out
                if alock is not None: alock.delete()
                raise

        # obtain the related journal, with associated lock
        related_journal = None
        rjlock = None
        if application.related_journal is not None:
            try:
                related_journal, rjlock = journalService.journal(
                    application.related_journal,
                    lock_journal=True,
                    lock_account=account)
            except lock.Locked as e:
                # if the resource is locked, we have to back out
                if alock is not None: alock.delete()
                if cjlock is not None: cjlock.delete()
                raise

        try:
            if current_journal is not None:
                current_journal.remove_current_application()
                saved = current_journal.save()
                if saved is None:
                    raise exceptions.SaveException(
                        "Unable to save journal record")

            if related_journal is not None:
                relation_record = related_journal.related_application_record(
                    application_id)
                if relation_record is None:
                    relation_record = {}
                related_journal.add_related_application(
                    application_id, relation_record.get("date_accepted"),
                    "deleted")
                saved = related_journal.save()
                if saved is None:
                    raise exceptions.SaveException(
                        "Unable to save journal record")

            application.delete()

        finally:
            if alock is not None: alock.delete()
            if cjlock is not None: cjlock.delete()
            if rjlock is not None: rjlock.delete()

        return
コード例 #24
0
    def test_01_delete_application(self, name, application_type, account_type, current_journal, related_journal, raises):

        ###############################################
        ## set up

        # create the test application (if needed), and the associated current_journal and related_journal in suitable states
        application = None
        cj = None
        rj = None
        if application_type == "found" or application_type == "locked":
            application = Suggestion(**ApplicationFixtureFactory.make_application_source())

            if current_journal == "none":
                application.remove_current_journal()
            elif current_journal == "not_found":
                application.set_current_journal("123456789987654321")
            elif current_journal == "found":
                cj = Journal(**JournalFixtureFactory.make_journal_source())
                cj.set_id(cj.makeid())
                cj.save(blocking=True)
                application.set_current_journal(cj.id)
            elif current_journal == "locked":
                cj = Journal(**JournalFixtureFactory.make_journal_source())
                cj.set_id(cj.makeid())
                cj.save(blocking=True)
                application.set_current_journal(cj.id)
                lock.lock(constants.LOCK_JOURNAL, cj.id, "otheruser")

            if related_journal == "none":
                application.remove_related_journal()
            elif related_journal == "not_found":
                application.set_related_journal("123456789987654321")
            elif related_journal == "found":
                rj = Journal(**JournalFixtureFactory.make_journal_source())
                rj.set_id(rj.makeid())
                rj.save(blocking=True)
                application.set_related_journal(rj.id)
            elif related_journal == "locked":
                rj = Journal(**JournalFixtureFactory.make_journal_source())
                rj.set_id(rj.makeid())
                rj.save(blocking=True)
                application.set_related_journal(rj.id)
                lock.lock(constants.LOCK_JOURNAL, rj.id, "otheruser")


        acc = None
        if account_type != "none":
            acc = Account(**AccountFixtureFactory.make_publisher_source())
            if account_type == "not_permitted":
                acc.remove_role("publisher")
            if application_type == "locked":
                thelock = lock.lock(constants.LOCK_APPLICATION, application.id, "otheruser")
                # we can't explicitly block on the lock, but we can halt until we confirm it is saved
                thelock.blockall([(thelock.id, thelock.last_updated)])

        application_id = None
        if application is not None:
            if acc is not None:
                application.set_owner(acc.id)
            application.save(blocking=True)
            application_id = application.id
        elif application_type == "not_found":
            application_id = u"sdjfasofwefkwflkajdfasjd"

        ###########################################################
        # Execution

        svc = DOAJ.applicationService()
        if raises != "":
            with self.assertRaises(EXCEPTIONS[raises]):
                svc.delete_application(application_id, acc)
            time.sleep(1)
            check_locks(application, cj, rj, acc)
        else:
            svc.delete_application(application_id, acc)

            # we need to sleep, so the index catches up
            time.sleep(1)

            # check that no locks remain set for this user
            check_locks(application, cj, rj, acc)

            # check that the application actually is gone
            if application is not None:
                assert Suggestion.pull(application.id) is None

            # check that the current journal no longer has a reference to the application
            if cj is not None:
                cj = Journal.pull(cj.id)
                assert cj.current_application is None

            # check that the related journal has a record that the application was deleted
            if rj is not None:
                rj = Journal.pull(rj.id)
                record = rj.related_application_record(application.id)
                assert "status" in record
                assert record["status"] == "deleted"
コード例 #25
0
ファイル: application.py プロジェクト: katrinleinweber/doaj
    def update_request_for_journal(self,
                                   journal_id,
                                   account=None,
                                   lock_timeout=None):
        """
        Obtain an update request application object for the journal with the given journal_id

        An update request may either be loaded from the database, if it already exists, or created
        in-memory if it has not previously been created.

        If an account is provided, this will validate that the account holder is allowed to make
        the conversion from journal to application, if a conversion is required.

        When this request runs, the journal will be locked to the provided account if an account is
        given.  If the application is loaded from the database, this will also be locked for the account
        holder.

        :param journal_id:
        :param account:
        :return: a tuple of (Application Object, Journal Lock, Application Lock)
        """
        # first validate the incoming arguments to ensure that we've got the right thing
        argvalidate("update_request_for_journal", [{
            "arg": journal_id,
            "instance": basestring,
            "allow_none": False,
            "arg_name": "journal_id"
        }, {
            "arg": account,
            "instance": models.Account,
            "allow_none": True,
            "arg_name": "account"
        }, {
            "arg": lock_timeout,
            "instance": int,
            "allow_none": True,
            "arg_name": "lock_timeout"
        }], exceptions.ArgumentException)

        if app.logger.isEnabledFor("debug"):
            app.logger.debug("Entering update_request_for_journal")

        journalService = DOAJ.journalService()
        authService = DOAJ.authorisationService()

        # first retrieve the journal, and return empty if there isn't one.
        # We don't attempt to obtain a lock at this stage, as we want to check that the user is authorised first
        journal_lock = None
        journal, _ = journalService.journal(journal_id)
        if journal is None:
            app.logger.info(
                "Request for journal {x} did not find anything in the database"
                .format(x=journal_id))
            return None, None, None

        # if the journal is not in_doaj, we won't create an update request for it
        if not journal.is_in_doaj():
            app.logger.info(
                "Request for journal {x} found it is not in_doaj; will not create update request"
                .format(x=journal_id))
            return None, None, None

        # retrieve the latest application attached to this journal
        application_lock = None
        application = models.Suggestion.find_latest_by_current_journal(
            journal_id)

        # if no such application exists, create one in memory (this will check that the user is permitted to create one)
        # at the same time, create the lock for the journal.  This will throw an AuthorisedException or a Locked exception
        # (in that order of preference) if any problems arise.
        if application is None:
            app.logger.info(
                "No existing update request for journal {x}; creating one".
                format(x=journal.id))
            application = journalService.journal_2_application(journal,
                                                               account=account)
            lra_id = journal.latest_related_application_id()
            if lra_id is not None:
                lra, _ = self.application(lra_id)
                if lra is not None:
                    self.patch_application(application, lra)
            if account is not None:
                journal_lock = lock.lock("journal", journal_id, account.id)

        # otherwise check that the user (if given) has the rights to edit the application
        # then lock the application and journal to the account.
        # If a lock cannot be obtained, unlock the journal and application before we return
        elif account is not None:
            try:
                authService.can_edit_application(account, application)
                application_lock = lock.lock("suggestion", application.id,
                                             account.id)
                journal_lock = lock.lock("journal", journal_id, account.id)
            except lock.Locked as e:
                if application_lock is not None: application_lock.delete()
                if journal_lock is not None: journal_lock.delete()
                raise
            except exceptions.AuthoriseException as e:
                msg = "Account {x} is not permitted to edit the current update request on journal {y}".format(
                    x=account.id, y=journal.id)
                app.logger.info(msg)
                e.message = msg
                raise

            app.logger.info(
                "Using existing application {y} as update request for journal {x}"
                .format(y=application.id, x=journal.id))

        if app.logger.isEnabledFor("debug"):
            app.logger.debug(
                "Completed update_request_for_journal; return application object"
            )

        return application, journal_lock, application_lock
コード例 #26
0
    def test_01_update_request(self, name, journal_id, journal_lock, account,
                               account_role, account_is_owner,
                               current_applications, application_lock,
                               application_status, completed_applications,
                               raises, return_app, return_jlock, return_alock,
                               db_jlock, db_alock, db_app):

        ###############################################
        ## set up

        # create the journal
        journal = None
        jid = None
        if journal_id == "valid":
            journal = Journal(**JournalFixtureFactory.make_journal_source(
                in_doaj=True))
            journal.remove_related_applications()
            journal.remove_current_application()
            jid = journal.id
        elif journal_id == "not_in_doaj":
            journal = Journal(**JournalFixtureFactory.make_journal_source(
                in_doaj=False))
            journal.remove_related_applications()
            journal.remove_current_application()
            jid = journal.id
        elif journal_id == "missing":
            jid = uuid.uuid4().hex

        acc = None
        if account == "yes":
            acc = Account(**AccountFixtureFactory.make_publisher_source())
            if account_role == "none":
                acc.remove_role("publisher")
            elif account_role == "admin":
                acc.remove_role("publisher")
                acc.add_role("admin")
            acc.set_id(acc.makeid())
            if account_is_owner == "yes":
                acc.set_id(journal.owner)

        if journal_lock == "yes":
            lock.lock("journal", jid, "someoneelse", blocking=True)

        latest_app = None
        current_app_count = int(current_applications)
        for i in range(current_app_count):
            app = Suggestion(
                **ApplicationFixtureFactory.make_application_source())
            app.set_id(app.makeid())
            app.set_created("198" + str(i) + "-01-01T00:00:00Z")
            app.set_current_journal(jid)
            app.save()
            latest_app = app
            if journal is not None:
                journal.set_current_application(app.id)

        comp_app_count = int(completed_applications)
        for i in range(comp_app_count):
            app = Suggestion(
                **ApplicationFixtureFactory.make_application_source())
            app.set_id(app.makeid())
            app.set_created("197" + str(i) + "-01-01T00:00:00Z")
            app.set_related_journal(jid)
            app.save()
            if journal is not None:
                journal.add_related_application(app.id,
                                                date_accepted=app.created_date)

        if current_app_count == 0 and comp_app_count == 0:
            # save at least one record to initialise the index mapping, otherwise tests fail
            app = Suggestion(
                **ApplicationFixtureFactory.make_application_source())
            app.set_id(app.makeid())
            app.save()

        if application_lock == "yes":
            lock.lock("suggestion",
                      latest_app.id,
                      "someoneelse",
                      blocking=True)

        if application_status != "n/a":
            latest_app.set_application_status(application_status)
            latest_app.save(blocking=True)

        # finally save the journal record, ensuring we get a blocking save, so everything
        # above here should be synchronised with the repo
        if journal is not None:
            journal.save(blocking=True)

        ###########################################################
        # Execution

        svc = DOAJ.applicationService()
        if raises != "":
            with self.assertRaises(EXCEPTIONS[raises]):
                svc.update_request_for_journal(jid, acc)
        else:
            application, jlock, alock = svc.update_request_for_journal(
                jid, acc)

            # we need to sleep, so the index catches up
            time.sleep(1)

            if return_app == "none":
                assert application is None
            elif return_app == "yes":
                assert application is not None

            if return_jlock == "none":
                assert jlock is None
            elif return_jlock == "yes":
                assert jlock is not None

            if return_alock == "none":
                assert alock is None
            elif return_alock == "yes":
                assert alock is not None

            if db_jlock == "no" and acc is not None:
                assert not lock.has_lock("journal", jid, acc.id)
            elif db_jlock == "yes" and acc is not None:
                l = lock.has_lock("journal", jid, acc.id)
                assert lock.has_lock("journal", jid, acc.id)

            if db_alock == "no" and application.id is not None and acc is not None:
                assert not lock.has_lock("suggestion", application.id, acc.id)
            elif db_alock == "yes" and application.id is not None and acc is not None:
                assert lock.has_lock("suggestion", application.id, acc.id)

            if db_app == "no" and application.id is not None:
                indb = Suggestion.q2obj(q="id.exact:" + application.id)
                assert indb is None
            elif db_app == "yes" and application.id is not None:
                indb = Suggestion.q2obj(q="id.exact:" + application.id)
                assert indb is not None

            if current_app_count == 0 and comp_app_count == 0 and application is not None:
                assert application.article_metadata is None
                assert application.articles_last_year is None
            elif application is not None:
                assert application.article_metadata is not None
                assert application.articles_last_year is not None
コード例 #27
0
ファイル: suggestion.py プロジェクト: kelly-mcdougall/doaj
def request_handler(request, suggestion_id, redirect_route="admin.suggestion_page", template="admin/suggestion.html", locked_template="admin/suggestion_locked.html",
                    editors=None, group_editable=False, editorial_available=False, status_options="admin"):
    if not current_user.has_role("edit_suggestion"):
        abort(401)
    s = models.Suggestion.pull(suggestion_id)
    if s is None:
        abort(404)

    # attempt to get a lock on the object
    try:
        lockinfo = lock.lock("suggestion", suggestion_id, current_user.id)
    except lock.Locked as l:
        return render_template(locked_template, suggestion=s, lock=l.lock, edit_suggestion_page=True)

    current_info = models.ObjectDict(SuggestionFormXWalk.obj2form(s))
    form = EditSuggestionForm(request.form, current_info)

    if status_options == "admin":
        form.application_status.choices = forms.application_status_choices_admin
    else:
        form.application_status.choices = forms.application_status_choices_editor

    process_the_form = True
    if request.method == 'POST' and s.application_status == 'accepted':
        flash('You cannot edit applications which have been accepted into DOAJ.', 'error')
        process_the_form = False

    if form.application_status.data == "accepted" and form.make_all_fields_optional.data:
        flash("You cannot accept an application into the DOAJ without fully validating it", "error")
        process_the_form = False

    # add the contents of a few fields to their descriptions since select2 autocomplete
    # would otherwise obscure the full values
    if form.publisher.data:
        if not form.publisher.description:
            form.publisher.description = 'Full contents: ' + form.publisher.data
        else:
            form.publisher.description += '<br><br>Full contents: ' + form.publisher.data

    if form.society_institution.data:
        if not form.society_institution.description:
            form.society_institution.description = 'Full contents: ' + form.society_institution.data
        else:
            form.society_institution.description += '<br><br>Full contents: ' + form.society_institution.data

    if form.platform.data:
        if not form.platform.description:
            form.platform.description = 'Full contents: ' + form.platform.data
        else:
            form.platform.description += '<br><br>Full contents: ' + form.platform.data

    if editors is not None:
        form.editor.choices = [("", "Choose an editor")] + [(editor, editor) for editor in editors]
    else:
        if s.editor is not None:
            form.editor.choices = [(s.editor, s.editor)]
        else:
            form.editor.choices = [("", "")]

    return suggestion_form(form, request, template,
                           existing_suggestion=s,
                           suggestion=s,
                           process_the_form=process_the_form,
                           admin_page=True,
                           subjectstr=subjects2str(s.bibjson().subjects()),
                           lcc_jstree=json.dumps(lcc_jstree),
                           group_editable=group_editable,
                           editorial_available=editorial_available,
                           redirect_route=redirect_route,
                           lock=lockinfo
    )
コード例 #28
0
ファイル: test_bll_update_request.py プロジェクト: DOAJ/doaj
    def test_01_update_request(self, name, journal_id, journal_lock,
                               account, account_role, account_is_owner,
                               current_applications, application_lock, application_status,
                               completed_applications, raises,
                               return_app, return_jlock, return_alock,
                               db_jlock, db_alock, db_app):

        ###############################################
        ## set up

        # create the journal
        journal = None
        jid = None
        if journal_id == "valid":
            journal = Journal(**JournalFixtureFactory.make_journal_source(in_doaj=True))
            journal.remove_related_applications()
            journal.remove_current_application()
            jid = journal.id
        elif journal_id == "not_in_doaj":
            journal = Journal(**JournalFixtureFactory.make_journal_source(in_doaj=False))
            journal.remove_related_applications()
            journal.remove_current_application()
            jid = journal.id
        elif journal_id == "missing":
            jid = uuid.uuid4().hex

        acc = None
        if account == "yes":
            acc = Account(**AccountFixtureFactory.make_publisher_source())
            if account_role == "none":
                acc.remove_role("publisher")
            elif account_role == "admin":
                acc.remove_role("publisher")
                acc.add_role("admin")
            acc.set_id(acc.makeid())
            if account_is_owner == "yes":
                acc.set_id(journal.owner)

        if journal_lock == "yes":
            lock.lock("journal", jid, "someoneelse", blocking=True)

        latest_app = None
        current_app_count = int(current_applications)
        for i in range(current_app_count):
            app = Suggestion(**ApplicationFixtureFactory.make_application_source())
            app.set_id(app.makeid())
            app.set_created("198" + str(i) + "-01-01T00:00:00Z")
            app.set_current_journal(jid)
            app.save()
            latest_app = app
            if journal is not None:
                journal.set_current_application(app.id)

        comp_app_count = int(completed_applications)
        for i in range(comp_app_count):
            app = Suggestion(**ApplicationFixtureFactory.make_application_source())
            app.set_id(app.makeid())
            app.set_created("197" + str(i) + "-01-01T00:00:00Z")
            app.set_related_journal(jid)
            app.save()
            if journal is not None:
                journal.add_related_application(app.id, date_accepted=app.created_date)

        if current_app_count == 0 and comp_app_count == 0:
            # save at least one record to initialise the index mapping, otherwise tests fail
            app = Suggestion(**ApplicationFixtureFactory.make_application_source())
            app.set_id(app.makeid())
            app.save()

        if application_lock == "yes":
            lock.lock("suggestion", latest_app.id, "someoneelse", blocking=True)

        if application_status != "n/a":
            latest_app.set_application_status(application_status)
            latest_app.save(blocking=True)

        # finally save the journal record, ensuring we get a blocking save, so everything
        # above here should be synchronised with the repo
        if journal is not None:
            journal.save(blocking=True)

        ###########################################################
        # Execution

        svc = DOAJ.applicationService()
        if raises != "":
            with self.assertRaises(EXCEPTIONS[raises]):
                svc.update_request_for_journal(jid, acc)
        else:
            application, jlock, alock = svc.update_request_for_journal(jid, acc)

            # we need to sleep, so the index catches up
            time.sleep(1)

            if return_app == "none":
                assert application is None
            elif return_app == "yes":
                assert application is not None

            if return_jlock == "none":
                assert jlock is None
            elif return_jlock == "yes":
                assert jlock is not None

            if return_alock == "none":
                assert alock is None
            elif return_alock == "yes":
                assert alock is not None

            if db_jlock == "no" and acc is not None:
                assert not lock.has_lock("journal", jid, acc.id)
            elif db_jlock == "yes" and acc is not None:
                assert lock.has_lock("journal", jid, acc.id)

            if db_alock == "no" and application.id is not None and acc is not None:
                assert not lock.has_lock("suggestion", application.id, acc.id)
            elif db_alock == "yes" and application.id is not None and acc is not None:
                assert lock.has_lock("suggestion", application.id, acc.id)

            if db_app == "no" and application.id is not None:
                indb = Suggestion.q2obj(q="id.exact:" + application.id)
                assert indb is None
            elif db_app == "yes" and application.id is not None:
                indb = Suggestion.q2obj(q="id.exact:" + application.id)
                assert indb is not None

            if current_app_count == 0 and comp_app_count == 0 and application is not None:
                assert application.article_metadata is None
                assert application.articles_last_year is None
            elif application is not None:
                assert application.article_metadata is not None
                assert application.articles_last_year is not None