From 404f6ff6d542dc6dc61395cdb25646e3a69eb061 Mon Sep 17 00:00:00 2001 From: Bryan Newbold Date: Thu, 13 Jun 2019 14:24:16 -0700 Subject: implement major refactor for other entity types --- python/fatcat_web/editing_routes.py | 255 ++++++++++------------- python/fatcat_web/entity_helpers.py | 135 ++++++++++-- python/fatcat_web/routes.py | 205 ++++++++---------- python/fatcat_web/templates/changelog_view.html | 1 + python/fatcat_web/templates/container_edit.html | 3 +- python/fatcat_web/templates/container_view.html | 34 +-- python/fatcat_web/templates/creator_view.html | 8 +- python/fatcat_web/templates/editgroup_view.html | 2 +- python/fatcat_web/templates/file_edit.html | 8 +- python/fatcat_web/templates/file_view.html | 4 +- python/fatcat_web/templates/fileset_view.html | 8 +- python/fatcat_web/templates/release_edit.html | 8 +- python/fatcat_web/templates/release_view.html | 80 +++---- python/fatcat_web/templates/webcapture_view.html | 6 +- python/fatcat_web/templates/work_view.html | 8 +- 15 files changed, 405 insertions(+), 360 deletions(-) (limited to 'python') diff --git a/python/fatcat_web/editing_routes.py b/python/fatcat_web/editing_routes.py index c8cebd62..73db76a6 100644 --- a/python/fatcat_web/editing_routes.py +++ b/python/fatcat_web/editing_routes.py @@ -47,8 +47,6 @@ def form_editgroup_get_or_create(api, edit_form): .format(eg.editgroup_id, eg.editgroup_id)) return eg -### Views ################################################################### - def generic_entity_edit(editgroup_id, entity_type, existing_ident, edit_template): """ @@ -99,6 +97,10 @@ def generic_entity_edit(editgroup_id, entity_type, existing_ident, edit_template status = 200 if entity_type == 'container': form = ContainerEntityForm() + elif entity_type == 'file': + form = FileEntityForm() + elif entity_type == 'release': + form = ReleaseEntityForm() else: raise NotImplementedError @@ -116,6 +118,10 @@ def generic_entity_edit(editgroup_id, entity_type, existing_ident, edit_template try: if entity_type == 'container': edit = user_api.create_container(editgroup.editgroup_id, entity) + elif entity_type == 'file': + edit = user_api.create_file(editgroup.editgroup_id, entity) + elif entity_type == 'release': + edit = user_api.create_release(editgroup.editgroup_id, entity) else: raise NotImplementedError except ApiException as ae: @@ -138,6 +144,10 @@ def generic_entity_edit(editgroup_id, entity_type, existing_ident, edit_template try: if entity_type == 'container': user_api.delete_container_edit(editgroup.editgroup_id, existing_edit.edit_id) + elif entity_type == 'file': + user_api.delete_file_edit(editgroup.editgroup_id, existing_edit.edit_id) + elif entity_type == 'release': + user_api.delete_release_edit(editgroup.editgroup_id, existing_edit.edit_id) else: raise NotImplementedError except ApiException as ae: @@ -148,6 +158,10 @@ def generic_entity_edit(editgroup_id, entity_type, existing_ident, edit_template try: if entity_type == 'container': edit = user_api.update_container(editgroup.editgroup_id, existing.ident, existing) + elif entity_type == 'file': + edit = user_api.update_file(editgroup.editgroup_id, existing.ident, existing) + elif entity_type == 'release': + edit = user_api.update_release(editgroup.editgroup_id, existing.ident, existing) else: raise NotImplementedError except ApiException as ae: @@ -164,6 +178,10 @@ def generic_entity_edit(editgroup_id, entity_type, existing_ident, edit_template if existing: if entity_type == 'container': form = ContainerEntityForm.from_entity(existing) + elif entity_type == 'file': + form = FileEntityForm.from_entity(existing) + elif entity_type == 'release': + form = ReleaseEntityForm.from_entity(existing) else: raise NotImplementedError @@ -201,6 +219,10 @@ def generic_edit_delete(editgroup_id, entity_type, edit_id): try: if entity_type == 'container': user_api.delete_container_edit(editgroup.editgroup_id, edit_id) + elif entity_type == 'file': + user_api.delete_file_edit(editgroup.editgroup_id, edit_id) + elif entity_type == 'release': + user_api.delete_release_edit(editgroup.editgroup_id, edit_id) else: raise NotImplementedError except ApiException as ae: @@ -208,9 +230,11 @@ def generic_edit_delete(editgroup_id, entity_type, edit_id): return redirect("/editgroup/{}".format(editgroup_id)) +### Views ################################################################### + @app.route('/container/create', methods=['GET', 'POST']) @login_required -def container_create(): +def container_create_view(): return generic_entity_edit(None, 'container', None, 'container_create.html') @app.route('/container//edit', methods=['GET', 'POST']) @@ -228,175 +252,110 @@ def container_editgroup_edit(editgroup_id, ident): def container_edit_delete(editgroup_id, edit_id): return generic_edit_delete(editgroup_id, 'container', edit_id) -@app.route('/creator//edit', methods=['GET']) -def creator_edit(ident): - return render_template('entity_edit.html'), 404 - -@app.route('/creator/create', methods=['GET']) -def creator_create_view(): - return abort(404) - @app.route('/file/create', methods=['GET', 'POST']) @login_required -def file_create(): - form = FileEntityForm() - status = 200 - if form.is_submitted(): - if form.validate_on_submit(): - # API on behalf of user - user_api = auth_api(session['api_token']) - eg = form_editgroup_get_or_create(user_api, form) - if eg: - # no merge or anything hard to do; just create the entity - entity = form.to_entity() - try: - edit = user_api.create_file(eg.editgroup_id, entity) - except ApiException as ae: - app.log.warning(ae) - abort(ae.status) - # redirect to new entity - return redirect('/file/{}'.format(edit.ident)) - else: - status = 400 - elif form.errors: - status = 400 - app.log.info("form errors (did not validate): {}".format(form.errors)) - else: - form.urls.append_entry() - form.release_ids.append_entry() - return render_template('file_create.html', form=form), status +def file_create_view(): + return generic_entity_edit(None, 'file', None, 'file_create.html') @app.route('/file//edit', methods=['GET', 'POST']) @login_required def file_edit(ident): - # TODO: prev_rev interlock - try: - entity = api.get_file(ident) - except ApiException as ae: - abort(ae.status) - status = 200 - form = FileEntityForm() - if form.is_submitted(): - if form.validate_on_submit(): - # API on behalf of user - user_api = auth_api(session['api_token']) - eg = form_editgroup_get_or_create(user_api, form) - if eg: - # all the tricky logic is in the update method - form.update_entity(entity) - try: - edit = user_api.update_file(eg.editgroup_id, entity.ident, entity) - except ApiException as ae: - app.log.warning(ae) - abort(ae.status) - # redirect to entity revision - # TODO: file_rev_view - return redirect('/file/{}'.format(edit.ident)) - else: - status = 400 - elif form.errors: - status = 400 - app.log.info("form errors (did not validate): {}".format(form.errors)) - else: # not submitted - form = FileEntityForm.from_entity(entity) - return render_template('file_edit.html', form=form, entity=entity), status + return generic_entity_edit(None, 'file', ident, 'file_edit.html') -@app.route('/fileset//edit', methods=['GET']) -def fileset_edit(ident): - try: - entity = api.get_fileset(ident) - except ApiException as ae: - abort(ae.status) +@app.route('/editgroup//file//edit', methods=['GET', 'POST']) +@login_required +def file_editgroup_edit(editgroup_id, ident): + return generic_entity_edit(editgroup_id, 'file', ident, 'file_edit.html') + +@app.route('/editgroup//file/edit//delete', methods=['POST']) +@login_required +def file_edit_delete(editgroup_id, edit_id): + return generic_edit_delete(editgroup_id, 'file', edit_id) + +@app.route('/release/create', methods=['GET', 'POST']) +@login_required +def release_create_view(): + return generic_entity_edit(None, 'release', None, 'release_create.html') + +@app.route('/release//edit', methods=['GET', 'POST']) +@login_required +def release_edit(ident): + return generic_entity_edit(None, 'release', ident, 'release_edit.html') + +@app.route('/editgroup//release//edit', methods=['GET', 'POST']) +@login_required +def release_editgroup_edit(editgroup_id, ident): + return generic_entity_edit(editgroup_id, 'release', ident, 'release_edit.html') + +@app.route('/editgroup//release/edit//delete', methods=['POST']) +@login_required +def release_edit_delete(editgroup_id, edit_id): + return generic_edit_delete(editgroup_id, 'release', edit_id) + + +### Not-Implemented Views ################################################### + +@app.route('/creator/create', methods=['GET']) +def creator_create_view(): + return abort(404) + +@app.route('/creator//edit', methods=['GET']) +def creator_edit(ident): return render_template('entity_edit.html'), 404 +@app.route('/editgroup//creator//edit', methods=['GET', 'POST']) +def creator_editgroup_edit(editgroup_id, ident): + return abort(404) + +@app.route('/editgroup//creator/edit//delete', methods=['POST']) +def creator_edit_delete(editgroup_id, edit_id): + return abort(404) + @app.route('/fileset/create', methods=['GET']) def fileset_create_view(): return abort(404) -@app.route('/webcapture//edit', methods=['GET']) -def webcapture_edit(ident): - try: - entity = api.get_webcapture(ident) - except ApiException as ae: - abort(ae.status) +@app.route('/fileset//edit', methods=['GET']) +def fileset_edit(ident): return render_template('entity_edit.html'), 404 +@app.route('/editgroup//fileset//edit', methods=['GET', 'POST']) +def fileset_editgroup_edit(editgroup_id, ident): + return abort(404) + +@app.route('/editgroup//fileset/edit//delete', methods=['POST']) +def fileset_edit_delete(editgroup_id, edit_id): + return abort(404) + @app.route('/webcapture/create', methods=['GET']) def webcapture_create_view(): return abort(404) -@app.route('/release/create', methods=['GET', 'POST']) -@login_required -def release_create(): - form = ReleaseEntityForm() - status = 200 - if form.is_submitted(): - if form.validate_on_submit(): - # API on behalf of user - user_api = auth_api(session['api_token']) - eg = form_editgroup_get_or_create(user_api, form) - if eg: - # no merge or anything hard to do; just create the entity - entity = form.to_entity() - try: - edit = user_api.create_release(eg.editgroup_id, entity) - except ApiException as ae: - app.log.warning(ae) - abort(ae.status) - # redirect to new release - return redirect('/release/{}'.format(edit.ident)) - else: - status = 400 - elif form.errors: - status = 400 - app.log.info("form errors (did not validate): {}".format(form.errors)) - else: # not submitted - form.contribs.append_entry() - return render_template('release_create.html', form=form), status +@app.route('/webcapture//edit', methods=['GET']) +def webcapture_edit(ident): + return render_template('entity_edit.html'), 404 -@app.route('/release//edit', methods=['GET', 'POST']) -@login_required -def release_edit(ident): - # TODO: prev_rev interlock - try: - entity = api.get_release(ident) - except ApiException as ae: - abort(ae.status) - status = 200 - form = ReleaseEntityForm() - if form.is_submitted(): - if form.validate_on_submit(): - # API on behalf of user - user_api = auth_api(session['api_token']) - eg = form_editgroup_get_or_create(user_api, form) - if eg: - # all the tricky logic is in the update method - form.update_entity(entity) - try: - edit = user_api.update_release(eg.editgroup_id, entity.ident, entity) - except ApiException as ae: - app.log.warning(ae) - abort(ae.status) - # redirect to entity revision - # TODO: release_rev_view - return redirect('/release/{}'.format(edit.ident)) - else: - status = 400 - elif form.errors: - status = 400 - app.log.info("form errors (did not validate): {}".format(form.errors)) - else: # not submitted - form = ReleaseEntityForm.from_entity(entity) - return render_template('release_edit.html', form=form, entity=entity), status +@app.route('/editgroup//webcapture//edit', methods=['GET', 'POST']) +def webcapture_editgroup_edit(editgroup_id, ident): + return abort(404) + +@app.route('/editgroup//webcapture/edit//delete', methods=['POST']) +def webcapture_edit_delete(editgroup_id, edit_id): + return abort(404) @app.route('/work/create', methods=['GET']) def work_create_view(): return abort(404) @app.route('/work//edit', methods=['GET']) -def work_edit_view(ident): - try: - entity = api.get_work(ident) - except ApiException as ae: - abort(ae.status) +def work_edit(ident): return render_template('entity_edit.html'), 404 + +@app.route('/editgroup//work//edit', methods=['GET', 'POST']) +def work_editgroup_edit(editgroup_id, ident): + return abort(404) + +@app.route('/editgroup//work/edit//delete', methods=['POST']) +def work_edit_delete(editgroup_id, edit_id): + return abort(404) + diff --git a/python/fatcat_web/entity_helpers.py b/python/fatcat_web/entity_helpers.py index 8a28deb3..b3cda67f 100644 --- a/python/fatcat_web/entity_helpers.py +++ b/python/fatcat_web/entity_helpers.py @@ -2,16 +2,105 @@ from flask import abort from fatcat_client.rest import ApiException from fatcat_tools.transforms import * -from fatcat_web import api +from fatcat_web import app, api +from fatcat_web.search import get_elastic_container_stats +from fatcat_web.hacks import strip_extlink_xml, wayback_suffix +def enrich_container_entity(entity): + if entity.state in ('redirect', 'deleted'): + return entity + if entity.state == "active": + entity._es = container_to_elasticsearch(entity, force_bool=False) + entity._stats = None + if entity.issnl: + try: + entity._stats = get_elastic_container_stats(entity.issnl) + except Exception as e: + app.log.error(e) + pass + return entity + +def enrich_creator_entity(entity): + if entity.state in ('redirect', 'deleted'): + return entity + entity._releases = None + if entity.state in ('active', 'wip'): + entity._releases = api.get_creator_releases(entity.ident) + return entity + +def enrich_file_entity(entity): + return entity + +def enrich_fileset_entity(entity): + if entity.state in ('redirect', 'deleted'): + return entity + entity._total_size = None + if entity.manifest != None: + entity._total_size = sum([f.size for f in entity.manifest]) or 0 + return entity + +def enrich_webcapture_entity(entity): + if entity.state in ('redirect', 'deleted'): + return entity + entity.wayback_suffix = wayback_suffix(entity) + return entity + +def enrich_release_entity(entity): + if entity.state in ('redirect', 'deleted'): + return entity + if entity.state == "active": + entity._es = release_to_elasticsearch(entity, force_bool=False) + if entity.container and entity.container.state == "active": + entity.container._es = container_to_elasticsearch(entity.container, force_bool=False) + if entity.filesets: + for fs in entity.filesets: + fs._total_size = sum([f.size for f in fs.manifest]) + if entity.webcaptures: + for wc in entity.webcaptures: + wc._wayback_suffix = wayback_suffix(wc) + for ref in entity.refs: + # this is a UI hack to get rid of XML crud in unstructured refs like: + # LOCKSS (2014) Available: http://lockss.org/. Accessed: 2014 + # November 1. + if ref.extra and ref.extra.get('unstructured'): + ref.extra['unstructured'] = strip_extlink_xml(ref.extra['unstructured']) + # author list to display; ensure it's sorted by index (any othors with + # index=None go to end of list) + authors = [c for c in entity.contribs if c.role in ('author', None)] + entity._authors = sorted(authors, key=lambda c: (c.index == None and 99999999) or c.index) + # hack to show plain text instead of latex abstracts + if entity.abstracts: + if 'latex' in entity.abstracts[0].mimetype: + entity.abstracts.reverse() + return entity + +def enrich_work_entity(entity): + if entity.state in ('redirect', 'deleted'): + return entity + entity._releases = None + if entity.state in ('active', 'wip'): + entity._releases = api.get_work_releases(entity.ident) + return entity def generic_get_entity(entity_type, ident): try: if entity_type == 'container': - entity = api.get_container(ident) - if entity.state == "active": - entity.es = container_to_elasticsearch(entity, force_bool=False) - return entity + return enrich_container_entity(api.get_container(ident)) + elif entity_type == 'creator': + return enrich_creator_entity(api.get_creator(ident)) + elif entity_type == 'file': + return enrich_file_entity(api.get_file(ident, expand="releases")) + elif entity_type == 'fileset': + return enrich_fileset_entity(api.get_fileset(ident, expand="releases")) + elif entity_type == 'webcapture': + return enrich_webcapture_entity(api.get_webcapture(ident, expand="releases")) + elif entity_type == 'release': + return enrich_release_entity(api.get_release(ident, expand="container,files,filesets,webcaptures")) + elif entity_type == 'work': + return api.get_work(ident) else: raise NotImplementedError except ApiException as ae: @@ -20,8 +109,19 @@ def generic_get_entity(entity_type, ident): def generic_get_entity_revision(entity_type, revision_id): try: if entity_type == 'container': - entity = api.get_container_revision(revision_id) - return entity + return enrich_container_entity(api.get_container_revision(revision_id)) + elif entity_type == 'creator': + return enrich_creator_entity(api.get_creator_revision(revision_id)) + elif entity_type == 'file': + return enrich_file_entity(api.get_file_revision(revision_id, expand="releases")) + elif entity_type == 'fileset': + return enrich_fileset_entity(api.get_fileset_revision(revision_id, expand="releases")) + elif entity_type == 'webcapture': + return enrich_webcapture_entity(api.get_webcapture_revision(revision_id, expand="releases")) + elif entity_type == 'release': + return enrich_release_entity(api.get_release_revision(revision_id, expand="container")) + elif entity_type == 'work': + return enrich_work_entity(api.get_work_revision(revision_id)) else: raise NotImplementedError except ApiException as ae: @@ -30,6 +130,18 @@ def generic_get_entity_revision(entity_type, revision_id): def generic_get_editgroup_entity(editgroup, entity_type, ident): if entity_type == 'container': edits = editgroup.edits.containers + elif entity_type == 'creator': + edits = editgroup.edits.creators + elif entity_type == 'file': + edits = editgroup.edits.files + elif entity_type == 'fileset': + edits = editgroup.edits.filesets + elif entity_type == 'webcapture': + edits = editgroup.edits.webcaptures + elif entity_type == 'release': + edits = editgroup.edits.releases + elif entity_type == 'work': + edits = editgroup.edits.works else: raise NotImplementedError revision_id = None @@ -41,12 +153,7 @@ def generic_get_editgroup_entity(editgroup, entity_type, ident): if not revision_id: # couldn't find relevent edit in this editgroup abort(404) - try: - if entity_type == 'container': - entity = api.get_container_revision(revision_id) - else: - raise NotImplementedError - except ApiException as ae: - abort(ae.status) + + entity = generic_get_entity_revision(entity_type, revision_id) entity.ident = ident return entity, edit diff --git a/python/fatcat_web/routes.py b/python/fatcat_web/routes.py index 6211b90c..9af0724e 100644 --- a/python/fatcat_web/routes.py +++ b/python/fatcat_web/routes.py @@ -13,7 +13,6 @@ from fatcat_web import app, api, auth_api, priv_api, mwoauth from fatcat_web.auth import handle_token_login, handle_logout, load_user, handle_ia_xauth, handle_wmoauth from fatcat_web.cors import crossdomain from fatcat_web.search import * -from fatcat_web.hacks import strip_extlink_xml, wayback_suffix from fatcat_web.entity_helpers import * @@ -189,149 +188,125 @@ def release_lookup(): def work_lookup(): abort(404) -### Entity Views ############################################################ +### More Generic Entity Views ############################################### -@app.route('/container/', methods=['GET']) -def container_view(ident): - entity = generic_get_entity('container', ident) - - if entity.issnl: - try: - stats = get_elastic_container_stats(entity.issnl) - except Exception as e: - stats = None - app.log.error(e) - else: - stats = None +def generic_entity_view(entity_type, ident, view_template): + entity = generic_get_entity(entity_type, ident) if entity.state == "redirect": - return redirect('/container/{}'.format(entity.redirect)) + return redirect('/{}/{}'.format(entity_type, entity.redirect)) + elif entity.state == "deleted": + return render_template('deleted_entity.html', entity_type=entity_type, entity=entity) + + return render_template(view_template, entity=entity, editgroup_id=None) + +def generic_editgroup_entity_view(editgroup_id, entity_type, ident, view_template): + try: + editgroup = api.get_editgroup(editgroup_id) + except ApiException as ae: + abort(ae.status) + + entity, edit = generic_get_editgroup_entity(editgroup, entity_type, ident) + if entity.state == "deleted": - return render_template('deleted_entity.html', entity=entity, entity_type="container") - if entity.state == "active": - entity.es = container_to_elasticsearch(entity, force_bool=False) - return render_template('container_view.html', - container=entity, editgroup_id=None, container_stats=stats) + return render_template('deleted_entity.html', entity=entity, + entity_type=entity_type, editgroup=editgroup) + + return render_template(view_template, entity=entity, editgroup=editgroup) + + +@app.route('/container/', methods=['GET']) +def container_view(ident): + return generic_entity_view('container', ident, 'container_view.html') @app.route('/container/rev/', methods=['GET']) def container_revision_view(revision_id): entity = generic_get_entity_revision('container', revision_id) - return render_template('container_view.html', container=entity, editgroup=None) + return render_template('container_view.html', entity=entity, editgroup=None) @app.route('/editgroup//container/', methods=['GET']) def container_editgroup_view(editgroup_id, ident): - try: - editgroup = api.get_editgroup(editgroup_id) - except ApiException as ae: - abort(ae.status) - entity, edit = generic_get_editgroup_entity(editgroup, 'container', ident) - if entity.state == "deleted": - return render_template('deleted_entity.html', entity=entity, entity_type="container", editgroup=editgroup) - return render_template('container_view.html', container=entity, editgroup=editgroup) + return generic_editgroup_entity_view(editgroup_id, 'container', ident, 'container_view.html') + @app.route('/creator/', methods=['GET']) def creator_view(ident): - try: - entity = api.get_creator(ident) - releases = api.get_creator_releases(ident) - except ApiException as ae: - abort(ae.status) - if entity.state == "redirect": - return redirect('/creator/{}'.format(entity.redirect)) - if entity.state == "deleted": - return render_template('deleted_entity.html', entity=entity, entity_type="creator") - return render_template('creator_view.html', creator=entity, releases=releases) + return generic_entity_view('creator', ident, 'creator_view.html') + +@app.route('/creator/rev/', methods=['GET']) +def creator_revision_view(revision_id): + entity = generic_get_entity_revision('creator', revision_id) + return render_template('creator_view.html', creator=entity, editgroup=None) + +@app.route('/editgroup//creator/', methods=['GET']) +def creator_editgroup_view(editgroup_id, ident): + return generic_editgroup_entity_view(editgroup_id, 'creator', ident, 'creator_view.html') @app.route('/file/', methods=['GET']) def file_view(ident): - try: - entity = api.get_file(ident, expand="releases") - except ApiException as ae: - abort(ae.status) - if entity.state == "redirect": - return redirect('/file/{}'.format(entity.redirect)) - elif entity.state == "deleted": - return render_template('deleted_entity.html', entity=entity, entity_type="file") - return render_template('file_view.html', file=entity) + return generic_entity_view('file', ident, 'file_view.html') + +@app.route('/file/rev/', methods=['GET']) +def file_revision_view(revision_id): + entity = generic_get_entity_revision('file', revision_id) + return render_template('file_view.html', entity=entity, editgroup=None) + +@app.route('/editgroup//file/', methods=['GET']) +def file_editgroup_view(editgroup_id, ident): + return generic_editgroup_entity_view(editgroup_id, 'file', ident, 'file_view.html') @app.route('/fileset/', methods=['GET']) def fileset_view(ident): - try: - entity = api.get_fileset(ident, expand="releases") - except ApiException as ae: - abort(ae.status) - if entity.state == "redirect": - return redirect('/fileset/{}'.format(entity.redirect)) - elif entity.state == "deleted": - return render_template('deleted_entity.html', entity=entity, entity_type="fileset") - else: - entity.total_size = sum([f.size for f in entity.manifest]) - return render_template('fileset_view.html', fileset=entity) + return generic_entity_view('fileset', ident, 'fileset_view.html') + +@app.route('/fileset/rev/', methods=['GET']) +def fileset_revision_view(revision_id): + entity = generic_get_entity_revision('fileset', revision_id) + return render_template('fileset_view.html', entity=entity, editgroup=None) + +@app.route('/editgroup//fileset/', methods=['GET']) +def fileset_editgroup_view(editgroup_id, ident): + return generic_editgroup_entity_view(editgroup_id, 'fileset', ident, 'fileset_view.html') @app.route('/webcapture/', methods=['GET']) def webcapture_view(ident): - try: - entity = api.get_webcapture(ident, expand="releases") - except ApiException as ae: - abort(ae.status) - if entity.state == "redirect": - return redirect('/webcapture/{}'.format(entity.redirect)) - elif entity.state == "deleted": - return render_template('deleted_entity.html', entity=entity, entity_type="webcapture") - entity.wayback_suffix = wayback_suffix(entity) - #print("SUFFIX: {}".format(entity.wayback_suffix)) - return render_template('webcapture_view.html', webcapture=entity) + return generic_entity_view('webcapture', ident, 'webcapture_view.html') + +@app.route('/webcapture/rev/', methods=['GET']) +def webcapture_revision_view(revision_id): + entity = generic_get_entity_revision('webcapture', revision_id) + return render_template('webcapture_view.html', entity=entity, editgroup=None) + +@app.route('/editgroup//webcapture/', methods=['GET']) +def webcapture_editgroup_view(editgroup_id, ident): + return generic_editgroup_entity_view(editgroup_id, 'webcapture', ident, 'webcapture_view.html') @app.route('/release/', methods=['GET']) def release_view(ident): - try: - entity = api.get_release(ident, expand="container,files,filesets,webcaptures") - except ApiException as ae: - abort(ae.status) - if entity.state == "redirect": - return redirect('/release/{}'.format(entity.redirect)) - if entity.state == "deleted": - return render_template('deleted_entity.html', entity=entity, entity_type="release") - if entity.container and entity.container.state == "active": - entity.container.es = container_to_elasticsearch(entity.container, force_bool=False) - if entity.state == "active": - entity.es = release_to_elasticsearch(entity, force_bool=False) - for fs in entity.filesets: - fs.total_size = sum([f.size for f in fs.manifest]) - for wc in entity.webcaptures: - wc.wayback_suffix = wayback_suffix(wc) - for ref in entity.refs: - # this is a UI hack to get rid of XML crud in unstructured refs like: - # LOCKSS (2014) Available: http://lockss.org/. Accessed: 2014 - # November 1. - if ref.extra and ref.extra.get('unstructured'): - ref.extra['unstructured'] = strip_extlink_xml(ref.extra['unstructured']) - # author list to display; ensure it's sorted by index (any othors with - # index=None go to end of list) - authors = [c for c in entity.contribs if c.role in ('author', None)] - authors = sorted(authors, key=lambda c: (c.index == None and 99999999) or c.index) - # hack to show plain text instead of latex abstracts - if entity.abstracts: - if 'latex' in entity.abstracts[0].mimetype: - entity.abstracts.reverse() - return render_template('release_view.html', release=entity, - authors=authors, container=entity.container) + return generic_entity_view('release', ident, 'release_view.html') + +@app.route('/release/rev/', methods=['GET']) +def release_revision_view(revision_id): + entity = generic_get_entity_revision('release', revision_id) + return render_template('release_view.html', entity=entity, editgroup=None) + +@app.route('/editgroup//release/', methods=['GET']) +def release_editgroup_view(editgroup_id, ident): + return generic_editgroup_entity_view(editgroup_id, 'release', ident, 'release_view.html') @app.route('/work/', methods=['GET']) def work_view(ident): - try: - entity = api.get_work(ident) - releases = api.get_work_releases(ident) - except ApiException as ae: - abort(ae.status) - if entity.state == "redirect": - return redirect('/work/{}'.format(entity.redirect)) - if entity.state == "deleted": - return render_template('deleted_entity.html', entity=entity, entity_type="work") - return render_template('work_view.html', work=entity, releases=releases) + return generic_entity_view('work', ident, 'work_view.html') + +@app.route('/work/rev/', methods=['GET']) +def work_revision_view(revision_id): + entity = generic_get_entity_revision('work', revision_id) + return render_template('work_view.html', entity=entity, editgroup=None) + +@app.route('/editgroup//work/', methods=['GET']) +def work_editgroup_view(editgroup_id, ident): + return generic_editgroup_entity_view(editgroup_id, 'work', ident, 'work_view.html') + ### Views ################################################################### diff --git a/python/fatcat_web/templates/changelog_view.html b/python/fatcat_web/templates/changelog_view.html index 8c4684d5..5b403b09 100644 --- a/python/fatcat_web/templates/changelog_view.html +++ b/python/fatcat_web/templates/changelog_view.html @@ -1,3 +1,4 @@ +{% set auth_to = {} %} {% extends "editgroup_view.html" %} {% block editgroupheader %} diff --git a/python/fatcat_web/templates/container_edit.html b/python/fatcat_web/templates/container_edit.html index 91432d5e..238335b4 100644 --- a/python/fatcat_web/templates/container_edit.html +++ b/python/fatcat_web/templates/container_edit.html @@ -10,7 +10,7 @@ {% endblock %} {{ form.hidden_tag() }} -

