def get_resource_dump_manifest(self, record_id): """ Get resource dump manifest. :param record_id: Identifier of record. :return: (xml) content of resourcedumpmanifest """ _validation = self._validation(record_id) if self.resource_dump_manifest and _validation: rdm = ResourceDumpManifest() rdm.up = '{}resync/{}/resourcedump.xml'.format( request.url_root, self.repository_id) record = WekoRecord.get_record_by_pid(record_id) if record: for file in record.files: current_app.logger.debug(file.info()) file_info = file.info() path = 'recid_{}/{}'.format(record.get('recid'), file_info.get('key')) lastmod = str(datetime.datetime.utcnow().replace( tzinfo=datetime.timezone.utc).isoformat()) rdm.add( Resource( '{}record/{}/files/{}'.format( request.url_root, record.get('recid'), file_info.get('key')), lastmod=lastmod, sha256=file_info.get('checksum').split(':')[1], length=str(file_info.get('size')), path=path)) return rdm.as_xml() return None
def getrecord(**kwargs): """Create OAI-PMH response for verb Identify.""" def get_error_code_msg(): code = "noRecordsMatch" msg = "The combination of the values of the from, until, " \ "set and metadataPrefix arguments results in an empty list." return [(code, msg)] record_dumper = serializer(kwargs['metadataPrefix']) pid = OAIIDProvider.get(pid_value=kwargs['identifier']).pid # record = Record.get_record(pid.object_uuid) identify = OaiIdentify.get_all() harvest_public_state, record = WekoRecord.get_record_with_hps( pid.object_uuid) if (identify and not identify.outPutSetting) or not harvest_public_state: return error(get_error_code_msg(), **kwargs) e_tree, e_getrecord = verb(**kwargs) e_record = SubElement(e_getrecord, etree.QName(NS_OAIPMH, 'record')) header( e_record, identifier=pid.pid_value, datestamp=record.updated, sets=record.get('_oai', {}).get('sets', []), ) e_metadata = SubElement(e_record, etree.QName(NS_OAIPMH, 'metadata')) e_metadata.append(record_dumper(pid, {'_source': record})) return e_tree
def check_identifier_new(item): """Check data Identifier. :argument item -- {dict} item import. item_exist -- {dict} item in system. :return return -- Name of key if is Identifier. """ if item.get('Identifier key'): item_iden = item.get('metadata', '').get(item.get('Identifier key')) for it in item_iden: try: pids = [ k for k in it.values() if k != 'DOI' or k != 'HDL'] for pid in pids: item_check = \ WekoRecord.get_record_by_pid(pid) if item_check and item_check.id != item.id: item['errors'] = ['Errors in Identifier'] item['status'] = '' except BaseException: current_app.logger.error('Unexpected error: ', sys.exc_info()[0]) return item
def get_items_metadata(self): """Get the metadata of items to bulk update.""" def get_file_data(meta): file_data = {} for key in meta: if isinstance(meta.get(key), list): for item in meta.get(key): if isinstance(item, dict) and 'filename' in item: file_data[key] = meta.get(key) break return file_data pids = request.values.get('pids') pid_list = [] if pids is not None: pid_list = pids.split('/') data = {} for pid in pid_list: record = WekoRecord.get_record_by_pid(pid) indexes = [] if isinstance(record.get('path'), list): for path in record.get('path'): indexes.append(path.split('/')[-1]) pidObject = PersistentIdentifier.get('recid', pid) meta = ItemsMetadata.get_record(pidObject.object_uuid) if meta: data[pid] = {} data[pid]['meta'] = meta data[pid]['index'] = {"index": indexes} data[pid]['contents'] = get_file_data(meta) return jsonify(data)
def getrecord(**kwargs): """Create OAI-PMH response for verb Identify.""" def get_error_code_msg(): """Get error by type.""" code = current_app.config.get('OAISERVER_CODE_NO_RECORDS_MATCH') msg = current_app.config.get('OAISERVER_MESSAGE_NO_RECORDS_MATCH') return [(code, msg)] record_dumper = serializer(kwargs['metadataPrefix']) pid = OAIIDProvider.get(pid_value=kwargs['identifier']).pid identify = OaiIdentify.get_all() harvest_public_state, record = WekoRecord.get_record_with_hps( pid.object_uuid) e_tree, e_getrecord = verb(**kwargs) e_record = SubElement(e_getrecord, etree.QName(NS_OAIPMH, 'record')) set_identifier(record, record) # Harvest is private _is_private_index = is_private_index(record) if not harvest_public_state or\ (identify and not identify.outPutSetting) or \ (_is_private_index and harvest_public_state and is_exists_doi(record)): return error(get_error_code_msg(), **kwargs) # Item is deleted # or Harvest is public & Item is private # or Harvest is public & Index is private elif is_deleted_workflow(pid) or (harvest_public_state and is_private_workflow(record)) or ( harvest_public_state and _is_private_index): header(e_record, identifier=pid.pid_value, datestamp=record.updated, sets=record.get('_oai', {}).get('sets', []), deleted=True) return e_tree header( e_record, identifier=pid.pid_value, datestamp=record.updated, sets=record.get('_oai', {}).get('sets', []), ) e_metadata = SubElement(e_record, etree.QName(NS_OAIPMH, 'metadata')) etree_record = copy.deepcopy(record) if not etree_record.get('system_identifier_doi', None): etree_record['system_identifier_doi'] = get_identifier(record) # Merge licensetype and licensefree etree_record = handle_license_free(etree_record) root = record_dumper(pid, {'_source': etree_record}) e_metadata.append(root) return e_tree
def record_from_pid(pid_value): """Get record from PID.""" try: return WekoRecord.get_record_by_pid(pid_value) except Exception as e: current_app.logger.debug('Unable to get version record: ') current_app.logger.debug(e) return {}
def get_contribute_tree(cls, pid, root_node_id=0): """Get Contrbute tree.""" from weko_deposit.api import WekoRecord record = WekoRecord.get_record_by_pid(pid) tree = cls.get_index_tree(root_node_id) if record.get('_oai'): reset_tree(tree=tree, path=record.get('path')) else: reset_tree(tree=tree, path=[]) return tree
def iframe_items_index(pid_value=0): """Iframe items index.""" try: if pid_value == 0: return redirect(url_for('.iframe_index')) record = WekoRecord.get_record_by_pid(pid_value) action = 'private' if record.get('publish_status', '1') == '1' \ else 'publish' if request.method == 'GET': return render_template( 'weko_items_ui/iframe/item_index.html', render_widgets=True, pid_value=pid_value, action=action, activity=session['itemlogin_activity'], item=session['itemlogin_item'], steps=session['itemlogin_steps'], action_id=session['itemlogin_action_id'], cur_step=session['itemlogin_cur_step'], record=session['itemlogin_record'], histories=session['itemlogin_histories'], res_check=session['itemlogin_res_check'], pid=session['itemlogin_pid'], community_id=session['itemlogin_community_id']) if request.headers['Content-Type'] != 'application/json': flash(_('Invalid Request'), 'error') return render_template('weko_items_ui/iframe/item_index.html', render_widgets=True) data = request.get_json() sessionstore = RedisStore( redis.StrictRedis.from_url('redis://{host}:{port}/1'.format( host=os.getenv('INVENIO_REDIS_HOST', 'localhost'), port=os.getenv('INVENIO_REDIS_PORT', '6379')))) if request.method == 'PUT': """update index of item info.""" item_str = sessionstore.get('item_index_{}'.format(pid_value)) sessionstore.delete('item_index_{}'.format(pid_value)) current_app.logger.debug(item_str) item = json.loads(item_str) item['index'] = data current_app.logger.debug(item) elif request.method == 'POST': """update item data info.""" sessionstore.put('item_index_{}'.format(pid_value), json.dumps(data), ttl_secs=300) return jsonify(data) except BaseException: current_app.logger.error('Unexpected error: ', sys.exc_info()[0]) return abort(400)
def citation(record, pid, style=None, ln=None): """Render citation for record according to style and language.""" locale = ln or "en-US" # ln or current_i18n.language style = style or "aapg-bulletin" # style or 'science' try: _record = WekoRecord.get_record(pid.object_uuid) return citeproc_v1.serialize(pid, _record, style=style, locale=locale) except Exception: current_app.logger.exception( 'Citation formatting for record {0} failed.'.format(str( record.id))) return None
def items_index(pid_value='0'): """Items index.""" try: if pid_value == '0' or pid_value == 0: return redirect(url_for('.index')) record = WekoRecord.get_record_by_pid(pid_value) action = 'private' if record.get('publish_status', '1') == '1' \ else 'publish' from weko_theme.utils import get_design_layout # Get the design for widget rendering page, render_widgets = get_design_layout( current_app.config['WEKO_THEME_DEFAULT_COMMUNITY']) if request.method == 'GET': return render_template( current_app.config['WEKO_ITEMS_UI_INDEX_TEMPLATE'], page=page, render_widgets=render_widgets, pid_value=pid_value, action=action) if request.headers['Content-Type'] != 'application/json': flash(_('Invalid request'), 'error') return render_template( current_app.config['WEKO_ITEMS_UI_INDEX_TEMPLATE'], page=page, render_widgets=render_widgets) data = request.get_json() sessionstore = RedisStore( redis.StrictRedis.from_url('redis://{host}:{port}/1'.format( host=os.getenv('INVENIO_REDIS_HOST', 'localhost'), port=os.getenv('INVENIO_REDIS_PORT', '6379')))) if request.method == 'PUT': """update index of item info.""" item_str = sessionstore.get('item_index_{}'.format(pid_value)) sessionstore.delete('item_index_{}'.format(pid_value)) current_app.logger.debug(item_str) item = json.loads(item_str) item['index'] = data current_app.logger.debug(item) elif request.method == 'POST': """update item data info.""" sessionstore.put('item_index_{}'.format(pid_value), json.dumps(data), ttl_secs=300) return jsonify(data) except BaseException: current_app.logger.error('Unexpected error: ', sys.exc_info()[0]) return abort(400)
def getrecord(**kwargs): """Create OAI-PMH response for verb Identify.""" def get_error_code_msg(): code = 'noRecordsMatch' msg = 'The combination of the values of the from, until, ' \ 'set and metadataPrefix arguments results in an empty list.' return [(code, msg)] record_dumper = serializer(kwargs['metadataPrefix']) pid = OAIIDProvider.get(pid_value=kwargs['identifier']).pid # record = Record.get_record(pid.object_uuid) identify = OaiIdentify.get_all() harvest_public_state, record = WekoRecord.get_record_with_hps( pid.object_uuid) if (identify and not identify.outPutSetting) or not harvest_public_state: return error(get_error_code_msg(), **kwargs) e_tree, e_getrecord = verb(**kwargs) e_record = SubElement(e_getrecord, etree.QName(NS_OAIPMH, 'record')) header( e_record, identifier=pid.pid_value, datestamp=record.updated, sets=record.get('_oai', {}).get('sets', []), ) e_metadata = SubElement(e_record, etree.QName(NS_OAIPMH, 'metadata')) etree_record = copy.deepcopy(record) if check_correct_system_props_mapping( pid.object_uuid, current_app.config.get('OAISERVER_SYSTEM_FILE_MAPPING')): etree_record = combine_record_file_urls(etree_record, pid.object_uuid) root = record_dumper(pid, {'_source': etree_record}) if check_correct_system_props_mapping( pid.object_uuid, current_app.config.get('OAISERVER_SYSTEM_IDENTIFIER_MAPPING')): if record.pid_doi: root = create_identifier_index(root, pid_type=record.pid_doi.pid_type, pid_value=record.pid_doi.pid_value) if record.pid_cnri: root = create_identifier_index(root, pid_type=record.pid_cnri.pid_type, pid_value=record.pid_cnri.pid_value) e_metadata.append(root) return e_tree
def handle_check_exist_record(list_recond) -> list: """Check record is exist in system. :argument list_recond -- {list} list recond import. :return return -- list record has property status. """ result = [] for item in list_recond: if not item.get('errors'): item = dict(**item, **{ 'status': 'new' }) try: item_id = item.get('id') if item_id: item_exist = WekoRecord.get_record_by_pid(item_id) if item_exist: if item_exist.pid.is_deleted(): item['status'] = None item['errors'] = [_('Item already DELETED' ' in the system')] result.append(item) continue else: exist_url = request.url_root + \ 'records/' + item_exist.get('recid') if item.get('uri') == exist_url: item['status'] = 'update' else: item['errors'] = ['URI of items are not match'] item['status'] = None else: item['id'] = None if item.get('uri'): item['errors'] = ['Item has no ID but non-empty URI'] item['status'] = None except PIDDoesNotExistError: pass except BaseException: current_app.logger.error( 'Unexpected error: ', sys.exc_info()[0] ) if item.get('status') == 'new': handle_remove_identifier(item) result.append(item) return result
def get(self, pid_value, **kwargs): """Render citation for record according to style and language.""" style = request.values.get('style', 1) # style or 'science' locale = request.values.get('locale', 2) try: pid = PersistentIdentifier.get('depid', pid_value) record = WekoRecord.get_record(pid.object_uuid) result = citeproc_v1.serialize(pid, record, style=style, locale=locale) return make_response(jsonify(result), 200) except Exception: current_app.logger.exception( 'Citation formatting for record {0} failed.'.format( str(record.id))) return make_response(jsonify("Not found"), 404)
def compare_identifier(item, item_exist): """Compare data is Identifier. :argument item -- {dict} item import. item_exist -- {dict} item in system. :return return -- Name of key if is Identifier. """ if item.get('Identifier key'): item_iden = item.get('metadata', '').get(item.get('Identifier key')) item_exist_iden = item_exist.get(item.get( 'Identifier key')).get('attribute_value_mlt') if len(item_iden) == len(item_exist_iden): list_dif = difference(item_iden, item_exist_iden) if list_dif: item['errors'] = ['Errors in Identifier'] item['status'] = '' elif len(item_iden) > len(item_exist_iden): list_dif = difference(item_iden, item_exist_iden) for i in list_dif + item_iden: if i not in item_exist_iden: try: pids = [ k for k in i.values() if k != 'DOI' or k != 'HDL'] for pid in pids: item_check = \ WekoRecord.get_record_by_pid(pid) if item_check and item_check.id != item.id: item['errors'] = ['Errors in Identifier'] item['status'] = '' except BaseException: current_app.logger.error('Unexpected error: ', sys.exc_info()[0]) if item['errors']: item['metadata'][item.get('Identifier key')] = list(set([ it for it in list_dif + item_iden ])) elif len(item_iden) < len(item_exist_iden): item['metadata'][item.get('Identifier key')] = item_exist_iden if item.get('uri'): pass return item
def _export_item(record_id, export_format, include_contents, tmp_path=None, records_data=None): """Exports files for record according to view permissions.""" exported_item = {} record = WekoRecord.get_record_by_pid(record_id) if record: exported_item['record_id'] = record.id exported_item['name'] = 'recid_{}'.format(record_id) exported_item['files'] = [] exported_item['path'] = 'recid_' + str(record_id) exported_item['item_type_id'] = record.get('item_type_id') if not records_data: records_data = record # Create metadata file. with open('{}/{}_metadata.json'.format(tmp_path, exported_item['name']), 'w', encoding='utf8') as output_file: json.dump(records_data, output_file, indent=2, sort_keys=True, ensure_ascii=False) # First get all of the files, checking for permissions while doing so if include_contents: # Get files for file in record.files: # TODO: Temporary processing if check_file_download_permission(record, file.info()): exported_item['files'].append(file.info()) # TODO: Then convert the item into the desired format if file: file_buffered = file.obj.file.storage().open() temp_file = open(tmp_path + '/' + file.obj.basename, 'wb') temp_file.write(file_buffered.read()) temp_file.close() return record, exported_item
def check_restricted_content(): """Check if record has restricted content for current user. :return: boolean """ if request.headers['Content-Type'] != 'application/json': return abort(400) post_data = request.get_json() restricted_records = set() for record_id in post_data['record_ids']: try: record = WekoRecord.get_record_by_pid(record_id) for file in record.files: if not check_file_download_permission(record, file.info()): restricted_records.add(record_id) except Exception: pass return jsonify({'restricted_records': list(restricted_records)})
def _is_record_in_index(self, record_id): """ Check record has register index. :param record_id: Identifier of record :return: True if record has register index_id """ from .utils import get_real_path, get_pid if self.repository_id == current_app.config.get( "WEKO_ROOT_INDEX", WEKO_ROOT_INDEX): return True if self.status: record_pid = get_pid(record_id) if record_pid: record = WekoRecord.get_record(record_pid.object_uuid) if record and record.get("path"): list_path = get_real_path(record.get("path")) if str(self.repository_id) in list_path: return True return False
def _validation(self, record_id=None): """ Update the index detail info. :param record_id: Identifier of record. :return: Updated Resource info """ from .utils import get_real_path if self.status: if self.repository_id == current_app.config.get( "WEKO_ROOT_INDEX", WEKO_ROOT_INDEX): return True if self.index.public_state: if record_id: record = WekoRecord.get_record_by_pid(record_id) if record and record.get("path"): list_path = get_real_path(record.get("path")) if str(self.repository_id) in list_path: return True else: return True return False
def file_ui(pid, record, _record_file_factory=None, is_preview=False, **kwargs): """File Ui. :param is_preview: Determine the type of event. True: file-preview, False: file-download :param _record_file_factory: :param pid: The :class:`invenio_pidstore.models.PersistentIdentifier` instance. :param record: The record metadata. """ _record_file_factory = _record_file_factory or record_file_factory # Extract file from record. fileobj = _record_file_factory(pid, record, kwargs.get('filename')) if not fileobj: abort(404) obj = fileobj.obj # Check file contents permission if not file_permission_factory(record, fjson=fileobj).can(): abort(403) # #Check permissions # ObjectResource.check_object_permission(obj) # Get user's language user = UserProfile.get_by_userid(current_user.get_id()) lang = 'en' # Defautl language for PDF coverpage if user is None: lang = 'en' else: lang = user.language add_signals_info(record, obj) """ Send file without its pdf cover page """ try: pdfcoverpage_set_rec = PDFCoverPageSettings.find(1) coverpage_state = WekoRecord.get_record_cvs(pid.object_uuid) is_original = request.args.get('original') or False is_pdf = 'pdf' in fileobj.mimetype can_download_original_pdf = check_original_pdf_download_permission( record) # if not pdf or cover page disabled: Download directly # if pdf and cover page enabled and has original in query param: check # permission (user roles) if is_pdf is False \ or pdfcoverpage_set_rec is None \ or pdfcoverpage_set_rec.avail == 'disable' \ or coverpage_state is False \ or (is_original and can_download_original_pdf): return ObjectResource.send_object( obj.bucket, obj, expected_chksum=fileobj.get('checksum'), logger_data={ 'bucket_id': obj.bucket_id, 'pid_type': pid.pid_type, 'pid_value': pid.pid_value, }, as_attachment=not is_preview, is_preview=is_preview) except AttributeError: return ObjectResource.send_object( obj.bucket, obj, expected_chksum=fileobj.get('checksum'), logger_data={ 'bucket_id': obj.bucket_id, 'pid_type': pid.pid_type, 'pid_value': pid.pid_value, }, as_attachment=not is_preview, is_preview=is_preview) # Send file with its pdf cover page file_instance_record = FileInstance.query.filter_by(id=obj.file_id).first() obj_file_uri = file_instance_record.uri # return obj_file_uri signals.file_downloaded.send(current_app._get_current_object(), obj=obj) return make_combined_pdf(pid, obj_file_uri, fileobj, obj, lang)
def prepare_edit_item(): """Prepare_edit_item. Host the api which provide 2 service: Create new activity for editing flow Check permission: check if user is owner/admin/shared user request: header: Content type must be json data: pid_value: pid_value return: The result json: code: status code, msg: meassage result, data: url redirect """ def _get_workflow_by_item_type_id(item_type_name_id, item_type_id): """Get workflow settings by item type id.""" workflow = WorkFlow.query.filter_by(itemtype_id=item_type_id).first() if not workflow: item_type_list = ItemTypes.get_by_name_id(item_type_name_id) id_list = [x.id for x in item_type_list] workflow = (WorkFlow.query.filter( WorkFlow.itemtype_id.in_(id_list)).order_by( WorkFlow.itemtype_id.desc()).order_by( WorkFlow.flow_id.asc()).first()) return workflow if request.headers['Content-Type'] != 'application/json': """Check header of request""" return jsonify(code=-1, msg=_('Header Error')) post_activity = request.get_json() pid_value = post_activity.get('pid_value') if pid_value: try: record = WekoRecord.get_record_by_pid(pid_value) owner = str(record.get('owner')) shared_id = str(record.get('weko_shared_id')) user_id = str(get_current_user()) is_admin = get_user_roles() activity = WorkActivity() pid_object = PersistentIdentifier.get('recid', pid_value) latest_pid = PIDVersioning(child=pid_object).last_child # check user's permission if user_id != owner and not is_admin[0] and user_id != shared_id: return jsonify( code=-1, msg=_(r"You are not allowed to edit this item.")) lists = ItemTypes.get_latest() if not lists: return jsonify(code=-1, msg=_(r"You do not even have an Itemtype.")) item_type_id = record.get('item_type_id') item_type = ItemTypes.get_by_id(item_type_id) if not item_type: return jsonify(code=-1, msg=_(r"This itemtype isn't found.")) # check item is being editied item_id = latest_pid.object_uuid workflow_activity = activity.get_workflow_activity_by_item_id( item_id) if not workflow_activity: # get workflow of first record attached version ID: x.1 workflow_activity = activity.get_workflow_activity_by_item_id( pid_object.object_uuid) # if workflow of the item is not found # use default settings of item type to which the item belongs else: # show error when has stt is Begin or Doing if workflow_activity.action_status == \ ActionStatusPolicy.ACTION_BEGIN \ or workflow_activity.action_status == \ ActionStatusPolicy.ACTION_DOING: return jsonify(code=-1, msg=_(r"The workflow is being edited.")) # prepare params for new workflow activity if workflow_activity: post_activity['workflow_id'] = workflow_activity.workflow_id post_activity['flow_id'] = workflow_activity.flow_id else: workflow = _get_workflow_by_item_type_id( item_type.name_id, item_type_id) if not workflow: return jsonify(code=-1, msg=_('Workflow setting does not exist.')) post_activity['workflow_id'] = workflow.id post_activity['flow_id'] = workflow.flow_id post_activity['itemtype_id'] = item_type_id getargs = request.args community = getargs.get('community', None) # Create a new version of a record. record = WekoDeposit.get_record(item_id) if not record: return jsonify(code=-1, msg=_('Record does not exist.')) deposit = WekoDeposit(record, record.model) draft_record = deposit.newversion(pid_object) if not draft_record: return jsonify(code=-1, msg=_('An error has occurred.')) # Create snapshot bucket for draft record from invenio_records_files.models import RecordsBuckets try: with db.session.begin_nested(): from weko_workflow.utils import delete_bucket draft_deposit = WekoDeposit(draft_record, draft_record.model) snapshot = record.files.bucket.snapshot(lock=False) snapshot.locked = False draft_deposit['_buckets'] = {'deposit': str(snapshot.id)} draft_record_bucket = RecordsBuckets.create( record=draft_record.model, bucket=snapshot) # Remove duplicated buckets draft_record_buckets = RecordsBuckets.query.filter_by( record_id=draft_record.model.id).all() for record_bucket in draft_record_buckets: if record_bucket != draft_record_bucket: delete_bucket_id = record_bucket.bucket_id RecordsBuckets.query.filter_by( bucket_id=delete_bucket_id).delete() delete_bucket(delete_bucket_id) draft_deposit.commit() except Exception as ex: db.session.rollback() current_app.logger.exception(str(ex)) return jsonify(code=-1, msg=_('An error has occurred.')) # Create a new workflow activity. rtn = activity.init_activity(post_activity, community, draft_record.model.id) if rtn: # GOTO: TEMPORARY EDIT MODE FOR IDENTIFIER identifier_actionid = get_actionid('identifier_grant') if workflow_activity: identifier = activity.get_action_identifier_grant( workflow_activity.activity_id, identifier_actionid) else: identifier = activity.get_action_identifier_grant( '', identifier_actionid) if identifier: if identifier.get('action_identifier_select') > \ IDENTIFIER_GRANT_DOI: identifier['action_identifier_select'] = \ IDENTIFIER_GRANT_CAN_WITHDRAW elif identifier.get('action_identifier_select') == \ IDENTIFIER_GRANT_IS_WITHDRAWING: identifier['action_identifier_select'] = \ IDENTIFIER_GRANT_WITHDRAWN activity.create_or_update_action_identifier( rtn.activity_id, identifier_actionid, identifier) mail_list = FeedbackMailList.get_mail_list_by_item_id( item_id=pid_object.object_uuid) if mail_list: activity.create_or_update_action_feedbackmail( activity_id=rtn.activity_id, action_id=ITEM_REGISTRATION_ACTION_ID, feedback_maillist=mail_list) if community: comm = GetCommunity.get_community_by_id(community) url_redirect = url_for('weko_workflow.display_activity', activity_id=rtn.activity_id, community=comm.id) else: url_redirect = url_for('weko_workflow.display_activity', activity_id=rtn.activity_id) return jsonify(code=0, msg='success', data={'redirect': url_redirect}) except Exception as e: current_app.logger.error('Unexpected error: ', str(e)) return jsonify(code=-1, msg=_('An error has occurred.'))
def iframe_items_index(pid_value='0'): """Iframe items index.""" try: if pid_value == '0' or pid_value == 0: return redirect(url_for('.iframe_index')) record = WekoRecord.get_record_by_pid(pid_value) action = 'private' if record.get('publish_status', '1') == '1' \ else 'publish' community_id = session.get('itemlogin_community_id') ctx = {'community': None} if community_id: comm = GetCommunity.get_community_by_id(community_id) ctx = {'community': comm} if request.method == 'GET': cur_activity = session['itemlogin_activity'] # If enable auto set index feature # and activity is usage application item type steps = session['itemlogin_steps'] contain_application_endpoint = False for step in steps: if step.get('ActionEndpoint') == 'item_login_application': contain_application_endpoint = True enable_auto_set_index = current_app.config.get( 'WEKO_WORKFLOW_ENABLE_AUTO_SET_INDEX_FOR_ITEM_TYPE') if enable_auto_set_index and contain_application_endpoint: index_id = get_index_id(cur_activity.activity_id) update_index_tree_for_record(pid_value, index_id) return redirect(url_for('weko_workflow.iframe_success')) # Get the design for widget rendering from weko_theme.utils import get_design_layout page, render_widgets = get_design_layout( community_id or current_app.config['WEKO_THEME_DEFAULT_COMMUNITY']) return render_template('weko_items_ui/iframe/item_index.html', page=page, render_widgets=render_widgets, pid_value=pid_value, action=action, activity=session['itemlogin_activity'], item=session['itemlogin_item'], steps=session['itemlogin_steps'], action_id=session['itemlogin_action_id'], cur_step=session['itemlogin_cur_step'], record=session['itemlogin_record'], histories=session['itemlogin_histories'], res_check=session['itemlogin_res_check'], pid=session['itemlogin_pid'], community_id=community_id, **ctx) if request.headers['Content-Type'] != 'application/json': flash(_('Invalid Request'), 'error') from weko_theme.utils import get_design_layout page, render_widgets = get_design_layout( current_app.config['WEKO_THEME_DEFAULT_COMMUNITY']) return render_template('weko_items_ui/iframe/item_index.html', page=page, render_widgets=render_widgets, community_id=community_id, **ctx) data = request.get_json() sessionstore = RedisStore( redis.StrictRedis.from_url('redis://{host}:{port}/1'.format( host=os.getenv('INVENIO_REDIS_HOST', 'localhost'), port=os.getenv('INVENIO_REDIS_PORT', '6379')))) if request.method == 'PUT': """update index of item info.""" item_str = sessionstore.get('item_index_{}'.format(pid_value)) sessionstore.delete('item_index_{}'.format(pid_value)) item = json.loads(item_str) item['index'] = data elif request.method == 'POST': """update item data info.""" sessionstore.put('item_index_{}'.format(pid_value), json.dumps(data), ttl_secs=300) return jsonify(data) except BaseException: current_app.logger.error('Unexpected error: ', sys.exc_info()[0]) return abort(400)
def display_activity(activity_id=0): """Display activity.""" activity = WorkActivity() activity_detail = activity.get_activity_detail(activity_id) item = None if activity_detail is not None and activity_detail.item_id is not None: try: item = ItemsMetadata.get_record(id_=activity_detail.item_id) except NoResultFound as ex: current_app.logger.exception(str(ex)) item = None steps = activity.get_activity_steps(activity_id) history = WorkActivityHistory() histories = history.get_activity_history_list(activity_id) workflow = WorkFlow() workflow_detail = workflow.get_workflow_by_id(activity_detail.workflow_id) if activity_detail.activity_status == \ ActivityStatusPolicy.ACTIVITY_FINALLY \ or activity_detail.activity_status == \ ActivityStatusPolicy.ACTIVITY_CANCEL: activity_detail.activity_status_str = _('End') else: activity_detail.activity_status_str = \ request.args.get('status', 'ToDo') cur_action = activity_detail.action action_endpoint = cur_action.action_endpoint action_id = cur_action.id temporary_comment = activity.get_activity_action_comment( activity_id=activity_id, action_id=action_id) # display_activity of Identifier grant idf_grant_data = None if 'identifier_grant' == action_endpoint and item: path = WekoRecord.get_record(item.id).get('path') if len(path) > 1: community_id = 'Root Index' else: index_address = path.pop(-1).split('/') index_id = Index.query.filter_by(id=index_address.pop()).one() community_id = get_community_id_by_index( index_id.index_name_english) idf_grant_data = Identifier.query.filter_by( repository=community_id).one_or_none() # valid date pidstore_identifier data if idf_grant_data is not None: if not idf_grant_data.jalc_doi: idf_grant_data.jalc_doi = '<Empty>' if not idf_grant_data.jalc_crossref_doi: idf_grant_data.jalc_crossref_doi = '<Empty>' if not idf_grant_data.jalc_datacite_doi: idf_grant_data.jalc_datacite_doi = '<Empty>' if not idf_grant_data.cnri: idf_grant_data.cnri = '<Empty>' if not idf_grant_data.suffix: idf_grant_data.suffix = '<Empty>' temporary_idf_grant = 0 temporary_idf_grant_suffix = [] temporary_identifier = activity.get_action_identifier_grant( activity_id=activity_id, action_id=action_id) if temporary_identifier: temporary_idf_grant = temporary_identifier.get( 'action_identifier_select') temporary_idf_grant_suffix.append( temporary_identifier.get('action_identifier_jalc_doi')) temporary_idf_grant_suffix.append( temporary_identifier.get('action_identifier_jalc_cr_doi')) temporary_idf_grant_suffix.append( temporary_identifier.get('action_identifier_jalc_dc_doi')) temporary_journal = activity.get_action_journal(activity_id=activity_id, action_id=action_id) if temporary_journal: temporary_journal = temporary_journal.action_journal cur_step = action_endpoint step_item_login_url = None approval_record = [] pid = None record = {} need_file = False json_schema = '' schema_form = '' item_save_uri = '' files = [] endpoints = {} links = None if 'item_login' == action_endpoint or 'file_upload' == action_endpoint: activity_session = dict(activity_id=activity_id, action_id=activity_detail.action_id, action_version=cur_action.action_version, action_status=ActionStatusPolicy.ACTION_DOING, commond='') session['activity_info'] = activity_session # get item edit page info. step_item_login_url, need_file, record, json_schema, \ schema_form, item_save_uri, files, endpoints = item_login( item_type_id=workflow_detail.itemtype_id) if item: pid_identifier = PersistentIdentifier.get_by_object( pid_type='depid', object_type='rec', object_uuid=item.id) record = item # if 'approval' == action_endpoint: if item: # get record data for the first time access to editing item screen pid_identifier = PersistentIdentifier.get_by_object( pid_type='depid', object_type='rec', object_uuid=item.id) record_class = import_string('weko_deposit.api:WekoRecord') resolver = Resolver(pid_type='recid', object_type='rec', getter=record_class.get_record) pid, approval_record = resolver.resolve(pid_identifier.pid_value) files = to_files_js(approval_record) # get files data after click Save btn sessionstore = RedisStore( redis.StrictRedis.from_url('redis://{host}:{port}/1'.format( host=os.getenv('INVENIO_REDIS_HOST', 'localhost'), port=os.getenv('INVENIO_REDIS_PORT', '6379')))) if sessionstore.redis.exists('activity_item_' + str(activity_id)): item_str = sessionstore.get('activity_item_' + str(activity_id)) item_json = json.loads(item_str.decode('utf-8')) if 'files' in item_json: files = item_json.get('files') if not files: deposit = WekoDeposit.get_record(item.id) if deposit is not None: files = to_files_js(deposit) from weko_deposit.links import base_factory links = base_factory(pid) res_check = check_authority_action(activity_id, action_id) getargs = request.args ctx = {'community': None} community_id = "" if 'community' in getargs: comm = GetCommunity.get_community_by_id(request.args.get('community')) community_id = request.args.get('community') ctx = {'community': comm} community_id = comm.id # be use for index tree and comment page. if 'item_login' == action_endpoint or 'file_upload' == action_endpoint: session['itemlogin_id'] = activity_id session['itemlogin_activity'] = activity_detail session['itemlogin_item'] = item session['itemlogin_steps'] = steps session['itemlogin_action_id'] = action_id session['itemlogin_cur_step'] = cur_step session['itemlogin_record'] = approval_record session['itemlogin_histories'] = histories session['itemlogin_res_check'] = res_check session['itemlogin_pid'] = pid session['itemlogin_community_id'] = community_id return render_template( 'weko_workflow/activity_detail.html', render_widgets=True, activity=activity_detail, item=item, steps=steps, action_id=action_id, cur_step=cur_step, temporary_comment=temporary_comment, temporary_journal=temporary_journal, temporary_idf_grant=temporary_idf_grant, temporary_idf_grant_suffix=temporary_idf_grant_suffix, idf_grant_data=idf_grant_data, idf_grant_input=IDENTIFIER_GRANT_LIST, idf_grant_method=IDENTIFIER_GRANT_SUFFIX_METHOD, record=approval_record, records=record, step_item_login_url=step_item_login_url, need_file=need_file, jsonschema=json_schema, schemaform=schema_form, id=workflow_detail.itemtype_id, item_save_uri=item_save_uri, files=files, endpoints=endpoints, error_type='item_login_error', links=links, histories=histories, res_check=res_check, pid=pid, community_id=community_id, **ctx)
def prepare_edit_item(): """Prepare_edit_item. Host the api which provide 2 service: Create new activity for editing flow Check permission: check if user is owner/admin/shared user request: header: Content type must be json data: pid_value: pid_value return: The result json: code: status code, msg: meassage result, data: url redirect """ if request.headers['Content-Type'] != 'application/json': """Check header of request""" return jsonify(code=-1, msg=_('Header Error')) post_activity = request.get_json() pid_value = post_activity.get('pid_value') if pid_value: try: record = WekoRecord.get_record_by_pid(pid_value) owner = str(record.get('owner')) shared_id = str(record.get('weko_shared_id')) user_id = str(get_current_user()) is_admin = get_user_roles() activity = WorkActivity() pid_object = PersistentIdentifier.get('recid', pid_value) # check item is being editied item_id = pid_object.object_uuid workflow_action_stt = \ activity.get_workflow_activity_status_by_item_id( item_id=item_id) # show error when has stt is Begin or Doing if workflow_action_stt is not None and \ (workflow_action_stt == ActionStatusPolicy.ACTION_BEGIN or workflow_action_stt == ActionStatusPolicy.ACTION_DOING): return jsonify(code=-13, msg=_('The workflow is being edited. ')) if user_id != owner and not is_admin[0] and user_id != shared_id: return jsonify(code=-1, msg=_('You are not allowed to edit this item.')) lists = ItemTypes.get_latest() if not lists: return jsonify(code=-1, msg=_('You do not even have an itemtype.')) item_type_id = record.get('item_type_id') item_type = ItemTypes.get_by_id(item_type_id) if item_type is None: return jsonify(code=-1, msg=_('This itemtype not found.')) upt_current_activity = activity.upt_activity_detail( item_id=pid_object.object_uuid) if upt_current_activity is not None: post_activity['workflow_id'] = upt_current_activity.workflow_id post_activity['flow_id'] = upt_current_activity.flow_id post_activity['itemtype_id'] = item_type_id getargs = request.args community = getargs.get('community', None) # Create a new version of a record. record = WekoDeposit.get_record(item_id) if record is None: return jsonify(code=-1, msg=_('Record does not exist.')) deposit = WekoDeposit(record, record.model) new_record = deposit.newversion(pid_object) if new_record is None: return jsonify(code=-1, msg=_('An error has occurred.')) rtn = activity.init_activity(post_activity, community, new_record.model.id) if rtn: # GOTO: TEMPORARY EDIT MODE FOR IDENTIFIER identifier_actionid = get_actionid('identifier_grant') identifier = activity.get_action_identifier_grant( upt_current_activity.activity_id, identifier_actionid) if identifier: if identifier.get('action_identifier_select') > \ IDENTIFIER_GRANT_DOI: identifier['action_identifier_select'] = \ IDENTIFIER_GRANT_CAN_WITHDRAW elif identifier.get('action_identifier_select') == \ IDENTIFIER_GRANT_IS_WITHDRAWING: identifier['action_identifier_select'] = \ IDENTIFIER_GRANT_WITHDRAWN activity.create_or_update_action_identifier( rtn.activity_id, identifier_actionid, identifier) if community: comm = GetCommunity.get_community_by_id(community) url_redirect = url_for( 'weko_workflow.display_activity', activity_id=rtn.activity_id, community=comm.id) else: url_redirect = url_for( 'weko_workflow.display_activity', activity_id=rtn.activity_id) return jsonify(code=0, msg='success', data={'redirect': url_redirect}) except Exception as e: current_app.logger.error('Unexpected error: ', str(e)) return jsonify(code=-1, msg=_('An error has occurred.'))
def get_change_dump_manifest_xml(self, record_id): """Get change dump manifest xml. :param record_id: Identifier of record :return xml """ if not self._is_record_in_index(record_id) or not self._validation(): return None cdm = ChangeDumpManifest() cdm.up = '{}resync/{}/changedump.xml'.format(request.url_root, self.repository_id) if self.change_dump_manifest: prev_id, prev_ver_id = record_id.split(".") current_record = WekoRecord.get_record_by_pid(record_id) from .utils import get_pid prev_record_pid = get_pid('{}.{}'.format(prev_id, str(int(prev_ver_id) - 1))) if prev_record_pid: prev_record = WekoRecord.get_record( id_=prev_record_pid.object_uuid) else: prev_record = None if current_record: list_file = [file for file in current_record.files] current_checksum = [ file.info().get('checksum') for file in current_record.files ] prev_checksum = [] if prev_record: list_file.extend([file for file in prev_record.files]) prev_checksum = [ file.info().get('checksum') for file in prev_record.files ] for file in list_file: file_info = file.info() change = None if file_info.get('checksum') in prev_checksum: if file_info.get('checksum') in current_checksum: change = None if file_info.get('checksum') not in current_checksum: change = 'deleted' else: if file_info.get('checksum') in current_checksum: change = 'created' path = 'recid_{}/{}'.format(current_record.get('recid'), file_info.get('key')) lastmod = str(datetime.datetime.utcnow().replace( tzinfo=datetime.timezone.utc).isoformat()) if change: re = Resource( '{}record/{}/files/{}'.format( request.url_root, current_record.get('recid'), file_info.get('key')), lastmod=lastmod, sha256=file_info.get('checksum').split(':')[1], length=str(file_info.get('size')), path=path if change != 'delete' else '', change=change) cdm.add(re) return cdm.as_xml()
def default_view_method(pid, record, filename=None, template=None, **kwargs): """Display default view. Sends record_viewed signal and renders template. :param pid: PID object. :param record: Record object. :param filename: File name. :param template: Template to render. :param kwargs: Additional view arguments based on URL rule. :returns: The rendered template. """ # Get PID version object to retrieve all versions of item pid_ver = PIDVersioning(child=pid) if not pid_ver.exists or pid_ver.is_last_child: abort(404) active_versions = list(pid_ver.children or []) all_versions = list( pid_ver.get_children(ordered=True, pid_status=None) or []) try: if WekoRecord.get_record(id_=active_versions[-1].object_uuid )['_deposit']['status'] == 'draft': active_versions.pop() if WekoRecord.get_record(id_=all_versions[-1].object_uuid )['_deposit']['status'] == 'draft': all_versions.pop() except Exception: pass if active_versions: # active_versions.remove(pid_ver.last_child) active_versions.pop() check_site_license_permission() check_items_settings() send_info = {} send_info['site_license_flag'] = True \ if hasattr(current_user, 'site_license_flag') else False send_info['site_license_name'] = current_user.site_license_name \ if hasattr(current_user, 'site_license_name') else '' record_viewed.send(current_app._get_current_object(), pid=pid, record=record, info=send_info) community_arg = request.args.get('community') community_id = "" ctx = {'community': None} if community_arg: from weko_workflow.api import GetCommunity comm = GetCommunity.get_community_by_id(community_arg) ctx = {'community': comm} community_id = comm.id # Get index style style = IndexStyle.get( current_app.config['WEKO_INDEX_TREE_STYLE_OPTIONS']['id']) width = style.width if style else '3' height = style.height if style else None detail_condition = get_search_detail_keyword('') # Add Item Reference data to Record Metadata pid_without_ver = record.get("recid").split('.')[0] res = ItemLink.get_item_link_info(pid_without_ver) if res: record["relation"] = res else: record["relation"] = {} google_scholar_meta = _get_google_scholar_meta(record) pdfcoverpage_set_rec = PDFCoverPageSettings.find(1) # Check if user has the permission to download original pdf file # and the cover page setting is set and its value is enable (not disabled) can_download_original = check_original_pdf_download_permission(record) \ and pdfcoverpage_set_rec and pdfcoverpage_set_rec.avail != 'disable' # Get item meta data record['permalink_uri'] = None permalink = get_record_permalink(record) if not permalink: record['permalink_uri'] = request.url else: record['permalink_uri'] = permalink can_update_version = has_update_version_role(current_user) datastore = RedisStore( redis.StrictRedis.from_url(current_app.config['CACHE_REDIS_URL'])) cache_key = current_app.config['WEKO_ADMIN_CACHE_PREFIX'].\ format(name='display_stats') if datastore.redis.exists(cache_key): curr_display_setting = datastore.get(cache_key).decode('utf-8') display_stats = True if curr_display_setting == 'True' else False else: display_stats = True groups_price = get_groups_price(record) billing_files_permission = get_billing_file_download_permission( groups_price) if groups_price else None billing_files_prices = get_min_price_billing_file_download( groups_price, billing_files_permission) if groups_price else None from weko_theme.utils import get_design_layout # Get the design for widget rendering page, render_widgets = get_design_layout( request.args.get('community') or current_app.config['WEKO_THEME_DEFAULT_COMMUNITY']) if hasattr(current_i18n, 'language'): index_link_list = get_index_link_list(current_i18n.language) else: index_link_list = get_index_link_list() files_thumbnail = [] if record.files: files_thumbnail = ObjectVersion.get_by_bucket( record.get('_buckets').get('deposit')).\ filter_by(is_thumbnail=True).all() files = [] for f in record.files: if check_file_permission(record, f.data) or is_open_restricted(f.data): files.append(f) # Flag: can edit record can_edit = True if pid == get_record_without_version(pid) else False open_day_display_flg = current_app.config.get('OPEN_DATE_DISPLAY_FLG') return render_template(template, pid=pid, pid_versioning=pid_ver, active_versions=active_versions, all_versions=all_versions, record=record, files=files, display_stats=display_stats, filename=filename, can_download_original_pdf=can_download_original, is_logged_in=current_user and current_user.is_authenticated, can_update_version=can_update_version, page=page, render_widgets=render_widgets, community_id=community_id, width=width, detail_condition=detail_condition, height=height, index_link_enabled=style.index_link_enabled, index_link_list=index_link_list, google_scholar_meta=google_scholar_meta, billing_files_permission=billing_files_permission, billing_files_prices=billing_files_prices, files_thumbnail=files_thumbnail, can_edit=can_edit, open_day_display_flg=open_day_display_flg, **ctx, **kwargs)
def listrecords(**kwargs): """Create OAI-PMH response for verb ListRecords.""" def get_error_code_msg(): """Get error by type.""" code = current_app.config.get('OAISERVER_CODE_NO_RECORDS_MATCH') msg = current_app.config.get('OAISERVER_MESSAGE_NO_RECORDS_MATCH') return [(code, msg)] def append_deleted_record(e_listrecords, pid_object, rec): """Append attribute [status="deleted] for 'header' tag.""" e_record = SubElement(e_listrecords, etree.QName(NS_OAIPMH, 'record')) header(e_record, identifier=pid_object.pid_value, datestamp=rec.updated, sets=rec.get('_oai', {}).get('sets', []), deleted=True) record_dumper = serializer(kwargs['metadataPrefix']) e_tree, e_listrecords = verb(**kwargs) result = get_records(**kwargs) identify = OaiIdentify.get_all() if not result.total or not identify or \ (identify and not identify.outPutSetting): return error(get_error_code_msg(), **kwargs) for record in result.items: try: pid = oaiid_fetcher(record['id'], record['json']['_source']) pid_object = OAIIDProvider.get(pid_value=pid.pid_value).pid rec = WekoRecord.get_record(record['id']) set_identifier(record, rec) # Check output delete, noRecordsMatch if not is_private_index(rec): if is_deleted_workflow(pid_object) or \ is_private_workflow(rec): append_deleted_record(e_listrecords, pid_object, rec) continue else: append_deleted_record(e_listrecords, pid_object, rec) continue e_record = SubElement(e_listrecords, etree.QName(NS_OAIPMH, 'record')) header( e_record, identifier=pid.pid_value, datestamp=record['updated'], sets=record['json']['_source'].get('_oai', {}).get('sets', []), ) e_metadata = SubElement(e_record, etree.QName(NS_OAIPMH, 'metadata')) etree_record = copy.deepcopy(record['json']) # Merge licensetype and licensefree handle_license_free(etree_record['_source']['_item_metadata']) e_metadata.append(record_dumper(pid, etree_record)) except Exception: current_app.logger.error(traceback.print_exc()) current_app.logger.error('Error when exporting item id ' + str(record['id'])) # Check <record> tag not exist. if len(e_listrecords) == 0: return error(get_error_code_msg(), **kwargs) resumption_token(e_listrecords, result, **kwargs) return e_tree