예제 #1
0
    def _cache_parsed_xml(self):
        """ Caches every Journal and Publisher found in the xml """
        if not self.parsed:
            return

        outcome = self.xml['header']['outcome'] is 'notFound'
        if outcome is 'notFound' or outcome is 'failed':
            return

        if self.xml['header']['outcome'] == 'singleJournal' \
            or self.xml['header']['outcome'] == 'uniqueZetoc':
            journal = self.xml['journals']['journal']
            cache.set("journal:" + journal['jtitle'].lower(), journal)

            if self.xml['header']['outcome'] != 'uniqueZetoc':
                # if the publisher has been indexed by RoMEO
                publisher = self.xml['publishers']['publisher']

                # Associate a Journal with a Publisher key in cache
                cache.set("journal-publisher:" + journal['jtitle'].lower(),
                          "publisher:" + publisher['name'].lower())
        elif self.xml['journals'] is not None:
            for journal in self.xml['journals']['journal']:
                cache.set("journal:" + journal['jtitle'].lower(), journal)

        if self.xml['header']['numhits'] == '1' \
            and self.xml['header']['outcome'] != 'uniqueZetoc':
            publisher = self.xml['publishers']['publisher']
            cache.set("publisher:" + publisher['name'].lower(), publisher)
        elif self.xml['publishers'] is not None:
            for publisher in self.xml['publishers']['publisher']:
                cache.set("publisher:" + publisher['name'].lower(), publisher)
예제 #2
0
    def set_single_item(self, journal=None, publisher=None):
        """
        Used to initialize the parser with items retrieved from cache

        Note: if both a journal and a publisher are defined
              the publisher is associated with the journal
        """
        self.xml = dict()
        self.xml['header'] = dict()
        self.xml['header']['outcome'] = ''
        if journal is not None:
            self.xml['journals'] = dict()
            self.xml['journals']['journal'] = journal
            self.xml['header']['numhits'] = '1'
            self.parsed = True
            self.single_item = True
            if publisher is not None:
                # Associate a Journal with a Publisher key in cache
                self.xml['header']['outcome'] = 'singleJournal'
                cache.set("journal-publisher:" + journal['jtitle'].lower(),
                          "publisher:" + publisher['name'].lower())
        elif publisher is not None:
            self.xml['header']['outcome'] = 'publisherFound'
            self.xml['header']['numhits'] = '1'
            self.xml['publishers'] = dict()
            self.xml['publishers']['publisher'] = publisher
            self.single_item = True
            self.parsed = True
예제 #3
0
def curate():
    """
    Index page with uploader and list of existing depositions
    """
    action = request.values.get('action')
    usercollection_id = request.values.get('collection')
    recid = request.values.get('recid', 0, type=int)

    # Allowed actions
    if action not in ['accept', 'reject', 'remove']:
        abort(400)

    # Check recid
    if not recid:
        abort(400)
    recid = int(recid)

    # Does collection exists
    u = UserCollection.query.filter_by(id=usercollection_id).first()
    if not u:
        abort(400)

    # Check permission to perform action on this record
    # - Accept and reject is done by community owner
    # - Remove  is done by record owner
    if action in ['accept', 'reject', ]:
        if u.id_user != current_user.get_id():
            abort(403)
    elif action == 'remove':
        try:
            email = get_fieldvalues(recid, '8560_f')[0]
            if email != current_user['email']:
                abort(403)
            # User not allowed to remove from the zenodo user collection
            if u.id == 'zenodo':
                abort(403)
        except (IndexError, KeyError):
            abort(403)

    # Prevent double requests (i.e. give bibupload a chance to make the change)
    key = "usercoll_curate:%s_%s" % (usercollection_id, recid)
    cache_action = cache.get(key)
    if cache_action == action or cache_action in ['reject', 'remove']:
        return jsonify({'status': 'success', 'cache': 1})
    elif cache_action:
        # Operation under way, but the same action
        return jsonify({'status': 'failure', 'cache': 1})

    if action == "accept":
        res = u.accept_record(recid)
    elif action == "reject" or action == "remove":
        res = u.reject_record(recid)

    if res:
        # Set 5 min cache to allow bibupload/webcoll to finish
        cache.set(key, action, timeout=5*60)
        return jsonify({'status': 'success', 'cache': 0})
    else:
        return jsonify({'status': 'failure', 'cache': 0})
예제 #4
0
 def save(self):
     """
     Saves modified data pernamently for logged users.
     """
     if not self.is_guest and self.modified:
         cache.set(self.get_key(),
                   dict(self.info),
                   timeout=CFG_WEBSESSION_EXPIRY_LIMIT_DEFAULT * 3600)