Editgroup

+

Editgroup Metadata

{{ edit_macros.editgroup_dropdown(form, editgroup, potential_editgroups) }}

The Basics

@@ -70,7 +70,6 @@ $(document).ready(function() { - $('.ui.accordion').accordion(); $('.ui.dropdown') .dropdown(); var fixup_url_numbering = function(group_item) { diff --git a/python/fatcat_web/templates/container_view.html b/python/fatcat_web/templates/container_view.html index ef4335fb..b86b1aa7 100644 --- a/python/fatcat_web/templates/container_view.html +++ b/python/fatcat_web/templates/container_view.html @@ -1,4 +1,4 @@ -{% set entity = container %} +{% set container = entity %} {% import "entity_macros.html" as entity_macros %} {% extends "base.html" %} @@ -50,9 +50,9 @@
-{% if container.es and container.es.is_oa == True %} +{% if container._es and container._es.is_oa == True %} Open Access Publisher -{% elif container.es and container.es.is_oa == False %} +{% elif container._es and container._es.is_oa == False %} Not Open Access {% else %} Unknown OA Status @@ -77,37 +77,37 @@
{% endif %} -{% if container_stats %} +{% if container._stats %} Release Counts
- {{ "{:,}".format(container_stats.total) }} total - {% if container_stats.total >= 1 %} -
{{ "{:,}".format(container_stats.is_preserved) }} - ({{ "{:.1f}".format(container_stats.is_preserved/container_stats.total*100) }}%) + {{ "{:,}".format(container._stats.total) }} total + {% if container._stats.total >= 1 %} +
{{ "{:,}".format(container._stats.is_preserved) }} + ({{ "{:.1f}".format(container._stats.is_preserved/container._stats.total*100) }}%) preserved or archived -
{{ "{:,}".format(container_stats.in_web) }} - ({{ "{:.1f}".format(container_stats.in_web/container_stats.total*100) }}%) +
{{ "{:,}".format(container._stats.in_web) }} + ({{ "{:.1f}".format(container._stats.in_web/container._stats.total*100) }}%) fulltext available to read {% endif %}
{% endif %} -{% if (container.es and container.es != None) %} +{% if (container._es and container._es != None) %} Directory Listings
- {% if container.es.in_doaj == True %} + {% if container._es.in_doaj == True %} In DOAJ
- {% elif container.es.in_doaj == False %} + {% elif container._es.in_doaj == False %} Not in DOAJ
{% endif %} - {% if container.es.in_road == True %} + {% if container._es.in_road == True %} In ISSN ROAD
- {% elif container.es.in_road == False %} + {% elif container._es.in_road == False %} Not in ISSN ROAD
{% endif %} - {% if container.es.in_kbart == True %} + {% if container._es.in_kbart == True %} In Keepers Registery
- {% elif container.es.in_kbart == False %} + {% elif container._es.in_kbart == False %} Not in Keepers Registry
{% endif %} diff --git a/python/fatcat_web/templates/creator_view.html b/python/fatcat_web/templates/creator_view.html index 63308a51..63f83917 100644 --- a/python/fatcat_web/templates/creator_view.html +++ b/python/fatcat_web/templates/creator_view.html @@ -1,4 +1,4 @@ -{% set entity = creator %} +{% set creator = entity %} {% import "entity_macros.html" as entity_macros %} {% extends "base.html" %} @@ -38,9 +38,9 @@

Releases

-{% if releases != [] %} +{% if creator._releases != [] %}

This creator has contributed to: - {{ entity_macros.release_list(releases) }} + {{ entity_macros.release_list(creator._releases) }} {% else %} This creator has not contributed to any releases. {% endif %} @@ -68,7 +68,7 @@ This creator has not contributed to any releases.
Google Scholar

-{{ entity_macros.fatcat_bits(entity, "creator", "") }} +{{ entity_macros.fatcat_bits(entity, "creator", "", editgroup) }}
diff --git a/python/fatcat_web/templates/editgroup_view.html b/python/fatcat_web/templates/editgroup_view.html index 41434a42..2b56d838 100644 --- a/python/fatcat_web/templates/editgroup_view.html +++ b/python/fatcat_web/templates/editgroup_view.html @@ -23,7 +23,7 @@ updated {% endif %} [view edit] - {% if auth_to.edit and not editgroup.changelog_index and not editgroup.submitted %} + {% if auth_to.edit and not editgroup.changelog_index and not editgroup.submitted and entity_type in ('release', 'file', 'container') %} [re-edit]
diff --git a/python/fatcat_web/templates/file_edit.html b/python/fatcat_web/templates/file_edit.html index bef80ee3..74a5682a 100644 --- a/python/fatcat_web/templates/file_edit.html +++ b/python/fatcat_web/templates/file_edit.html @@ -6,12 +6,12 @@

Edit File Entity

- + {% endblock %} {{ form.hidden_tag() }} -
- {{ edit_macros.editgroup_dropdown(form) }} +

Editgroup Metadata

+ {{ edit_macros.editgroup_dropdown(form, editgroup, potential_editgroups) }}

File Metadata

@@ -103,7 +103,7 @@ $(document).ready(function() { - $('.ui.accordion').accordion(); + $('.ui.dropdown') .dropdown(); var fixup_url_numbering = function(group_item) { items = Array.from(group_item.querySelectorAll(".list-group-item")) diff --git a/python/fatcat_web/templates/file_view.html b/python/fatcat_web/templates/file_view.html index 097ee5f6..39ffaaa0 100644 --- a/python/fatcat_web/templates/file_view.html +++ b/python/fatcat_web/templates/file_view.html @@ -1,4 +1,4 @@ -{% set entity = file %} +{% set file = entity %} {% import "entity_macros.html" as entity_macros %} {% extends "base.html" %} @@ -75,7 +75,7 @@ No known public URL, mirror, or archive for this file.
{% endif %} -{{ entity_macros.fatcat_bits(entity, "file", "") }} +{{ entity_macros.fatcat_bits(entity, "file", "", editgroup) }} diff --git a/python/fatcat_web/templates/fileset_view.html b/python/fatcat_web/templates/fileset_view.html index 7f41e617..7bc46d45 100644 --- a/python/fatcat_web/templates/fileset_view.html +++ b/python/fatcat_web/templates/fileset_view.html @@ -1,4 +1,4 @@ -{% set entity = fileset %} +{% set fileset = entity %} {% import "entity_macros.html" as entity_macros %} {% extends "base.html" %} @@ -64,13 +64,13 @@ No known public URL, mirror, or archive for this File Set.
-{% if fileset.total_size != None %} +{% if fileset._total_size != None %}
-

Total Size  {{ fileset.total_size|filesizeformat }} +

Total Size  {{ fileset._total_size|filesizeformat }}

{% endif %} -{{ entity_macros.fatcat_bits(entity, "fileset", "") }} +{{ entity_macros.fatcat_bits(entity, "fileset", "", editgroup) }}
diff --git a/python/fatcat_web/templates/release_edit.html b/python/fatcat_web/templates/release_edit.html index b3beec2b..9a4cf80d 100644 --- a/python/fatcat_web/templates/release_edit.html +++ b/python/fatcat_web/templates/release_edit.html @@ -6,12 +6,12 @@

Edit Release Entity

- + {% endblock %} {{ form.hidden_tag() }} -
- {{ edit_macros.editgroup_dropdown(form) }} +

Editgroup Metadata

+ {{ edit_macros.editgroup_dropdown(form, editgroup, potential_editgroups) }}

The Basics

@@ -134,7 +134,7 @@ $(document).ready(function() { // form focusing (eg, for required fields) :( //$('#release_type').dropdown(); //$('#release_stage').dropdown(); - $('.ui.accordion').accordion(); + $('.ui.dropdown') .dropdown(); var fixup_contrib_numbering = function(group_item) { items = Array.from(group_item.querySelectorAll(".list-group-item")) diff --git a/python/fatcat_web/templates/release_view.html b/python/fatcat_web/templates/release_view.html index a5977166..5fdc2244 100644 --- a/python/fatcat_web/templates/release_view.html +++ b/python/fatcat_web/templates/release_view.html @@ -1,4 +1,4 @@ -{% set entity = release %} +{% set release = entity %} {% import "entity_macros.html" as entity_macros %} {% extends "base.html" %} @@ -19,7 +19,7 @@ {% endif %} - {% for author in authors %} + {% for author in release._authors %} {% endfor %} @@ -89,15 +89,16 @@

- {% if authors != [] %} by {% endif %} - {% for contrib in authors[:12] %} + {% if release._authors != [] %} by {% endif %} + {% for contrib in release._authors[:12] %} {% if contrib.creator_id %} {{ contrib.raw_name }}{% if not loop.last %}, {% endif %} {% else %} {% if contrib.raw_name != None %}{{ contrib.raw_name }}{% else %}Unknown{% endif %}{% if not loop.last %}, {% endif %} {% endif %} {% endfor %} - {% if authors|count > 12 %} (+{{ authors|length - 12 }} others) + {% if release._authors|count > 12 %} + (+{{ release._authors|length - 12 }} others) {% endif %}

@@ -109,10 +110,10 @@
{% if release.release_stage == 'published' %} - Published in {{ container.name }} + Published in {{ release.container.name }} {% else %} Released as a {{ release.release_type }} - {% if container %} in {{ container.name }} {% endif %} + {% if release.container %} in {{ release.container.name }} {% endif %} {% endif %} {% if release.publisher %} by {{ release.publisher }} @@ -128,9 +129,9 @@ Version {{ release.version }} {% endif %} - {% if container != None and container.issnl != None %} + {% if release.container != None and release.container.issnl != None %} ISSN-L - {{ container.issnl }} + {{ release.container.issnl }} {% endif %} {% if release.volume != None %} @@ -154,9 +155,9 @@ Release Year {{ release.release_year }} {% endif %} - {% if container != None and container.container_type != None %} + {% if release.container != None and release.container.container_type != None %} Container Type - {{ container.container_type }} + {{ release.container.container_type }} {% endif %} {% if release.publisher != None %} Publisher @@ -215,7 +216,7 @@ {{ entity_macros.extra_metadata(entity.extra) }} {% endif %} - +{% if entity.status == 'active' %}

Known Files and URLs

{% if entity.files != [] %} @@ -251,14 +252,15 @@

There are no known files associated with this release (you could try other releases for this work?). {% endif %} +{% endif %} - +{% if entity.status == 'active' %} {% if entity.filesets != [] %}

File Sets

{% for fileset in entity.filesets %} -
{{ fileset.manifest|count }} files  {{ fileset.total_size|filesizeformat }} +
{{ fileset.manifest|count }} files  {{ fileset._total_size|filesizeformat }}
fileset:{{ fileset.ident }}
{% for url in fileset.urls[:5] %} @@ -275,8 +277,9 @@
{% endif %} +{% endif %} - +{% if entity.status == 'active' %} {% if entity.webcaptures != [] %}

Web Captures

@@ -287,7 +290,7 @@
webcapture:{{ webcapture.ident }}
{% for url in webcapture.archive_urls[:5] %} - {{ url.url.split('/')[2] }} ({{ url.rel }})
+ {{ url.url.split('/')[2] }} ({{ url.rel }})
{% endfor %} {% if webcapture.urls|length > 5 %} + {{ file.urls|length - 5 }} more URLs @@ -296,6 +299,7 @@
{% endif %} +{% endif %} {% if release.refs != None and release.refs.size != 0 %} @@ -335,10 +339,10 @@
-{% if entity.files != [] and entity.files[0].urls != [] %} +{% if entity.status == 'active' and entity.files != [] and entity.files[0].urls != [] %} Download Full Text -{% elif entity.webcaptures != [] and entity.webcaptures[0].archive_urls != [] and entity.webcaptures[0].archive_urls[0].rel == "wayback" %} -View Web Archive +{% elif entity.status == 'active' and entity.webcaptures != [] and entity.webcaptures[0].archive_urls != [] and entity.webcaptures[0].archive_urls[0].rel == "wayback" %} +View Web Archive {% else %} No Full Text Available {% endif %} @@ -401,36 +405,36 @@
{% endif %} -{% if container != None and container.es %} +{% if release.container != None and release.container._es %}
Container Metadata
-{% if container.es.is_oa == True %} +{% if release.container._es.is_oa == True %} Open Access Publication
-{% elif container.es.is_oa == False %} +{% elif release.container._es.is_oa == False %} Not Open Access
{% else %} Unknown OA Status
{% endif %} -{% if (container.es != None) %} - {% if container.es.in_doaj == True %} - In DOAJ
- {% elif container.es.in_doaj == False %} +{% if (release.container._es != None) %} + {% if release.container._es.in_doaj == True %} + In DOAJ
+ {% elif release.container._es.in_doaj == False %} Not in DOAJ
{% endif %} - {% if container.es.in_road == True %} - In ISSN ROAD
- {% elif container.es.in_road == False %} + {% if release.container._es.in_road == True %} + In ISSN ROAD
+ {% elif release.container._es.in_road == False %} Not in ISSN ROAD
{% endif %} - {% if container.es.in_kbart == True %} - In Keepers Registery
- {% elif container.es.in_kbart == False %} Not in Keepers Registry
+ {% if release.container._es.in_kbart == True %} + In Keepers Registery
+ {% elif release.container._es.in_kbart == False %} Not in Keepers Registry
{% endif %} {% endif %} -{% if container.issnl != None %} - ISSN-L:  {{ container.issnl }}
+{% if release.container.issnl != None %} + ISSN-L:  {{ release.container.issnl }}
{% endif %} - Fatcat Entry + Fatcat Entry
{% endif %} @@ -457,8 +461,8 @@
Lookup Links
- {% if container != None and container.issnl != None %} - SHERPA/RoMEO (journal policies)
+ {% if release.container != None and release.container.issnl != None %} + SHERPA/RoMEO (journal policies)
{% endif %} {% if release != None and release.ext_ids.doi != None %} oaDOI/unpaywall
@@ -479,7 +483,7 @@
-{{ entity_macros.fatcat_bits(entity, "release", "container,files,filesets,webcaptures") }} +{{ entity_macros.fatcat_bits(entity, "release", "container,files,filesets,webcaptures", editgroup) }}
diff --git a/python/fatcat_web/templates/webcapture_view.html b/python/fatcat_web/templates/webcapture_view.html index 9020bf63..b5495cee 100644 --- a/python/fatcat_web/templates/webcapture_view.html +++ b/python/fatcat_web/templates/webcapture_view.html @@ -1,4 +1,4 @@ -{% set entity = webcapture %} +{% set webcapture = entity %} {% import "entity_macros.html" as entity_macros %} {% extends "base.html" %} @@ -36,7 +36,7 @@

Archive URLs

{% if webcapture.archive_urls != None %} - {{ entity_macros.url_list(webcapture.archive_urls, webcapture.wayback_suffix) }} + {{ entity_macros.url_list(webcapture.archive_urls, webcapture._wayback_suffix) }} {% else %} No known public archive for this webcapture. {% endif %} @@ -78,7 +78,7 @@ This web capture is empty (contains no resources). {% endif %} -{{ entity_macros.fatcat_bits(entity, "webcapture", "") }} +{{ entity_macros.fatcat_bits(entity, "webcapture", "", editgroup) }} diff --git a/python/fatcat_web/templates/work_view.html b/python/fatcat_web/templates/work_view.html index 507498c8..aa32ba39 100644 --- a/python/fatcat_web/templates/work_view.html +++ b/python/fatcat_web/templates/work_view.html @@ -1,4 +1,4 @@ -{% set entity = work %} +{% set work = entity %} {% import "entity_macros.html" as entity_macros %} {% extends "base.html" %} @@ -22,8 +22,8 @@ {% endif %}

Releases

-{% if releases != [] %} - {{ entity_macros.release_list(releases) }} +{% if work._releases != [] and work._releases != None %} + {{ entity_macros.release_list(work._releases) }} {% else %}

There are no known releases associated with this work. {% endif %} @@ -42,7 +42,7 @@ reference the same underlying "work".

-{{ entity_macros.fatcat_bits(entity, "work", "") }} +{{ entity_macros.fatcat_bits(entity, "work", "", editgroup) }}
-- cgit v1.2.3