def record_actions(recid=None, project_id=None, action_name='', action=None, msg='', redirect_url=None): uid = current_user.get_id() record = get_record(recid) if not record: abort(404) # either the use is allowed in the project # or is the owner if project_id: project = Project.query.get_or_404(project_id) if not project.is_user_allowed(): abort(401) else: if uid != int(record.get('owner', {}).get('id', -1)): abort(401) # crazy invenio stuff, cache actions so they dont get duplicated key = action_key(recid, action_name) cache_action = cache.get(key) if cache_action == action_name: return json_error(400, ' '.join([msg, 'Please wait some minutes.'])) # Set 5 min cache to allow bibupload/bibreformat to finish cache.set(key, action_name, timeout=5 * 60) r = action(record) if r is not None: return r if redirect_url is None: redirect_url = url_for('record.metadata', recid=recid) return jsonify({'status': 'ok', 'redirect': redirect_url})
def research(): cms_reclist = randomise(Collection.query.filter(Collection.name == 'CMS').first_or_404().reclist, 6) cms = [] for rec in cms_reclist: cms.append(get_record(rec)) print "here" alice_reclist = randomise(Collection.query.filter(Collection.name == 'ALICE').first_or_404().reclist, 6) alice = [] for rec in alice_reclist: alice.append(get_record(rec)) try: return render_template('research.html', cms = cms, alice = alice) except TemplateNotFound: return abort(404)
def tranfer_json(self): """Transfer the MARC data in xml format.""" json = str(get_record(self.recid).dumps()) file_writer = open("{0}.json".format( os.path.join(self.bagit_folder_path, self.name)), mode='w') file_writer.write(json) file_writer.close()
def openaire_upload_notification(recid): """ Send a notification to all user collections. """ ctx = { 'record': get_record(recid), } ucolls = Community.from_recid(recid, provisional=True) for c in ucolls: try: if c.owner.email: ctx.update({ 'community': c, }) content = render_template_to_string( "communities/new_upload_email.html", **ctx) send_email( CFG_SITE_SUPPORT_EMAIL, c.owner.email.encode('utf8'), "[%s] New upload to %s" % ( CFG_SITE_NAME, c.title.encode('utf8') ), content=content.encode('utf8') ) logger.info("Sent email for new record %s to %s." % (recid, c.owner.email.encode('utf8'))) except AttributeError: pass
def get(self, recid): from invenio.legacy.bibdocfile.api import BibRecDocs from invenio.legacy.search_engine import check_user_can_view_record record = get_record(recid) if not record: abort(404) auth_code, _ = check_user_can_view_record(current_user, recid) if auth_code: abort(401) ids = [recid] for k in ['rel_dataset', 'rel_software']: ids.extend([int(r) for r in record.get(k, [])]) files = [] for recid in ids: record_files = BibRecDocs(recid).list_latest_files( list_hidden=False) files.extend( map( lambda f: { 'id': f.docid, 'name': '%s%s' % (f.name, f.format), 'url': url_for('recordfileresource', recid=recid, fileid=f.docid), }, filter(lambda f: not f.is_icon(), record_files)) ) return files
def get(self, recid): from invenio.legacy.bibdocfile.api import BibRecDocs from invenio.legacy.search_engine import check_user_can_view_record record = get_record(recid) if not record: abort(404) auth_code, _ = check_user_can_view_record(current_user, recid) if auth_code: abort(401) ids = [recid] for k in ['rel_dataset', 'rel_software']: ids.extend([int(r) for r in record.get(k, [])]) files = [] for recid in ids: record_files = BibRecDocs(recid).list_latest_files( list_hidden=False) files.extend( map( lambda f: { 'id': f.docid, 'name': '%s%s' % (f.name, f.format), 'url': url_for( 'recordfileresource', recid=recid, fileid=f.docid), }, filter(lambda f: not f.is_icon(), record_files))) return files
def test_validate_xml_against_xsd(self): """ Validate generated DataCite XML for all public records """ from invenio.modules.search.models import Collection from invenio.modules.formatter import format_record from invenio.modules.records.api import get_record etree.clear_error_log() for recid in Collection.query.filter_by(name='zenodo').first().reclist: try: xml = None record = get_record(recid) for identifier in record.get('related_identifiers', []): if identifier['scheme'] != identifier['scheme'].lower(): raise Exception("Record %s has problem with upper-case scheme %s" % (recid, identifier['scheme'])) if record.get('doi', None): # v2.2 xml = StringIO(format_record(recid, 'dcite')) xml_doc = etree.parse(xml) self.schema.assertValid(xml_doc) # v3.0 xml = StringIO(format_record(recid, 'dcite3')) xml_doc = etree.parse(xml) self.schema3.assertValid(xml_doc) except Exception: if xml: print(xml.getvalue()) raise
def get_record(recid): """Directly the record object corresponding to the recid.""" import warnings warnings.warn('Deprecated get_record({}).'.format(str(recid)), stacklevel=2) from invenio.modules.records import api return api.get_record(recid).legacy_create_recstruct()
def _build_integrate_draft(project, selected_records): from lw_daap.modules.invenio_deposit.models \ import DepositionDraftCacheManager rel_dataset = [] rel_software = [] for recid in selected_records: r = get_record(recid) rec_info = { 'title': '%s (record id: %s)' % (r.get('title'), recid), 'identifier': recid, } if r.get('upload_type') == 'dataset': rel_dataset.append(rec_info) elif r.get('upload_type') == 'software': rel_software.append(rec_info) current_app.logger.debug(rel_dataset) current_app.logger.debug(rel_software) draft_cache = DepositionDraftCacheManager.get() draft_cache.data['project'] = project.id draft_cache.data['record_curated_in_project'] = True draft_cache.data['record_public_from_project'] = False draft_cache.data['rel_dataset'] = rel_dataset draft_cache.data['rel_software'] = rel_software draft_cache.save()
def rel_record_validator(form, field): from invenio.modules.records.api import get_record from lw_daap.modules.projects.models import Project from flask import current_app from flask_login import current_user for rel in field.data: current_app.logger.debug(field.data) current_app.logger.debug(rel) if rel.get('is_pid', None): return record = get_record(rel['identifier']) if not record: raise ValidationError("Invalid record id %s" % rel['identifier']) msg = "User does not have permission to access this record" if not record.get('communities'): current_app.logger.debug(record.get('communities')) if 'project' in record: p = Project.get_project(record['project']) if not p.is_user_allowed(): raise ValidationError(msg) else: if current_user.get_id() != record['owner']['id']: raise ValidationError(msg)
def tokenize_via_recjson(self, recID): """ Will tokenize with use of bibfield. @param recID: id of the record """ rec = get_record(recID) return [str(rec.get(self.nonmarc_tag) or 0)]
def record_id_process(form, field, submit=False): value = field.data or '' if value == "" or value.isspace(): return def is_number(s): try: float(s) return True except ValueError: return False if is_number(field.data): json_reader = get_record(value) else: field.add_message("Record id must be a number!", state='error') return if json_reader is not None: webdeposit_json = form.uncook_json(json_reader, {}, value) # FIXME: update current json, past self, what do you mean?? :S field.add_message('<a href="/record/"' + value + '>Record</a> was loaded successfully', state='info') form.process(MultiDict(webdeposit_json)) else: field.add_message("Record doesn't exist", state='info')
def metadata(recid, of='hd'): from invenio.legacy.bibrank.downloads_similarity import register_page_view_event from invenio.modules.formatter import get_output_format_content_type register_page_view_event(recid, current_user.get_id(), str(request.remote_addr)) if get_output_format_content_type(of) != 'text/html': from invenio.modules.search.views.search import response_formated_records return response_formated_records([recid], g.collection, of, qid=None) # Send the signal 'document viewed' record_viewed.send( current_app._get_current_object(), recid=recid, id_user=current_user.get_id(), request=request) def splitting(value, delimiter='/', maxsplit=0): return value.split(delimiter, maxsplit) def get_record_name(recid): tmp_rec = get_record(recid) if tmp_rec is None: return 'Can\'t link to record ( WRONG recid )' if 'title_additional' in tmp_rec : return tmp_rec.get('title_additional', '').get('title', '') elif tmp_rec.get('title',{}).get('title',''): return tmp_rec.get('title',{}).get('title','') def get_record_author_list(recid): tmp_rec = get_record(recid) if tmp_rec is None: return None return tmp_rec.get('authors','') current_app.jinja_env.filters['splitthem'] = splitting current_app.jinja_env.filters['get_record_name'] = get_record_name current_app.jinja_env.filters['get_record_author_list'] = get_record_author_list current_app.jinja_env.filters['get_download_time'] = calculate_download_time record_collection = get_record(recid)['collections'][0]['primary'] rec_col = Collection.query.filter(Collection.name == record_collection).first_or_404() parent_collection = rec_col.most_specific_dad if ( rec_col.most_specific_dad.id != 1 ) else None breadcrumbs = [{}] if parent_collection: breadcrumbs.append({ "url":".collection", "text": parent_collection.name_ln, "param":"name", "value": parent_collection.name }) breadcrumbs.append({"url":".collection", "text": rec_col.name_ln, "param":"name", "value":rec_col.name }) try: return render_template('records/base_base.html', breadcrumbs = breadcrumbs ) except TemplateNotFound: return abort(404) # FIX
def get_record_name(recid): tmp_rec = get_record(recid) if tmp_rec is None: return 'Can\'t link to record ( WRONG recid )' if 'title_additional' in tmp_rec : return tmp_rec.get('title_additional', '').get('title', '') elif tmp_rec.get('title',{}).get('title',''): return tmp_rec.get('title',{}).get('title','')
def collection(name): """ Render the collection page. It renders it either with a collection specific template (aka collection_{collection_name}.html) or with the default collection template (collection.html) """ from invenio.utils.text import slugify from invenio.modules.formatter import format_record from invenio.modules.search.forms import EasySearchForm from invenio.ext.template.context_processor import \ register_template_context_processor from flask.ext.breadcrumbs import current_breadcrumbs collection = Collection.query.filter(Collection.name == name).first() if collection == None: return render_template('404.html') parent_collection = collection.most_specific_dad \ if (collection.most_specific_dad and \ collection.most_specific_dad.id != 1) else None coll_reclist = collection.reclist coll_records = [] for rec in coll_reclist: coll_records.append(get_record(rec)) def splitting(value, delimiter='/'): return value.split(delimiter) current_app.jinja_env.filters['splitthem'] = splitting @register_template_context_processor def index_context(): breadcrumbs = current_breadcrumbs + collection.breadcrumbs(ln=g.ln)[1:] return dict( of=request.values.get('of', collection.formatoptions[0]['code']), format_record=format_record, easy_search_form=EasySearchForm(csrf_enabled=False), breadcrumbs=breadcrumbs) breadcrumbs = [{}] if parent_collection: breadcrumbs.append({ "url":".collection", "text": parent_collection.name_ln, "param":"name", "value": parent_collection.name }) exp = parent_collection.name_ln else: exp = collection.name_ln breadcrumbs.append({ "url":".collection", "text": collection.name_ln, "param":"name", "value": collection.name }) return render_template(['search/collection_{0}.html'.format(collection.id), 'search/collection_{0}.html'.format(slugify(name, '_')), 'search/collection.html'], collection=collection, coll_records=coll_records, breadcrumbs = breadcrumbs, exp = exp)
def _getter(field): if field.data: try: obj = get_record(int(field.data)) except ValueError: return field.data if obj: return "%s (record id: %s)" % (obj.get('title', None), field.data) return None
def send_reject_notification(request, message=None): """Receiver for request-rejected signal to send email notification.""" _send_notification( request.sender_email, _("Access request rejected"), "accessrequests/emails/rejected.tpl", request=request, record=get_record(request.recid), message=message, )
def get_record(recid): """Directly the record object corresponding to the recid.""" import warnings warnings.warn('Deprecated get_record({}).'.format(str(recid)), stacklevel=2) from invenio.modules.records import api try: return api.get_record(recid).legacy_create_recstruct() except AttributeError: return api.Record.create({'recid': recid}, 'json').legacy_create_recstruct()
def access_request(recid=None): """Create an access request.""" record = get_record(recid) # Record must be in restricted access mode. if record.get('access_right') != 'restricted' or \ not record.get('access_conditions'): abort(404) # Record must have an owner and owner must still exists. try: record_owner = User.query.get_or_404(record['owner']['id']) except KeyError: abort(404) sender = None initialdata = dict() # Prepare initial form data if current_user.is_authenticated(): sender = current_user initialdata = dict( # FIXME: add full_name attribute to user accounts. full_name=" ".join([sender["family_name"], sender["given_names"]]), email=sender["email"], ) # Normal form validation form = AccessRequestForm(formdata=request.form, **initialdata) if form.validate_on_submit(): accreq = AccessRequest.create( recid=recid, receiver=record_owner, sender_full_name=form.data['full_name'], sender_email=form.data['email'], justification=form.data['justification'], sender=sender ) if accreq.status == RequestStatus.EMAIL_VALIDATION: flash(_( "Email confirmation needed: We have sent you an email to " "verify your address. Please check the email and follow the " "instructions to complete the access request."), category='info') else: flash(_("Access request submitted."), category='info') return redirect(url_for("record.metadata", recid=recid)) return render_template( 'accessrequests/access_request.html', record=record, form=form, )
def _modify_record(self, recid, test_func, replace_func, include_func, append_colls=[], replace_colls=[]): """Generate record a MARCXML file. @param test_func: Function to test if a collection id should be changed @param replace_func: Function to replace the collection id. @param include_func: Function to test if collection should be included """ rec = get_record(recid).legacy_create_recstruct() newcolls = [] dirty = False try: colls = rec['980'] if replace_colls: for c in replace_colls: newcolls.append([('a', c)]) dirty = True else: for c in colls: try: # We are only interested in subfield 'a' code, val = c[0][0] if test_func(code, val): c[0][0] = replace_func(code, val) dirty = True if include_func(code, val): newcolls.append(c[0]) else: dirty = True except IndexError: pass for c in append_colls: newcolls.append([('a', c)]) dirty = True except KeyError: return False if not dirty: return False rec = {} record_add_field(rec, '001', controlfield_value=str(recid)) for subfields in newcolls: record_add_field(rec, '980', subfields=subfields) return rec
def get_record(recid): """Directly the record object corresponding to the recid.""" import warnings warnings.warn('Deprecated get_record({}).'.format(str(recid)), stacklevel=2) from invenio.modules.records import api try: return api.get_record(recid).legacy_create_recstruct() except AttributeError: return api.Record.create({ 'recid': recid }, 'json').legacy_create_recstruct()
def send_accept_notification(request, message=None, expires_at=None): """Receiver for request-accepted signal to send email notification.""" _send_notification( request.sender_email, _("Access request accepted"), "accessrequests/emails/accepted.tpl", request=request, record=get_record(request.recid), record_link=request.link.get_absolute_url('record.metadata'), message=message, expires_at=expires_at, )
def inputrecords_autocomplete_dataset(dummy_form, dummy_field, term, limit=50): from invenio.legacy.search_engine import search_pattern_parenthesised from invenio.modules.records.models import Record from invenio.modules.records.api import get_record if not term: objs = Record.query.limit(limit).all() else: # datasets from projects w/ curate = True recids = search_pattern_parenthesised( # p='title:%%%s%% AND 980__:dataset AND (980__:community-* OR # (8560_w:%s AND (NOT 980__:project-* OR 983__a:True)))' % # (term.encode('utf-8'), current_user.get_id())) p=('title:%%%s%% AND 980__:dataset AND' ' (980__:community-* OR 8560_w:%s)') % (term.encode('utf-8'), current_user.get_id())) objs = Record.query.filter( Record.id.in_(recids) ).filter_by().limit(limit).all() if not objs: if re.match(DOISyntaxValidator.pattern, term, re.I): return [{ 'value': "%s (doi)" % term, 'fields': { 'identifier': term, 'title': "%s (doi)" % term, 'is_pid': True } }] if re.match("lifewatch.openscience.\d+", term, re.I): return [{ 'value': "%s (pid)" % term, 'fields': { 'identifier': term, 'title': "%s (pid)" % term, 'is_pid': True } }] return map( lambda o: { 'value': "%s (record id: %s)" % (o[1]['title'], o[0]), 'fields': { 'identifier': o[0], 'title': "%s (record id: %s)" % (o[1]['title'], o[0]), } }, filter(lambda o: (o[1].get('project', None) == None or o[1].get('record_curated_in_project', False)), map(lambda o: (o.id, get_record(o.id)), objs) ) )
def receive_after_insert(mapper, connection, target): """Check 'after_insert' signal for Tags.""" from invenio.modules.records.api import get_record record = get_record(target.id_bibrec) if 'files' in record: for rec in record['files']: if 'full_path' in rec and target.tag.name in \ cfg['CLOUDCONNECTOR_SERVICE_NAME_MAPPING']: # FIXME make the upload asynchronous upload(target.tag.name, rec['full_path'], cfg['CLOUDCONNECTOR_UPLOAD_FOLDER'] + '/' + rec['full_path'])
def _merge_record(obj, eng): d = Deposition(obj) sip = d.get_latest_sip(sealed=False) # Get the current record, which contains all fields. current_record = get_record( sip.metadata.get('recid'), reset_cache=True ) form_class = d.get_draft(draft_id).form_class # Create a simplified record from the current record, that only # contains fields concerning this deposition. current_simple_record = deposition_record( current_record, [form_class], pre_process_load=pre_process_load, post_process_load=post_process_load, process_export=partial(process_export, d), ) # Create a simplified record from the changes the user have made. changed_simple_record = make_record(sip.metadata, is_dump=True) # Make an initial patch of current record (e.g. some default values set # by the form, might not exists in the current record) for k in current_simple_record: if k not in current_record: current_record[k] = current_simple_record[k] # Export clean dumps current_simple_json = current_simple_record.dumps(clean=True) changed_simple_json = changed_simple_record.dumps(clean=True) current_full_json = current_record.dumps(clean=True) # Merge changes from changed record into the current record. sip.metadata = merge_func( d, current_full_json, current_simple_json, changed_simple_json, ) # Ensure we are based on latest version_id to prevent being rejected in # the bibupload queue. hst_record = HstRECORD.query.filter_by( id_bibrec=sip.metadata.get('recid') ).order_by(HstRECORD.job_date.desc()).first() sip.metadata['modification_date'] = hst_record.job_date.isoformat() d.update()
def _collect_recjson(self, recIDs, termslist): """ Collects terms from recjson with use of bibfield. Used together with recjson tokenizer. """ tokenizing_function = self.tokenizing_function for recID in recIDs: record = get_record(recID) if record: new_words = tokenizing_function(record) if not recID in termslist: termslist[recID] = [] termslist[recID] = list_union(new_words, termslist[recID]) return termslist
def _add_record_variables(): from invenio.legacy.bibdocfile.api import BibRecDocs from invenio.modules.records.api import get_record ctx = dict( daap_files=[f for f in BibRecDocs( kwargs['recid'], human_readable=True ).list_latest_files( list_hidden=False ) if not f.is_icon()], # this updates the DB, but avoids ugly caching daap_record=get_record(kwargs['recid'], True) ) return ctx
def receive_after_insert(mapper, connection, target): """Check 'after_insert' signal for Tags.""" from invenio.modules.records.api import get_record record = get_record(target.id_bibrec) if 'files' in record: for rec in record['files']: if 'full_path' in rec and target.tag.name in \ cfg['CLOUDCONNECTOR_SERVICE_NAME_MAPPING']: # FIXME make the upload asynchronous upload( target.tag.name, rec['full_path'], cfg['CLOUDCONNECTOR_UPLOAD_FOLDER'] + '/' + rec['full_path'])
def tokenize_via_recjson(self, recID): """ Tokenizes for journal info. Uses bibfield. """ phrases = [] rec = get_record(recID) recjson_field = rec.get(self.nonmarc_tag) get_values_recursively(recjson_field, phrases) final = [] append = final.append for phrase in phrases: info = phrase.split("-", 1) append(info[0]) return final
def doi_consistency_check(): """Check if all DOIs in records have been registered.""" from invenio.base.globals import cfg from invenio.modules.records.api import get_record from invenio.legacy.search_engine import perform_request_search from invenio.modules.pidstore.models import PersistentIdentifier from invenio.modules.pidstore.tasks import datacite_register result = perform_request_search(p="") for r in result: doi = get_record(r).get('doi') if doi and doi.startswith(cfg['CFG_DATACITE_DOI_PREFIX']): pid = PersistentIdentifier.get("doi", doi) if pid and pid.is_new(): if pid.has_object("rec", r): datacite_register.delay(r)
def get_unique_record_json(param): """API to query records from the database.""" from invenio.modules.search.api import Query data, query = {}, {} data['status'] = 'notfound' recid = Query(param).search() if len(recid) == 1: query = get_record(recid[0]).dumps(clean=True) data['status'] = 'success' elif len(recid) > 1: data['status'] = 'multiplefound' data['source'] = 'database' data['query'] = query return data
def is_minted(self, sealed=True): """ Determine if deposition has a minted pid """ if self.has_sip(sealed): sip = self.get_latest_sip(sealed=sealed) recid = sip.metadata.get('recid', None) if recid is not None: from invenio.modules.records.api import get_record try: record = get_record(recid, True) if record: return record.get('doi', None) is not None except Exception: pass return False
def calculate_preservation_score(recid): """Calculate the preservation score of a given record.""" r = get_record(recid) files = r[current_app.config['PRESERVATIONMETER_FILES_FIELD']] score = calculate_score( [(f['full_name'], f['path']) for f in files] ) marcxml = """<record> <controlfield tag="001">{0}</controlfield> <datafield tag="347" ind1="" ind2=""> <subfield code="p">{1}</subfield> </datafield> </record> """.format(recid, score) bibupload_record(marcxml)
def create_secret_link(request, message=None, expires_at=None): """Receiver for request-accepted signal.""" record = get_record(request.recid) if not record: raise RecordNotFound(request.recid) description = render_template( "accessrequests/link_description.tpl", request=request, record=record, expires_at=expires_at, message=message, ) request.create_secret_link(record["title"], description=description, expires_at=expires_at)