def get_publishers(
        self,
        attribute=None,
        journal=None,
    ):
        """ Returns a list of the publishers if a publisher search was made or
        an empty list.

        If a journal is defined, it returns the associated publisher
        for this Journal or None. A journal definition makes the functions
        to query again if the publisher isn't found in the xml or cache.
        Note: If you define a journal, you must have searched for it first.

        If an attribute is defined, returns only this attribute from
        every publisher
        """

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

        if self.xml['header']['outcome'] == 'singleJournal':
            return self.xml['publishers']['publisher']

        if self.xml['header']['outcome'] == 'uniqueZetoc':
            # the Publisher has not yet been indexed by RoMEO
            return None

        if journal is not None:
            #  search the cache for matches
            publisher_key = cache.get("journal-publisher:" + journal.lower())
            if publisher_key is not None:
                return cache.get(publisher_key)

            # Query again sherpa romeo db to get the publisher
            s = SherpaRomeoSearch()
            issn = self.get_journals(attribute='issn')[0]
            if issn is not None:
                s.search_issn(issn)
                return s.parser.get_publishers()
            else:
                return None

        publishers = list()
        if self.xml['header']['outcome'] == 'publisherFound':
            if self.xml['header']['numhits'] == '1':
                p = self.xml['publishers']['publisher']
                if attribute is None:
                    publishers.append(p)
                else:
                    if p[attribute] is None:
                        return []
                    publishers.append(p[attribute])
            else:
                for p in self.xml['publishers']['publisher']:
                    if attribute is None:
                        publishers.append(p)
                    else:
                        publishers.append(p[attribute])
        return publishers
    def _runtime_vars_init(self):
        """ Initializes user_id, deposition type, uuid and form_type
        """

        self.user_id = current_user.get_id()

        if self.deposition_type is None:

            self.runtime_deposition_type = cache.get(
                str(self.user_id) + ":current_deposition_type")
        else:
            self.runtime_deposition_type = None

            #  The uuid is always defined on runtime
        self.uuid = cache.get(str(self.user_id) + ":current_uuid")

        if self.uuid is not None and self.form_type is None:
            webdeposit_draft_query = \
                db.session.query(WebDepositDraft).\
                join(Workflow).\
                filter(Workflow.user_id == self.user_id,
                       WebDepositDraft.uuid == self.uuid)
            # get the draft with the max step
            webdeposit_draft = max(webdeposit_draft_query.all(),
                                   key=lambda w: w.step)

            self.runtime_form_type = webdeposit_draft.form_type
        else:
            self.runtime_form_type = None
    def _login(self, uid, force=False):
        """
        Get account information about currently logged user from database.

        Should raise an exception when session.uid is not valid User.id.
        """
        data = cache.get(self.get_key())
        if not force and data is not None:
            return data

        from invenio.websession_model import User
        data = {}

        try:
            user = User.query.get(uid)
            data['id'] = data['uid'] = user.id or -1
            data['nickname'] = user.nickname or ''
            data['email'] = user.email or ''
            data['note'] = user.note or ''
            data.update(user.settings or {})
            data['settings'] = user.settings or {}
            data['guest'] = str(int(user.guest))  # '1' or '0'
            self.modified = True
        except:
            data = self._create_guest()

        return data
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})
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
    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()
    def search_publisher(self, query):
        """
        Search for Publishers
        query: the query to be made

        returns a list with publisher names
        """

        # Search first for exact matches in cache
        cached_publisher = cache.get("publisher:" + query.lower())
        if cached_publisher is not None:
            self.parser.set_single_item(publisher=cached_publisher, )
            return cached_publisher['name']

        cleanquery = query.replace(" ", "+")
        url = "http://www.sherpa.ac.uk/romeo/api29.php?pub=" + cleanquery
        self.parser.parse_url(url)
        self.error = self.parser.error
        self.error_message = self.parser.error_message
        if not self.error:
            return self.parser.get_publishers(attribute='name')
def get_preingested_form_data(user_id, uuid=None, key=None, cached_data=False):
    def get_preingested_data(key):
        def getter(json):
            if 'pop_obj' in json:
                if key is None:
                    return json['pop_obj']
                else:
                    return json['pop_obj'][key]
            else:
                return {}

        return getter

    if cached_data:
        return cache.get(str(user_id) + ':cached_form_data')
    try:
        return Workflow.get_extra_data(user_id,
                                       uuid=uuid,
                                       getter=get_preingested_data(key))
    except NoResultFound:
        return None
    def search_journal(self, query, query_type='contains'):
        """
        Search for Journals
        query: the query to be made
        query_type: it must be 'contains'(default), 'exact' or 'start'

        returns a list with the specific journal titles or empty list
        """

        if query_type is 'exact':
            # Search first for exact matches in cache
            cached_journal = cache.get("journal:" + query.lower())
            if cached_journal is not None:
                self.parser.set_single_item(journal=cached_journal)
                return cached_journal['jtitle']

        cleanquery = query.replace(" ", "+")
        url = "http://www.sherpa.ac.uk/romeo/api29.php?jtitle=" + cleanquery + "&qtype=" + query_type
        self.parser.parse_url(url)
        self.error = self.parser.error
        self.error_message = self.parser.error_message
        if not self.error:
            return self.parser.get_journals(attribute='jtitle')
    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
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})
 def get(self, name):
     return cache.get(CFG_CACHE_KEY_PREFIX_SESSION + name)
 def curation_action(recid, ucoll_id=None):
     """
     Determine if curation action is underway
     """
     return cache.get("usercoll_curate:%s_%s" % (ucoll_id, recid))