def get(self, domain_name, **kwargs): pag = pager.parse_args() page_size = pag.get('page_size') or PAGE_SIZE page_offset = pag.get('page_offset') or 0 if page_size > MAX_PAGE_SIZE: page_size = MAX_PAGE_SIZE if domain_name not in metadata_classes().keys(): abort(404, status=404, message="Please try a valid domain name: " +\ ", ".join(metadata_classes().keys())) # get domain id from domain name from .b2share_model.model import Bib98x, BibrecBib98x domain = Bib98x.query.filter_by(value=domain_name).first() domain_records = BibrecBib98x.query.filter_by(id_bibxxx=domain.id).all() record_ids = [record.id_bibrec for record in domain_records] record_list = [] start = page_offset * page_size stop = start + page_size for record_id in record_ids[start : stop]: record_details = get_record_details(record_id) record_list.append(record_details) return jsonify({'records': record_list})
def read_basic_metadata_field_from_marc(bfo, fieldname): if fieldname in basic_fields_meta: marctag = basic_fields_meta[fieldname][0] multiple = basic_fields_meta[fieldname][1] # we need to do additional filtering due to the # clash between domain and resource_type # they are both encoded as the same marc field if fieldname == 'domain': ret = [r.lower() for r in bfo.fields(marctag) if r.lower() in metadata_classes()] return ret if multiple else ", ".join(ret) elif fieldname == 'resource_type': ret = [r for r in bfo.fields(marctag) if r.lower() not in metadata_classes()] return ret if multiple else ", ".join(ret) elif marctag: if multiple: return bfo.fields(marctag) else: return bfo.field(marctag) return None
def read_basic_metadata_field_from_marc(bfo, fieldname): if fieldname in basic_fields_meta: marctag = basic_fields_meta[fieldname][0] multiple = basic_fields_meta[fieldname][1] if fieldname == 'domain': ret = [r.lower() for r in bfo.fields(marctag) if r.lower() in metadata_classes()] return ret if multiple else ", ".join(ret) elif marctag: if multiple: return bfo.fields(marctag) else: return bfo.field(marctag) return None
def do_upgrade(): """Implement your upgrades here.""" from invenio.b2share.modules.b2deposit.edit import get_domain_admin_group from invenio.b2share.modules.b2deposit.b2share_model import metadata_classes from invenio.modules.accounts.models import User from invenio.ext.login import login_user from flask.ext.login import current_user admin_user = User.query.get(1) login_user(admin_user.get_id()) if not current_user.is_super_admin: raise Exception("Cannot find the superadmin user") for domain in metadata_classes(): groupname = get_domain_admin_group(domain) print "Creating domain administrator group: ", groupname create_user_group(groupname, 'Administrators of the {} domain'.format(domain), admin_user)
def do_upgrade(): """Implement your upgrades here.""" from invenio.b2share.modules.b2deposit.edit import get_domain_admin_group from invenio.b2share.modules.b2deposit.b2share_model import metadata_classes from invenio.modules.accounts.models import User from invenio.ext.login import login_user from flask.ext.login import current_user admin_user = User.query.get(1) login_user(admin_user.get_id()) if not current_user.is_super_admin: raise Exception("Cannot find the superadmin user") for domain in metadata_classes(): groupname = get_domain_admin_group(domain) print "Creating domain administrator group: ", groupname create_user_group(groupname, 'Administrators of the {} domain'.format(domain), admin_user)
def post(self, deposit_id, **kwargs): """ Creates a new deposition Test this with: $ curl -v -X POST -H "Content-Type: application/json" -d '{"domain":"generic", "title":"REST Test Title", "description":"REST Test Description"}' http://0.0.0.0:4000/api/deposition/DEPOSITION_ID/commit\?access_token\=xxx """ CFG_B2SHARE_UPLOAD_FOLDER = current_app.config.get( "CFG_B2SHARE_UPLOAD_FOLDER") deposition_status = os.path.join(CFG_B2SHARE_UPLOAD_FOLDER, deposit_id, 'uncommitted') if not os.path.exists(deposition_status): return {'message': 'Bad deposit_id parameter or already closed deposition.', 'status': 404}, 404 if not get_depositing_files_metadata(deposit_id): return {'message':'No files: add files to this deposition first', 'status':400}, 400 try: form = request.get_json() except: return {'message':'Invalid POST data', 'status':400}, 400 os.remove(deposition_status) domain = form.get('domain', '').lower() if domain in metadata_classes(): metaclass = metadata_classes()[domain] meta = metaclass() else: domains = ", ".join(metadata_classes().keys()) json_data = { 'message': 'Invalid domain. The submitted metadata must '+\ 'contain a valid "domain" field. Valid domains '+\ 'are: '+ domains, 'status': 400, } return json_data, 400 if not is_current_user_allowed_to_deposit(meta): return {'message':'depositions to this domain are restricted', 'status':401}, 401 if 'open_access' not in form: return {'message':'open_access boolean field required', 'status':400}, 400 if not form['open_access'] or form['open_access'] == 'restricted': del form['open_access'] # action required by the b2share_marc_handler if not form.get('language'): form['language'] = meta.language_default form = ImmutableMultiDict(form) MetaForm = model_form(meta.__class__, base_class=FormWithKey, exclude=['submission', 'submission_type'], field_args=meta.field_args, converter=HTML5ModelConverter()) meta_form = MetaForm(form, meta, csrf_enabled=False) if meta_form.validate_on_submit(): recid, marc = create_marc(form, deposit_id, current_user['email'], meta) tmp_file = write_marc_to_temp_file(marc) # all usual tasks have priority 0; we want the bibuploads to run first from invenio.legacy.bibsched.bibtask import task_low_level_submission task_low_level_submission('bibupload', 'webdeposit', '--priority', '1', '-r', tmp_file) #TODO: remove the existing deposition folder?; the user can now # repeatedly create records with the same deposition location = "/api/record/%d" % (recid,) json_data = { 'message': "New record submitted for processing", 'location': "/api/record/%d" % (recid,), 'record_id': recid, } return json_data, 201, {'Location':location} # return location header else: fields = {} for (fname, field) in meta.field_args.iteritems(): if not field.get('hidden'): fields[fname] = { 'description' : field.get('description') } if self.is_required_field(metaclass, fname): fields[fname]['required'] = True if field.get('cardinality') == 'n': fields[fname]['multiple'] = True if field.get('data_source'): fields[fname]['options'] = field.get('data_source') json_data = { 'message': 'Invalid metadata, please review the required fields', 'status': 400, 'fields': fields, } return json_data, 400
def get_record_details(recid, curr_user_email=None): from invenio.legacy.bibdocfile.api import BibRecDocs try: recdocs = BibRecDocs(recid) except: current_app.logger.error("REST API: Error while building BibRecDocs for record %d" % (recid,)) return {} latest_files = recdocs.list_latest_files() if len(latest_files) == 0: current_app.logger.error("REST API: BibRecDocs reports 0 files for record %d" % (recid,)) # bibformat uses get_record, usually is one db # hit per object; should be fastest from invenio.modules.formatter import engine as bibformat_engine bfo = bibformat_engine.BibFormatObject(recid) # first put the record_id and list of files ret = { 'record_id': recid, 'files': [{ 'name': afile.get_full_name().decode('utf-8'), 'size': afile.get_size(), 'url': afile.get_full_url(), } for afile in latest_files ], } if not curr_user_email: curr_user_email = current_user['email'] # add basic metadata fields for fieldname in basic_fields_meta: if fieldname == "open_access": open_access = (read_basic_metadata_field_from_marc(bfo, fieldname) == "open") ret[fieldname] = open_access if not open_access: if read_basic_metadata_field_from_marc(bfo, "uploaded_by") != curr_user_email: ret['files'] = "RESTRICTED" else: ret[fieldname] = read_basic_metadata_field_from_marc(bfo, fieldname) # add 'PID' and 'checksum' for fx in bfo.fields('0247_'): if fx.get('2') in ["PID", "checksum"]: ret[fx.get('2')] = fx.get('a') # add 'domain' domain = read_basic_metadata_field_from_marc(bfo, 'domain') ret['domain'] = domain # add domain-specific metadata fields if domain not in metadata_classes(): current_app.logger.error("Bad domain metadata class for record %d" % (recid,)) else: domain_class = metadata_classes()[domain]() for fieldset in domain_class.fieldsets: if fieldset.name != 'Generic': ret['domain_metadata'] = get_domain_metadata(domain_class, fieldset, bfo) return ret
def format_element(bfo): ret = '<div><table class="metadata_table table table-striped'\ ' table-condensed">' html = '<tr><th><div style="white-space:nowrap">{0}:</div></th><td><div style="word-break:break-all">{1}</div></td></tr>' ids = bfo.fields("0247_") for i in ids: val = i['a'] if i['2'] == "PID": try: val = '<a href="{0}">{0}</a>'.format(i['a']) except ImportError: None ret += html.format(i['2'][0].upper() + i['2'][1:], val) ver = bfo.field("250__a") if ver: ret += html.format('Version', ver) pub = bfo.field("260__") if pub: ret += html.format('Publication', pub.get('b')) if 'c' in pub: ret += html.format('Publication Date', pub['c']) licence = bfo.field("540__a") or 'Unspecified' ret += html.format('Licence', licence) disciplines = bfo.fields("526__a") for discipline in disciplines: if discipline: ret += html.format('Discipline', discipline) resource_types = bfo.fields("337__a") for resource_type in resource_types: if resource_type: ret += html.format('Resource Type', resource_type) uploader = bfo.field("8560_f") if uploader: ret += html.format('Uploaded by', uploader) contact_email = bfo.field("270__m") if contact_email: ret += html.format('Contact email', contact_email) alternate_identifier = bfo.field("024__a") if alternate_identifier: ret += html.format('Alternate Identifier', alternate_identifier) domain = bfo.field("980__a") if domain: ret += html.format('Domain', domain) md_class = None if domain.lower() in metadata_classes(): md_class = metadata_classes()[domain.lower()]() domain_data = bfo.fields("690__") for md in domain_data: field = md['a'] value = md['b'] if md_class: field_args = md_class.field_args.get(field) if field_args: data_source = field_args.get('data_source') field = field_args.get('label', field) if (data_source and len(data_source) and isinstance(data_source[0], (list, tuple, set)) and len(data_source[0]) == 2): value = next((v for k, v in data_source if k == value), value) ret += html.format(field, value) ids = bfo.fields("0247_") for i in ids: val = i['a'] if i['2'] != "PID": ret += html.format(i['2'][0].upper() + i['2'][1:], val) ret += '</table></div>' return ret
def format_element(bfo): ret = '<div><table class="metadata_table table table-striped'\ ' table-condensed">' html = '<tr><th><div style="white-space:nowrap">{0}:</div></th><td><div style="word-break:break-all">{1}</div></td></tr>' ids = bfo.fields("0247_") for i in ids: val = i['a'] if i['2'] == "PID": try: val = '<a href="{0}">{0}</a>'.format(i['a']) except ImportError: None ret += html.format(i['2'][0].upper() + i['2'][1:], val) ver = bfo.field("250__a") if ver: ret += html.format('Version', ver) pub = bfo.field("260__") if pub: ret += html.format('Publication', pub.get('b')) if 'c' in pub: ret += html.format('Publication Date', pub['c']) licence = bfo.field("540__a") or 'Unspecified' ret += html.format('Licence', licence) disciplines = bfo.fields("526__a") for discipline in disciplines: if discipline: ret += html.format('Discipline', discipline) resource_types = bfo.fields("337__a") for resource_type in resource_types: if resource_type: ret += html.format('Resource Type', resource_type) uploader = bfo.field("8560_f") if uploader: ret += html.format('Uploaded by', uploader) contact_email = bfo.field("270__m") if contact_email: ret += html.format('Contact email', contact_email) alternate_identifier = bfo.field("024__a") if alternate_identifier: ret += html.format('Alternate Identifier', alternate_identifier) domain = bfo.field("980__a") if domain: ret += html.format('Domain', domain) md_class = None if domain.lower() in metadata_classes(): md_class = metadata_classes()[domain.lower()]() domain_data = bfo.fields("690__") for md in domain_data: field = md['a'] value = md['b'] if md_class: field_args = md_class.field_args.get(field) if field_args: data_source = field_args.get('data_source') field = field_args.get('label', field) if (data_source and len(data_source) and isinstance(data_source[0], (list, tuple, set)) and len(data_source[0]) == 2): value = next((v for k, v in data_source if k == value), value) ret += html.format(field, value) ids = bfo.fields("0247_") for i in ids: val = i['a'] if i['2'] != "PID": ret += html.format(i['2'][0].upper() + i['2'][1:], val) ret += '</table></div>' return ret