예제 #5
0
def preingest_form_data(user_id,
                        form_data,
                        uuid=None,
                        append=False,
                        cached_data=False):
    """Used to insert form data to the workflow before running it
    Creates an identical json structure to the draft json.
    If cached_data is enabled, the data will be used by the next workflow
    initiated by the user, so the uuid can be ommited in this case.

    @param user_id: the user id

    @param uuid: the id of the workflow

    @param form_data: a json with field_name -> value structure

    @param append: set to True if you want to append the values to the existing
                   ones

    @param cached_data: set to True if you want to cache the data.
    """
    def preingest_data(form_data, append):
        def preingest(json):
            if 'pop_obj' not in json:
                json['pop_obj'] = {}
            for field, value in form_data.items():
                if append:
                    try:
                        if isinstance(json['pop_obj'][field], list):
                            json['pop_obj'][field].append(value)
                        else:
                            new_values_list = [json['pop_obj'][field]]
                            new_values_list.append(value)
                            json['pop_obj'][field] = new_values_list
                    except KeyError:
                        json['pop_obj'][field] = [value]
                else:
                    json['pop_obj'][field] = value
            json['pop_obj']['timestamp'] = str(datetime.now())

        return preingest

    if cached_data:
        cache.set(str(user_id) + ':cached_form_data', form_data)
    else:
        Workflow.set_extra_data(user_id=user_id,
                                uuid=uuid,
                                setter=preingest_data(form_data, append))

        # Ingest the data in the forms, in case there are any
        if append:
            for field_name, value in form_data.items():
                draft_field_list_add(user_id, uuid, field_name, value)
        else:
            for field_name, value in form_data.items():
                draft_field_set(user_id, uuid, field_name, value)
예제 #6
0
    def parse_url(self, url):
        self.url = url
        #example
        #url = 'http://www.sherpa.ac.uk/romeo/api29.php?jtitle=Annals%20of%20Physics'

        found_journal = url.find("jtitle=")
        found_publisher = url.find("pub=")
        if found_journal != -1:
            self.search_type = "journal_search"
            self.query = url[found_journal + 7:(len(url) - 15)]
        elif found_publisher != -1:
            self.search_type = "publisher_search"
            found_publisher = url.find("pub=")
            self.query = url[found_publisher + 4:len(url)]
        else:
            self.search_type = "issn_search"
            found_publisher = url.find("issn=")
            self.query = url[found_publisher + 4:len(url)]

        cached_xml = cache.get(self.search_type + ":" + self.query.lower())
        if cached_xml is None:
            try:
                self.data = urllib2.urlopen(url).read()
            except urllib2.HTTPError:
                self.error = True
                return
            try:
                root = ElementTree.XML(self.data)
            except ParseError:
                self.error = True
                return
            self.xml = XmlDictConfig(root)
            outcome = self.xml['header']['outcome']
            if outcome != 'failed' and outcome != 'notFound':
                cache.set(self.search_type + ":" + self.query.lower(),
                          self.xml, 999999999999)
        else:
            self.xml = cached_xml
            #self.data = cached_xml
            #root = ElementTree.XML(self.data)
            #self.xml = XmlDictConfig(root)

        if self.xml['header']['outcome'] == 'failed':
            self.error = True
            self.error_message = self.xml['header']['message']
        self.parsed = True
        self._cache_parsed_xml()
예제 #7
0
class ZenodoExtension(Extension):
    """
    Temporary extension (let's see how long it will stay ;-).

    This extension is made until a pull-request has been integrated in the
    main Flask-Cache branch, so that generated cache keys are stable and
    predictable instead of based on filename and line numbers.
    """

    tags = set(['zenodocache'])

    def parse(self, parser):
        lineno = parser.stream.next().lineno

        # Parse timeout
        args = [parser.parse_expression()]

        # Parse fragment name
        parser.stream.skip_if('comma')
        args.append(parser.parse_expression())

        # Parse vary_on parameters
        vary_on = []
        while parser.stream.skip_if('comma'):
            vary_on.append(parser.parse_expression())

        if vary_on:
            args.append(nodes.List(vary_on))
        else:
            args.append(nodes.Const([]))

        body = parser.parse_statements(['name:endcache'], drop_needle=True)
        return nodes.CallBlock(self.call_method('_cache', args),
                               [], [], body).set_lineno(lineno)

    def _cache(self, timeout, fragment_name, vary_on,  caller):
        try:
            cache = getattr(self.environment, JINJA_CACHE_ATTR_NAME)
        except AttributeError, e:
            raise e

        key = make_template_fragment_key(fragment_name, vary_on=vary_on)

        # Delete key if timeout is 'del'
        if timeout == "del":
            cache.delete(key)
            return caller()

        rv = cache.get(key)
        if rv is None:
            rv = caller()
            cache.set(key, rv, timeout)
        return rv
