def resolve_funder(doi_code): """Resolve the JsonRef funder.""" pid_value = "10.13039/{0}".format(doi_code) _, record = Resolver(pid_type='frdoi', object_type='rec', getter=Record.get_record).resolve(pid_value) return record
def run(self, event): """Process the circulation event. This method builds the frame, fetching the item and calling *_run* in a nested transaction. """ resolver = Resolver(pid_type='crcitm', object_type='rec', getter=Item.get_record) _, item = resolver.resolve(event.payload['item_id']) self.circulation_event_schema.context['item'] = item data, errors = self.circulation_event_schema.load(event.payload) if errors: event.response_code = 400 event.response = {'message': errors} return if data.get('dry_run'): event.response_code = 204 return with db.session.begin_nested(): data, _ = self.circulation_event_schema.dump(data) self._run(item, data) item.commit() RecordIndexer().index(item)
def test_record_files_migration(app, location, script_info, datadir): """Test CDS records and files migrations.""" runner = CliRunner() filepath = join(datadir, 'cds_records_and_files_dump.json') result = runner.invoke( cli, ['dumps', 'loadrecords', filepath], obj=script_info) assert result.exit_code == 0 assert RecordMetadata.query.count() == 1 # CERN Theses resolver = Resolver( pid_type='recid', object_type='rec', getter=Record.get_record) pid, record = resolver.resolve(1198695) assert record assert record.revision_id == 34 # 33 from the dump and 1 for the files assert record['main_entry_personal_name']['personal_name'] == 'Caffaro, J' assert 'CERN' in record['subject_indicator'] assert record['control_number'] == '1198695' assert record['title_statement']['title'] == \ 'Improving the Formatting Tools of CDS Invenio' assert record['source_of_acquisition'][0]['stock_number'] == \ 'CERN-THESIS-2009-057' assert '_files' in record assert record['_files'][0]['key'] == 'CERN-THESIS-2009-057.pdf' assert record['_files'][0]['doctype'] == 'CTH_FILE'
def create_url_rules(endpoint, list_route=None, item_route=None, pid_type=None, pid_minter=None): """Create Werkzeug URL rules.""" assert list_route assert item_route assert pid_type resolver = Resolver(pid_type=pid_type, object_type='rec', getter=Record.get_record) serializers = { 'application/json': record_to_json_serializer, } list_view = RecordsListResource.as_view( RecordsListResource.view_name.format(endpoint), resolver=resolver, minter_name=pid_minter, serializers=serializers) item_view = RecordResource.as_view( RecordResource.view_name.format(endpoint), resolver=resolver, serializers=serializers) return [ dict(rule=list_route, view_func=list_view), dict(rule=item_route, view_func=item_view), ]
def recid(pid_value=None): resolver = Resolver( pid_type='recid', object_type='rec', getter=Record.get_record) try: pid, record = resolver.resolve(pid_value) except: abort(404) is_public = ActionUsers.query.filter( ActionUsers.action == 'records-read', ActionUsers.user_id.is_(None)).first() permission_read_record = read_permission_factory(record) if is_public or permission_read_record.can(): return record_view(pid_value, resolver, ['records/detail-' + record.get("collections", [""])[ 0] + '.html', 'records/detail.html'], None, default_view_method ) abort(403)
def default_view_method(pid, record, template=None): """Default view method for updating record. Sends ``record_viewed`` signal and renders template. :param pid: PID object. :param record: Record object. :param template: Template to render. """ # Fetch deposit id from record and resolve deposit record and pid. depid = zenodo_deposit_fetcher(None, record) if not depid: abort(404) depid, deposit = Resolver( pid_type=depid.pid_type, object_type='rec', getter=ZenodoDeposit.get_record, ).resolve(depid.pid_value) # Put deposit in edit mode if not already. if deposit['_deposit']['status'] != 'draft': deposit = deposit.edit() db.session.commit() record_viewed.send( current_app._get_current_object(), pid=pid, record=record, ) return render_template( template, pid=pid, record=record, )
def resolve(cls, pid_value): """Resolve a PID value and return the PID and record.""" return Resolver( pid_type=cls.pid_type, object_type=cls.object_type, getter=cls.get_record, ).resolve(pid_value)
def create_url_rule( endpoint, route=None, pid_type=None, permission_factory_imp=None, record_class=None, manifest_class=None, ): """Create Werkzeug URL rule for a specific endpoint.""" assert route assert pid_type permission_factory = (import_string(permission_factory_imp) if permission_factory_imp else None) record_class = import_string(record_class) if record_class else Record manifest_class = (import_string(manifest_class) if manifest_class else IIIFManifest) view_func = partial( manifest_view, resolver=Resolver( pid_type=pid_type, object_type='rec', getter=record_class.get_record, ), permission_factory=permission_factory, manifest_class=manifest_class, ) # Make view well-behaved for Flask-DebugToolbar view_func.__module__ = manifest_view.__module__ view_func.__name__ = manifest_view.__name__ return dict(endpoint=endpoint, rule=route, view_func=view_func, methods=['GET'])
def record_permissions(pid_value=None): resolver = Resolver( pid_type='recid', object_type='rec', getter=Record.get_record) pid, record = resolver.resolve(pid_value) permissions = get_record_permissions(record.id) result = dict() result['permissions'] = [] collab_egroups = current_app.config.get('CAP_COLLAB_EGROUPS') if record.get('experiment', None): result['collab_egroup'] = six.next( six.itervalues(collab_egroups.get(record['experiment'])) )[0] for p in permissions: if isinstance(p, ActionUsers) and p.user: result['permissions'].append( {"action": p.action, "user": {"email": p.user.email}} ) elif isinstance(p, ActionRoles) and p.role: result['permissions'].append( {"action": p.action, "user": {"email": p.role.name}} ) resp = jsonify(**result) resp.status_code = 200 return resp
def get_record_by_data(cls, data): # depending of the providers this method can be more complex, meaning using other # external PIDs like url or doi assert cls.oai_provider resolver = Resolver( pid_type=cls.oai_provider.pid_type, object_type=cls.object_type, getter=cls.get_record, ) try: pid = cls.oai_provider.get_pid_from_data(data=data) try: persistent_identifier, record = resolver.resolve(str(pid)) return record except PIDDeletedError: PersistentIdentifier.query.filter_by( pid_type=pids.RECORD_SOURCE_OAI_PID_TYPE, pid_value=str(pid)).delete() db.session.commit() return None except Exception as e: print(traceback.format_exc()) persistent_identifier = PersistentIdentifier.get( pids.RECORD_SOURCE_OAI_PID_TYPE, str(pid)) persistent_identifier.unassign() persistent_identifier.status == PIDStatus.NEW persistent_identifier.delete() db.session.commit() return None # return super(IrokoRecord, cls).get_record( # persistent_identifier.object_uuid, with_deleted=with_deleted # ) except PIDDoesNotExistError: return None
def create_or_update_record(data, pid_type, id_key, minter): """Register a funder or grant.""" resolver = Resolver(pid_type=pid_type, object_type='rec', getter=Record.get_record) try: pid, record = resolver.resolve(data[id_key]) data_c = deepcopy(data) del data_c['remote_modified'] record_c = deepcopy(record) del record_c['remote_modified'] # All grants on OpenAIRE are modified periodically even if nothing # has changed. We need to check for actual differences in the metadata if data_c != record_c: record.update(data) record.commit() record_id = record.id db.session.commit() RecordIndexer().index_by_id(str(record_id)) except PIDDoesNotExistError: record = Record.create(data) record_id = record.id minter(record.id, data) db.session.commit() RecordIndexer().index_by_id(str(record_id))
def prepare_authors_data_for_pushing_to_orcid(json): """ Extracts the authors with valid orcid credentials from the list of authors of a given record in json format. """ resolver = Resolver(pid_type='literature', object_type='rec', getter=lambda x: x) record_id = resolver.resolve(json.get('control_number'))[ 0].object_uuid authors = get_orcid_valid_authors(json) token = None author_orcid = '' authors_with_orcid_credentials = [] for author in authors: try: token, author_orcid = get_authors_credentials(author) except AttributeError: continue try: authors_with_orcid_credentials.append((InspireOrcidRecords.query.filter_by( orcid=author_orcid, record_id=record_id).first().put_code, token, author_orcid, record_id)) except AttributeError: authors_with_orcid_credentials.append( ([], token, author_orcid, record_id)) continue return authors_with_orcid_credentials
def create_reana_workflow(): """Create a reana workflow by json.""" _args = request.get_json() # try fetch the deposit with the provided PID try: resolver = Resolver(pid_type='depid', object_type='rec', getter=lambda x: x) deposit, rec_uuid = resolver.resolve(_args.get('pid')) except PIDDoesNotExistError: abort( 404, "You tried to create a workflow and connect" " it with a non-existing record") # if record exist check if the user has 'deposit-update' rights with UpdateDepositPermission(deposit).require(403): token = get_reana_token(rec_uuid) name = _args.get('workflow_name') workflow_name = generate_slug(2) workflow_json = _args.get('workflow_json') try: resp = create_workflow(workflow_json, workflow_name, token) except ValidationError as e: return jsonify({'message': e.message}), 400 except Exception: return jsonify({ 'message': 'An exception has occured while creating ' 'the workflow in REANA.' }), 400 # create a workflow dict, which can be used to populate # the db, but also used in the serializer _workflow = { 'service': 'reana', 'user_id': current_user.id, 'name': name, 'workflow_name': workflow_name, 'name_run': resp['workflow_name'], 'workflow_id': resp['workflow_id'], 'rec_uuid': str(rec_uuid), 'depid': _args.get('pid'), 'status': 'created', 'workflow_json': workflow_json, } # TOFIX: check for integrity errors workflow = ReanaWorkflow(**_workflow) db.session.add(workflow) db.session.commit() workflow_serialized = ReanaWorkflowSchema().dump(_workflow).data return jsonify(workflow_serialized)
def resolver(self): """PID resolver.""" record_cls = obj_or_import_string(self.record_class, default=Record) getter = obj_or_import_string(self.getter, default=partial(record_cls.get_record, with_deleted=True)) return Resolver(pid_type=self.pid_type, object_type=self.object_type, getter=getter)
def institution_resolver(pid): """Resolve referenced institution.""" resolver = Resolver(pid_type='inst', object_type="rec", getter=Record.get_record) _, record = resolver.resolve(pid) del record['$schema'] return record
def get_record_by_pid(cls, pid, with_deleted=False): """Get ils record by pid value.""" resolver = Resolver( pid_type=CIRCULATION_LOAN_PID_TYPE, object_type="rec", getter=cls.get_record, ) _, record = resolver.resolve(str(pid)) return record
def __init__(self, url_map, pid_type, getter=None, record_class=None): """Initialize the converter.""" super(PIDConverter, self).__init__(url_map) getter = obj_or_import_string(getter, default=partial( obj_or_import_string(record_class, default=Record).get_record, with_deleted=True )) self.resolver = Resolver(pid_type=pid_type, object_type='rec', getter=getter)
def resolve_depid(depid): """Resolve the workflow id into a UUID.""" resolver = Resolver(pid_type='depid', object_type='rec', getter=lambda x: x) # deposit, rec_uuid = resolver.resolve(depid) # workflow = ReanaWorkflow.query.filter_by(workflow_id=workflow_id).first() return resolver.resolve(depid)
def get_record_by_legacy_recid(cls, legacy_pid_type, pid_value): """Get ils record by pid value and pid type.""" resolver = Resolver( pid_type=legacy_pid_type, object_type="rec", getter=cls.get_record, ) pid, record = resolver.resolve(str(pid_value)) return record
def user_resolver(pid): """Resolve referenced user.""" resolver = Resolver(pid_type='user', object_type="rec", getter=Record.get_record) _, record = resolver.resolve(pid) del record['$schema'] return record
def source_resolver(pid): """Resolve referenced user.""" resolver = Resolver(pid_type='srcid', object_type="src", getter=Record.get_record) _, record = resolver.resolve(pid) del record['$schema'] return record
def get_record_by_pid(cls, pid, with_deleted=False): """Get ils record by pid value.""" assert cls.provider resolver = Resolver(pid_type=cls.provider.pid_type, object_type=cls.object_type, getter=cls.get_record) persistent_identifier, record = resolver.resolve(str(pid)) return super(IlsRecord, cls).get_record(persistent_identifier.object_uuid, with_deleted=with_deleted)
def get_record_by_legacy_recid(cls, pid_value): """Get ils record by pid value and pid type.""" legacy_pid_type = current_app.config["CDS_ILS_RECORD_LEGACY_PID_TYPE"] resolver = Resolver( pid_type=legacy_pid_type, object_type="rec", getter=cls.get_record, ) _, record = resolver.resolve(str(pid_value)) return record
def record_jsonresolver(authid): """Resolve referenced author.""" # Setup a resolver to retrive an author record given its id resolver = Resolver(pid_type='authid', object_type="rec", getter=Record.get_record) _, record = resolver.resolve(str(authid)) # we could manipulate here the record and eventually add/remove fields del record['$schema'] return record
def get_record_by_pid(cls, pid, with_deleted=False): """Get ils record by pid value.""" from .config import _CIRCULATION_LOAN_PID_TYPE resolver = Resolver( pid_type=_CIRCULATION_LOAN_PID_TYPE, object_type='rec', getter=cls.get_record, ) persistent_identifier, record = resolver.resolve(str(pid)) return record
def fetch_published(self): """Return a tuple with PID and published record.""" pid_type = self['_deposit']['pid']['type'] pid_value = self['_deposit']['pid']['value'] resolver = Resolver(pid_type=pid_type, object_type='rec', getter=partial(Record.get_record, with_deleted=True)) return resolver.resolve(pid_value)
def test_permission(app): """Test permission control to records.""" app.config.update( WTF_CSRF_ENABLED=False, SECRET_KEY='CHANGEME', SECURITY_PASSWORD_SALT='CHANGEME', # conftest switches off permission checking, so re-enable it for this # app. RECORDS_UI_DEFAULT_PERMISSION_FACTORY='helpers:' 'only_authenticated_users', ) Menu(app) InvenioRecordsUI(app) accounts = InvenioAccounts(app) app.register_blueprint(accounts_blueprint) InvenioAccess(app) setup_record_fixture(app) # Create admin with app.app_context(): accounts.datastore.create_user( email='*****@*****.**', password=encrypt_password('123456'), active=True, ) # Get record 1 r = Resolver(pid_type='recid', object_type='rec', getter=Record.get_record) dummy_pid, record = r.resolve('1') db.session.commit() with app.test_request_context(): login_url = url_for('security.login') record_url = url_for('invenio_records_ui.recid', pid_value='1') # Access record 1 as admin with app.test_client() as client: res = client.get(record_url) assert res.status_code == 302 res = client.post(login_url, data={ 'email': '*****@*****.**', 'password': '******' }) assert res.status_code == 302 res = client.get(record_url) res.status_code == 200 # Access record 1 as anonymous with app.test_client() as client: res = client.get(record_url) res.status_code == 403
def get_record_by_id(recid): try: resolver = Resolver(pid_type='recid', object_type='rec', getter=Record.get_record) pid, record = resolver.resolve(recid) return record except NoResultFound: print('No record found for recid {}'.format(recid)) return None except PIDDoesNotExistError: print('The PID {0} does not exist'.format(recid)) return None
def resolve(record_type, pid_value): """Resolve a pid value for a given record type.""" config = current_app.config['RECORDS_REST_ENDPOINTS'] config = config.get(record_type, {}) pid_type = config.get('pid_type') cfg = current_app.config['REROILS_RECORD_EDITOR_OPTIONS'].get(record_type) record_class = cfg.get('record_class', Record) resolver = Resolver(pid_type=pid_type, object_type='rec', getter=record_class.get_record) return resolver.resolve(pid_value)
def get_record_pid_uuid(app, users, create_deposit, create_schema): owner = users['cms_user'] create_schema('deposits/records/test-v0.0.1', experiment='CMS') deposit = create_deposit(owner, 'test-v0.0.1') pid = deposit['_deposit']['id'] resolver = Resolver(pid_type='depid', object_type='rec', getter=lambda x: x) _, uuid = resolver.resolve(pid) return pid, str(uuid)