Beispiel #1
0
    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})
Beispiel #2
0
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
Beispiel #3
0
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
Beispiel #4
0
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)
Beispiel #6
0
    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
Beispiel #7
0
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
Beispiel #8
0
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
Beispiel #9
0
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