diff options
| author | Bryan Newbold <bnewbold@robocracy.org> | 2019-04-02 17:52:19 -0700 | 
|---|---|---|
| committer | Bryan Newbold <bnewbold@robocracy.org> | 2019-04-02 17:52:21 -0700 | 
| commit | 428f8872d15aff319602697f16ffb51868c86c12 (patch) | |
| tree | d7bc952458de2a12343b116126049db13077752a | |
| parent | 7240dbce3300ff30999e3730ef9330d6ff93b06c (diff) | |
| download | fatcat-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)
| -rw-r--r-- | python/fatcat_web/editing_routes.py | 166 | ||||
| -rw-r--r-- | python/fatcat_web/forms.py | 61 | ||||
| -rw-r--r-- | python/fatcat_web/routes.py | 9 | 
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) | 