예제 #8
0
    def _precache(self, info, force=False):
        """
        Calculate prermitions for user actions.

        FIXME: compatibility layer only !!!
        """
        # get autorization key
        acc_key = self.get_acc_key()
        acc = cache.get(acc_key)
        if not force and acc_key is not None and acc is not None:
            return acc

        #FIXME: acc_authorize_action should use flask request directly
        user_info = info
        user_info.update(self.req)

        from invenio.webuser import isUserSubmitter, isUserReferee, \
            isUserAdmin, isUserSuperAdmin
        from invenio.access_control_engine import acc_authorize_action
        from invenio.access_control_admin import acc_get_role_id, \
            acc_is_user_in_role
        from invenio.search_engine import get_permitted_restricted_collections

        data = {}
        data['precached_permitted_restricted_collections'] = \
            get_permitted_restricted_collections(user_info)
        data['precached_usebaskets'] = acc_authorize_action(
            user_info, 'usebaskets')[0] == 0
        data['precached_useloans'] = acc_authorize_action(
            user_info, 'useloans')[0] == 0
        data['precached_usegroups'] = acc_authorize_action(
            user_info, 'usegroups')[0] == 0
        data['precached_usealerts'] = acc_authorize_action(
            user_info, 'usealerts')[0] == 0
        data['precached_usemessages'] = acc_authorize_action(
            user_info, 'usemessages')[0] == 0
        data['precached_usestats'] = acc_authorize_action(
            user_info, 'runwebstatadmin')[0] == 0
        data['precached_viewsubmissions'] = isUserSubmitter(user_info)
        data['precached_useapprove'] = isUserReferee(user_info)
        data['precached_useadmin'] = isUserAdmin(user_info)
        data['precached_usesuperadmin'] = isUserSuperAdmin(user_info)
        data['precached_canseehiddenmarctags'] = acc_authorize_action(
            user_info, 'runbibedit')[0] == 0
        usepaperclaim = False
        usepaperattribution = False
        viewclaimlink = False

        if (CFG_BIBAUTHORID_ENABLED and acc_is_user_in_role(
                user_info, acc_get_role_id("paperclaimviewers"))):
            usepaperclaim = True

        if (CFG_BIBAUTHORID_ENABLED and acc_is_user_in_role(
                user_info, acc_get_role_id("paperattributionviewers"))):
            usepaperattribution = True

        viewlink = False
        try:
            viewlink = session['personinfo']['claim_in_process']
        except (KeyError, TypeError):
            pass

        if (CFG_BIBAUTHORID_ENABLED and usepaperattribution and viewlink):
            viewclaimlink = True


#                if (CFG_BIBAUTHORID_ENABLED
#                    and ((usepaperclaim or usepaperattribution)
#                         and acc_is_user_in_role(data, acc_get_role_id("paperattributionlinkviewers")))):
#                    viewclaimlink = True

        data['precached_viewclaimlink'] = viewclaimlink
        data['precached_usepaperclaim'] = usepaperclaim
        data['precached_usepaperattribution'] = usepaperattribution

        cache.set(acc_key,
                  data,
                  timeout=CFG_WEBSESSION_EXPIRY_LIMIT_DEFAULT * 3600)
        return data
예제 #9
0
def curate():
    """
    Index page with uploader and list of existing depositions
    """
    action = request.values.get('action')
    usercollection_id = request.values.get('collection')
    recid = request.values.get('recid', 0, type=int)

    # Allowed actions
    if action not in ['accept', 'reject', 'remove']:
        abort(400)

    # Check recid
    if not recid:
        abort(400)
    recid = int(recid)

    # Does collection exists
    u = UserCollection.query.filter_by(id=usercollection_id).first()
    if not u:
        abort(400)

    # Check permission to perform action on this record
    # - Accept and reject is done by community owner
    # - Remove  is done by record owner
    if action in [
            'accept',
            'reject',
    ]:
        if u.id_user != current_user.get_id():
            abort(403)
    elif action == 'remove':
        try:
            email = get_fieldvalues(recid, '8560_f')[0]
            if email != current_user['email']:
                abort(403)
            # User not allowed to remove from the zenodo user collection
            if u.id == 'zenodo':
                abort(403)
        except (IndexError, KeyError):
            abort(403)

    # Prevent double requests (i.e. give bibupload a chance to make the change)
    key = "usercoll_curate:%s_%s" % (usercollection_id, recid)
    cache_action = cache.get(key)
    if cache_action == action or cache_action in ['reject', 'remove']:
        return jsonify({'status': 'success', 'cache': 1})
    elif cache_action:
        # Operation under way, but the same action
        return jsonify({'status': 'failure', 'cache': 1})

    if action == "accept":
        res = u.accept_record(recid)
    elif action == "reject" or action == "remove":
        res = u.reject_record(recid)

    if res:
        # Set 5 min cache to allow bibupload/webcoll to finish
        cache.set(key, action, timeout=5 * 60)
        return jsonify({'status': 'success', 'cache': 0})
    else:
        return jsonify({'status': 'failure', 'cache': 0})
예제 #10
0
 def set(self, name, value, timeout=None):
     cache.set(CFG_CACHE_KEY_PREFIX_SESSION + name, value, timeout=3600)