aboutsummaryrefslogtreecommitdiffstats
path: root/python/fatcat_web
diff options
context:
space:
mode:
authorBryan Newbold <bnewbold@robocracy.org>2019-04-02 17:52:19 -0700
committerBryan Newbold <bnewbold@robocracy.org>2019-04-02 17:52:21 -0700
commit428f8872d15aff319602697f16ffb51868c86c12 (patch)
treed7bc952458de2a12343b116126049db13077752a /python/fatcat_web
parent7240dbce3300ff30999e3730ef9330d6ff93b06c (diff)
downloadfatcat-428f8872d15aff319602697f16ffb51868c86c12.tar.gz
fatcat-428f8872d15aff319602697f16ffb51868c86c12.zip
file basic editing; several cleanups
- use logging when appropriate - refactor out editgroup form fetching code - handle "editgroup doesn't exist" error (and display)
Diffstat (limited to 'python/fatcat_web')
-rw-r--r--python/fatcat_web/editing_routes.py166
-rw-r--r--python/fatcat_web/forms.py61
-rw-r--r--python/fatcat_web/routes.py9
3 files changed, 159 insertions, 77 deletions
diff --git a/python/fatcat_web/editing_routes.py b/python/fatcat_web/editing_routes.py
index fe2c0722..f45c5379 100644
--- a/python/fatcat_web/editing_routes.py
+++ b/python/fatcat_web/editing_routes.py
@@ -25,15 +25,19 @@ def form_editgroup_get_or_create(api, edit_form):
try:
eg = api.get_editgroup(edit_form.editgroup_id.data)
except ApiException as ae:
- app.logging.warn(ae)
+ if ae.status == 404:
+ edit_form.editgroup_id.errors.append("Editgroup does not exist")
+ return None
+ app.logger.warn(ae)
abort(ae.status)
+ # TODO: check here that editgroup hasn't been merged already
else:
# if no editgroup, create one from description
try:
eg = api.create_editgroup(
Editgroup(description=edit_form.editgroup_description.data or None))
except ApiException as ae:
- app.logging.warn(ae)
+ app.logger.warn(ae)
abort(ae.status)
# set this session editgroup_id
session['active_editgroup_id'] = eg.editgroup_id
@@ -52,22 +56,22 @@ def container_create():
# API on behalf of user
user_api = auth_api(session['api_token'])
eg = form_editgroup_get_or_create(user_api, form)
- # no merge or anything hard to do; just create the entity
- entity = form.to_entity()
- try:
- edit = user_api.create_container(entity, editgroup_id=eg.editgroup_id)
- except ApiException as ae:
- app.logging.warn(ae)
- abort(ae.status)
- # redirect to new entity
- return redirect('/container/{}'.format(edit.ident))
+ if eg:
+ # no merge or anything hard to do; just create the entity
+ entity = form.to_entity()
+ try:
+ edit = user_api.create_container(entity, editgroup_id=eg.editgroup_id)
+ except ApiException as ae:
+ app.logger.warn(ae)
+ abort(ae.status)
+ # redirect to new entity
+ return redirect('/container/{}'.format(edit.ident))
elif form.errors:
app.logger.info("form errors (did not validate): {}".format(form.errors))
else:
editgroup_id = session.get('active_editgroup_id', None)
form.editgroup_id.data = editgroup_id
- return render_template('container_create.html',
- form=form, editgroup_id=editgroup_id)
+ return render_template('container_create.html', form=form)
@login_required
@app.route('/container/<ident>/edit', methods=['GET', 'POST'])
@@ -83,17 +87,18 @@ def container_edit(ident):
# API on behalf of user
user_api = auth_api(session['api_token'])
eg = form_editgroup_get_or_create(user_api, form)
- # all the tricky logic is in the update method
- form.update_entity(entity)
- try:
- edit = user_api.update_container(entity.ident, entity,
- editgroup_id=eg.editgroup_id)
- except ApiException as ae:
- app.logging.warn(ae)
- abort(ae.status)
- # redirect to entity revision
- # TODO: container_rev_view
- return redirect('/container/{}'.format(edit.ident))
+ if eg:
+ # all the tricky logic is in the update method
+ form.update_entity(entity)
+ try:
+ edit = user_api.update_container(entity.ident, entity,
+ editgroup_id=eg.editgroup_id)
+ except ApiException as ae:
+ app.logger.warn(ae)
+ abort(ae.status)
+ # redirect to entity revision
+ # TODO: container_rev_view
+ return redirect('/container/{}'.format(edit.ident))
elif form.errors:
app.logger.info("form errors (did not validate): {}".format(form.errors))
else:
@@ -101,8 +106,7 @@ def container_edit(ident):
if not form.is_submitted():
editgroup_id = session.get('active_editgroup_id', None)
form.editgroup_id.data = editgroup_id
- return render_template('container_edit.html',
- form=form, editgroup_id=editgroup_id, entity=entity)
+ return render_template('container_edit.html', form=form, entity=entity)
@app.route('/creator/<ident>/edit', methods=['GET'])
def creator_edit(ident):
@@ -112,13 +116,68 @@ def creator_edit(ident):
abort(ae.status)
return render_template('entity_edit.html')
-@app.route('/file/<ident>/edit', methods=['GET'])
+@app.route('/file/create', methods=['GET', 'POST'])
+@login_required
+def file_create():
+ 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:
+ # no merge or anything hard to do; just create the entity
+ entity = form.to_entity()
+ try:
+ edit = user_api.create_file(entity, editgroup_id=eg.editgroup_id)
+ except ApiException as ae:
+ app.logger.warn(ae)
+ abort(ae.status)
+ # redirect to new entity
+ return redirect('/file/{}'.format(edit.ident))
+ elif form.errors:
+ app.logger.info("form errors (did not validate): {}".format(form.errors))
+ else:
+ editgroup_id = session.get('active_editgroup_id', None)
+ form.editgroup_id.data = editgroup_id
+ form.urls.append_entry()
+ form.release_ids.append_entry()
+ return render_template('file_create.html',
+ form=form)
+
+@login_required
+@app.route('/file/<ident>/edit', methods=['GET', 'POST'])
def file_edit(ident):
+ # TODO: prev_rev interlock
try:
entity = api.get_file(ident)
except ApiException as ae:
abort(ae.status)
- return render_template('entity_edit.html')
+ 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(entity.ident, entity,
+ editgroup_id=eg.editgroup_id)
+ except ApiException as ae:
+ app.logger.warn(ae)
+ abort(ae.status)
+ # redirect to entity revision
+ # TODO: file_rev_view
+ return redirect('/file/{}'.format(edit.ident))
+ elif form.errors:
+ app.logger.info("form errors (did not validate): {}".format(form.errors))
+ else: # not submitted
+ form = FileEntityForm.from_entity(entity)
+ editgroup_id = session.get('active_editgroup_id', None)
+ form.editgroup_id.data = editgroup_id
+ return render_template('file_edit.html', form=form, entity=entity)
@app.route('/fileset/<ident>/edit', methods=['GET'])
def fileset_edit(ident):
@@ -145,24 +204,23 @@ def release_create():
# API on behalf of user
user_api = auth_api(session['api_token'])
eg = form_editgroup_get_or_create(user_api, form)
- # no merge or anything hard to do; just create the entity
- entity = form.to_entity()
- try:
- edit = user_api.create_release(entity, editgroup_id=eg.editgroup_id)
- except ApiException as ae:
- app.logging.warn(ae)
- abort(ae.status)
- # redirect to new release
- return redirect('/release/{}'.format(edit.ident))
+ if eg:
+ # no merge or anything hard to do; just create the entity
+ entity = form.to_entity()
+ try:
+ edit = user_api.create_release(entity, editgroup_id=eg.editgroup_id)
+ except ApiException as ae:
+ app.logger.warn(ae)
+ abort(ae.status)
+ # redirect to new release
+ return redirect('/release/{}'.format(edit.ident))
elif form.errors:
app.logger.info("form errors (did not validate): {}".format(form.errors))
- elif len(form.contribs) == 0:
+ else: # not submitted
form.contribs.append_entry()
- if not form.is_submitted():
editgroup_id = session.get('active_editgroup_id', None)
form.editgroup_id.data = editgroup_id
- return render_template('release_create.html',
- form=form, editgroup_id=editgroup_id)
+ return render_template('release_create.html', form=form)
@login_required
@app.route('/release/<ident>/edit', methods=['GET', 'POST'])
@@ -178,25 +236,25 @@ def release_edit(ident):
# API on behalf of user
user_api = auth_api(session['api_token'])
eg = form_editgroup_get_or_create(user_api, form)
- # all the tricky logic is in the update method
- form.update_entity(entity)
- try:
- edit = user_api.update_release(entity.ident, entity,
- editgroup_id=eg.editgroup_id)
- except ApiException as ae:
- app.logging.warn(ae)
- abort(ae.status)
- # redirect to entity revision
- # TODO: release_rev_view
- return redirect('/release/{}'.format(edit.ident))
+ if eg:
+ # all the tricky logic is in the update method
+ form.update_entity(entity)
+ try:
+ edit = user_api.update_release(entity.ident, entity,
+ editgroup_id=eg.editgroup_id)
+ except ApiException as ae:
+ app.logger.warn(ae)
+ abort(ae.status)
+ # redirect to entity revision
+ # TODO: release_rev_view
+ return redirect('/release/{}'.format(edit.ident))
elif form.errors:
app.logger.info("form errors (did not validate): {}".format(form.errors))
else: # not submitted
form = ReleaseEntityForm.from_entity(entity)
editgroup_id = session.get('active_editgroup_id', None)
form.editgroup_id.data = editgroup_id
- return render_template('release_edit.html',
- form=form, editgroup_id=editgroup_id, entity=entity)
+ return render_template('release_edit.html', form=form, entity=entity)
@app.route('/work/create', methods=['GET'])
def work_create_view():
diff --git a/python/fatcat_web/forms.py b/python/fatcat_web/forms.py
index ebe6fafe..08c401b7 100644
--- a/python/fatcat_web/forms.py
+++ b/python/fatcat_web/forms.py
@@ -9,7 +9,7 @@ from wtforms import SelectField, DateField, StringField, IntegerField, \
HiddenField, FormField, FieldList, validators
from fatcat_client import ContainerEntity, CreatorEntity, FileEntity, \
- ReleaseEntity, ReleaseContrib
+ ReleaseEntity, ReleaseContrib, FileEntityUrls
release_type_options = [
('', 'Unknown'),
@@ -37,7 +37,8 @@ role_type_options = [
class EntityEditForm(FlaskForm):
editgroup_id = StringField('Editgroup ID',
- [validators.Optional(True)])
+ [validators.Optional(True),
+ validators.Length(min=26, max=26)])
editgroup_description = StringField('Editgroup Description',
[validators.Optional(True)])
edit_description = StringField('Description of Changes',
@@ -47,6 +48,7 @@ class ReleaseContribForm(FlaskForm):
class Meta:
# this is a sub-form, so disable CSRF
csrf = False
+
#surname
#given_name
#creator_id (?)
@@ -71,10 +73,14 @@ class ReleaseEntityForm(EntityEditForm):
- date
"""
title = StringField('Title',
- [validators.InputRequired()])
+ [validators.DataRequired()])
original_title = StringField('Original Title')
- work_id = StringField('Work FCID')
- container_id = StringField('Container FCID')
+ work_id = StringField('Work FCID',
+ [validators.Optional(True),
+ validators.Length(min=26, max=26)])
+ container_id = StringField('Container FCID',
+ [validators.Optional(True),
+ validators.Length(min=26, max=26)])
release_type = SelectField('Release Type',
[validators.DataRequired()],
choices=release_type_options,
@@ -172,7 +178,7 @@ CONTAINER_SIMPLE_ATTRS = ['name', 'container_type', 'publisher', 'issnl',
class ContainerEntityForm(EntityEditForm):
name = StringField('Name/Title',
- [validators.InputRequired()])
+ [validators.DataRequired()])
container_type = SelectField('Container Type',
[validators.Optional(True)],
choices=container_type_options,
@@ -230,7 +236,8 @@ class FileUrlForm(FlaskForm):
csrf = False
url = StringField('Display Name',
- [validators.DataRequired()])
+ [validators.DataRequired(),
+ validators.URL(require_tld=False)])
rel = SelectField(
[validators.DataRequired()],
choices=url_rel_options,
@@ -240,25 +247,41 @@ class FileEntityForm(EntityEditForm):
size = IntegerField('Size (bytes)',
[validators.DataRequired()])
# TODO: positive definite
- md5 = StringField("MD5")
- sha1 = StringField("SHA-1")
- sha256 = StringField("SHA-256")
+ md5 = StringField("MD5",
+ [validators.Optional(True),
+ validators.Length(min=32, max=32)])
+ sha1 = StringField("SHA-1",
+ [validators.DataRequired(),
+ validators.Length(min=40, max=40)])
+ sha256 = StringField("SHA-256",
+ [validators.Optional(True),
+ validators.Length(min=64, max=64)])
urls = FieldList(FormField(FileUrlForm))
mimetype = StringField("Mimetype")
- release_ids = FieldList(StringField("Release FCID"))
+ release_ids = FieldList(
+ StringField("Release FCID",
+ [validators.DataRequired(),
+ validators.Length(min=26, max=26)]))
- def from_entity(re):
+ def from_entity(fe):
"""
Initializes form with values from an existing file entity.
"""
ref = FileEntityForm()
for simple_attr in FILE_SIMPLE_ATTRS:
a = getattr(ref, simple_attr)
- a.data = getattr(re, simple_attr)
+ a.data = getattr(fe, simple_attr)
+ for i, c in enumerate(fe.urls):
+ ruf = FileUrlForm()
+ ruf.rel = c.rel
+ ruf.url = c.url
+ ref.urls.append_entry(ruf)
+ for r in fe.release_ids:
+ ref.release_ids.append_entry(r)
return ref
def to_entity(self):
- assert(self.name.data)
+ assert(self.sha1.data)
entity = FileEntity()
self.update_entity(entity)
return entity
@@ -275,15 +298,15 @@ class FileEntityForm(EntityEditForm):
if a == '':
a = None
setattr(fe, simple_attr, a)
- re.urls = []
+ fe.urls = []
for u in self.urls:
- re.contribs.append(FileUrl(
- rel=u.role.data or None,
+ fe.urls.append(FileEntityUrls(
+ rel=u.rel.data or None,
url=u.url.data or None,
))
- re.release_ids = []
+ fe.release_ids = []
for ri in self.release_ids:
- re.release_ids.append(ri.data)
+ fe.release_ids.append(ri.data)
if self.edit_description.data:
fe.edit_extra = dict(description=self.edit_description.data)
diff --git a/python/fatcat_web/routes.py b/python/fatcat_web/routes.py
index ed9abf0b..c4152188 100644
--- a/python/fatcat_web/routes.py
+++ b/python/fatcat_web/routes.py
@@ -22,6 +22,7 @@ def container_history(ident):
entity = api.get_container(ident)
history = api.get_container_history(ident)
except ApiException as ae:
+ app.logger.info(ae)
abort(ae.status)
#print(history)
return render_template('entity_history.html',
@@ -57,7 +58,7 @@ def container_view(ident):
stats = get_elastic_container_stats(entity.issnl)
except Exception as e:
stats = None
- print(e)
+ app.logger.error(e)
else:
stats = None
@@ -397,7 +398,7 @@ def stats_page():
stats = get_elastic_entity_stats()
stats.update(get_changelog_stats())
except Exception as ae:
- print(ae)
+ app.logger.error(e)
abort(503)
return render_template('stats.html', stats=stats)
@@ -410,7 +411,7 @@ def stats_json():
stats = get_elastic_entity_stats()
stats.update(get_changelog_stats())
except Exception as ae:
- print(ae)
+ app.logger.error(e)
abort(503)
return jsonify(stats)
@@ -420,7 +421,7 @@ def container_issnl_stats(issnl):
try:
stats = get_elastic_container_stats(issnl)
except Exception as ae:
- print(ae)
+ app.logger.error(e)
abort(503)
return jsonify(stats)