From 5527ecc2b7bd81bab9bcb065adbbccd941b85be8 Mon Sep 17 00:00:00 2001 From: Bryan Newbold Date: Thu, 21 Mar 2019 16:59:18 -0700 Subject: major progress on release create form --- python/fatcat_web/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'python/fatcat_web/__init__.py') diff --git a/python/fatcat_web/__init__.py b/python/fatcat_web/__init__.py index e80393c2..00bc84fd 100644 --- a/python/fatcat_web/__init__.py +++ b/python/fatcat_web/__init__.py @@ -46,7 +46,7 @@ else: print("No privileged token found") priv_api = None -from fatcat_web import routes, auth, cors +from fatcat_web import routes, auth, cors, forms gitlab_bp = create_flask_blueprint(Gitlab, oauth, auth.handle_oauth) app.register_blueprint(gitlab_bp, url_prefix='/auth/gitlab') -- cgit v1.2.3 From 6fa603c92b3329a6e49b8baa0ba68489a0ebfba8 Mon Sep 17 00:00:00 2001 From: Bryan Newbold Date: Mon, 1 Apr 2019 22:10:22 -0700 Subject: add necessary CSRF invocation to entrypoint --- python/fatcat_web/__init__.py | 3 +++ 1 file changed, 3 insertions(+) (limited to 'python/fatcat_web/__init__.py') diff --git a/python/fatcat_web/__init__.py b/python/fatcat_web/__init__.py index 00bc84fd..3f3824e1 100644 --- a/python/fatcat_web/__init__.py +++ b/python/fatcat_web/__init__.py @@ -3,6 +3,7 @@ from flask import Flask from flask_uuid import FlaskUUID from flask_debugtoolbar import DebugToolbarExtension from flask_login import LoginManager +from flask_wtf.csrf import CSRFProtect from authlib.flask.client import OAuth from loginpass import create_flask_blueprint, Gitlab from raven.contrib.flask import Sentry @@ -10,11 +11,13 @@ import fatcat_client from fatcat_web.web_config import Config + toolbar = DebugToolbarExtension() app = Flask(__name__) app.config.from_object(Config) toolbar = DebugToolbarExtension(app) FlaskUUID(app) +app.csrf = CSRFProtect(app) login_manager = LoginManager() login_manager.init_app(app) -- cgit v1.2.3 From 4bbdfce35d6682cac197961c13ea82bb66658d8b Mon Sep 17 00:00:00 2001 From: Bryan Newbold Date: Tue, 2 Apr 2019 15:33:36 -0700 Subject: refactor editing routes into separate file --- python/fatcat_web/__init__.py | 2 +- python/fatcat_web/editing_routes.py | 170 ++++++++++++++++++++++++++++++++++++ python/fatcat_web/routes.py | 165 ---------------------------------- 3 files changed, 171 insertions(+), 166 deletions(-) create mode 100644 python/fatcat_web/editing_routes.py (limited to 'python/fatcat_web/__init__.py') diff --git a/python/fatcat_web/__init__.py b/python/fatcat_web/__init__.py index 3f3824e1..7d62bb5f 100644 --- a/python/fatcat_web/__init__.py +++ b/python/fatcat_web/__init__.py @@ -49,7 +49,7 @@ else: print("No privileged token found") priv_api = None -from fatcat_web import routes, auth, cors, forms +from fatcat_web import routes, editing_routes, auth, cors, forms gitlab_bp = create_flask_blueprint(Gitlab, oauth, auth.handle_oauth) app.register_blueprint(gitlab_bp, url_prefix='/auth/gitlab') diff --git a/python/fatcat_web/editing_routes.py b/python/fatcat_web/editing_routes.py new file mode 100644 index 00000000..dda0bc6f --- /dev/null +++ b/python/fatcat_web/editing_routes.py @@ -0,0 +1,170 @@ + +import os +import json +from flask import Flask, render_template, send_from_directory, request, \ + url_for, abort, g, redirect, jsonify, session, flash, Response +from flask_login import login_required + +from fatcat_client import Editgroup +from fatcat_client.rest import ApiException +from fatcat_tools.transforms import * +from fatcat_web import app, api, auth_api, priv_api +from fatcat_web.auth import handle_token_login, handle_logout, load_user, handle_ia_xauth +from fatcat_web.cors import crossdomain +from fatcat_web.search import * +from fatcat_web.forms import * + + +### Views ################################################################### + +@app.route('/container//edit', methods=['GET']) +def container_edit_view(ident): + try: + entity = api.get_container(ident) + except ApiException as ae: + abort(ae.status) + return render_template('entity_edit.html') + +@app.route('/container/create', methods=['GET']) +@login_required +def container_create_view(): + return render_template('container_create.html') + +@app.route('/container/create', methods=['POST']) +@login_required +def container_create(): + raise NotImplementedError + params = dict() + for k in request.form: + if k.startswith('container_'): + params[k[10:]] = request.form[k] + container = None + #edit = api.create_container(container, params=params) + #return redirect("/container/{}".format(edit.ident)) + +@app.route('/creator//edit', methods=['GET']) +def creator_edit_view(ident): + try: + entity = api.get_creator(ident) + except ApiException as ae: + abort(ae.status) + return render_template('entity_edit.html') + +@app.route('/file//edit', methods=['GET']) +def file_edit_view(ident): + try: + entity = api.get_file(ident) + except ApiException as ae: + abort(ae.status) + return render_template('entity_edit.html') + +@app.route('/fileset//edit', methods=['GET']) +def fileset_edit_view(ident): + try: + entity = api.get_fileset(ident) + except ApiException as ae: + abort(ae.status) + return render_template('entity_edit.html') + +@app.route('/webcapture//edit', methods=['GET']) +def webcapture_edit_view(ident): + try: + entity = api.get_webcapture(ident) + except ApiException as ae: + abort(ae.status) + return render_template('entity_edit.html') + +# XXX: figure out CSRF stuff for local dev +@app.route('/release/create', methods=['GET', 'POST']) +@login_required +@app.csrf.exempt +def release_create(): + form = ReleaseEntityForm(csrf_enabled=False) # XXX: + if form.is_submitted(): + if form.validate_on_submit(): + # API on behalf of user + user_api = auth_api(session['api_token']) + if form.editgroup_id.data: + # TODO: error handling + eg = user_api.get_editgroup(form.editgroup_id.data) + else: + # if no editgroup, create one from description + eg = user_api.create_editgroup( + Editgroup(description=form.editgroup_description.data or None)) + # set this session editgroup_id + session['active_editgroup_id'] = eg.editgroup_id + print(eg.editgroup_id) # XXX: debug + flash('Started new editgroup {}' \ + .format(eg.editgroup_id, eg.editgroup_id)) + # no merge or anything hard to do; just create the entity + entity = form.to_entity() + edit = user_api.create_release(entity, editgroup_id=eg.editgroup_id) + # redirect to new release + return redirect('/release/{}'.format(edit.ident)) + elif form.errors: + print("user form errors: {}".format(form.errors)) + print("didn't validate...") + elif len(form.contribs) == 0: + 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) + +# XXX: figure out CSRF stuff for local dev +@login_required +@app.csrf.exempt +@app.route('/release//edit', methods=['GET', 'POST']) +def release_edit(ident): + # TODO: prev_rev interlock + # TODO: factor out editgroup active/creation stuff + try: + entity = api.get_release(ident) + except ApiException as ae: + abort(ae.status) + form = ReleaseEntityForm(csrf_enabled=False) # XXX: + if form.is_submitted(): + if form.validate_on_submit(): + # API on behalf of user + user_api = auth_api(session['api_token']) + if form.editgroup_id.data: + # TODO: error handling + eg = user_api.get_editgroup(form.editgroup_id.data) + else: + # if no editgroup, create one from description + eg = user_api.create_editgroup( + Editgroup(description=form.editgroup_description.data or None)) + # set this session editgroup_id + session['active_editgroup_id'] = eg.editgroup_id + print(eg.editgroup_id) # XXX: debug + flash('Started new editgroup {}' \ + .format(eg.editgroup_id, eg.editgroup_id)) + # all the tricky logic is in the update method + form.update_entity(entity) + edit = user_api.update_release(entity.ident, entity, + editgroup_id=eg.editgroup_id) + # redirect to release revision + # TODO: release_rev_view + return redirect('/release/{}'.format(edit.ident)) + elif form.errors: + print("user form errors (didn't validate): {}".format(form.errors)) + else: + form = ReleaseEntityForm.from_entity(entity) + if not form.is_submitted(): + 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) + +@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) + return render_template('entity_edit.html') diff --git a/python/fatcat_web/routes.py b/python/fatcat_web/routes.py index 2bfb9025..ed9abf0b 100644 --- a/python/fatcat_web/routes.py +++ b/python/fatcat_web/routes.py @@ -12,7 +12,6 @@ from fatcat_web import app, api, auth_api, priv_api from fatcat_web.auth import handle_token_login, handle_logout, load_user, handle_ia_xauth from fatcat_web.cors import crossdomain from fatcat_web.search import * -from fatcat_web.forms import * ### Views ################################################################### @@ -31,43 +30,6 @@ def container_history(ident): entity=entity, history=history) -@app.route('/container//edit', methods=['GET']) -def container_edit_view(ident): - try: - entity = api.get_container(ident) - except ApiException as ae: - abort(ae.status) - return render_template('entity_edit.html') - -#@app.route('/container//edit', methods=['POST']) -#def container_edit(ident): -# raise NotImplemented() -# params = dict() -# for k in request.form: -# if k.startswith('container_'): -# params[k[10:]] = request.form[k] -# edit = api.update_container(params=params) -# return redirect("/container/{}".format(edit.ident)) -# # else: -# #return render_template('container_edit.html') - -@app.route('/container/create', methods=['GET']) -@login_required -def container_create_view(): - return render_template('container_create.html') - -@app.route('/container/create', methods=['POST']) -@login_required -def container_create(): - raise NotImplementedError - params = dict() - for k in request.form: - if k.startswith('container_'): - params[k[10:]] = request.form[k] - container = None - #edit = api.create_container(container, params=params) - #return redirect("/container/{}".format(edit.ident)) - @app.route('/container/lookup', methods=['GET']) def container_lookup(): extid = None @@ -121,14 +83,6 @@ def creator_history(ident): entity=entity, history=history) -@app.route('/creator//edit', methods=['GET']) -def creator_edit_view(ident): - try: - entity = api.get_creator(ident) - except ApiException as ae: - abort(ae.status) - return render_template('entity_edit.html') - @app.route('/creator/lookup', methods=['GET']) def creator_lookup(): for key in ('orcid', 'wikidata_qid'): @@ -169,14 +123,6 @@ def file_history(ident): entity=entity, history=history) -@app.route('/file//edit', methods=['GET']) -def file_edit_view(ident): - try: - entity = api.get_file(ident) - except ApiException as ae: - abort(ae.status) - return render_template('entity_edit.html') - @app.route('/file/lookup', methods=['GET']) def file_lookup(): for key in ('md5', 'sha1', 'sha256'): @@ -223,14 +169,6 @@ def fileset_history(ident): entity=entity, history=history) -@app.route('/fileset//edit', methods=['GET']) -def fileset_edit_view(ident): - try: - entity = api.get_fileset(ident) - except ApiException as ae: - abort(ae.status) - return render_template('entity_edit.html') - @app.route('/fileset/lookup', methods=['GET']) def fileset_lookup(): raise NotImplementedError @@ -268,14 +206,6 @@ def webcapture_history(ident): entity=entity, history=history) -@app.route('/webcapture//edit', methods=['GET']) -def webcapture_edit_view(ident): - try: - entity = api.get_webcapture(ident) - except ApiException as ae: - abort(ae.status) - return render_template('entity_edit.html') - @app.route('/webcapture/lookup', methods=['GET']) def webcapture_lookup(): raise NotImplementedError @@ -313,44 +243,6 @@ def release_lookup(): abort(ae.status) return redirect('/release/{}'.format(resp.ident)) -# XXX: figure out CSRF stuff for local dev -@app.route('/release/create', methods=['GET', 'POST']) -@login_required -@app.csrf.exempt -def release_create(): - form = ReleaseEntityForm(csrf_enabled=False) # XXX: - if form.is_submitted(): - if form.validate_on_submit(): - # API on behalf of user - user_api = auth_api(session['api_token']) - if form.editgroup_id.data: - # TODO: error handling - eg = user_api.get_editgroup(form.editgroup_id.data) - else: - # if no editgroup, create one from description - eg = user_api.create_editgroup( - Editgroup(description=form.editgroup_description.data or None)) - # set this session editgroup_id - session['active_editgroup_id'] = eg.editgroup_id - print(eg.editgroup_id) # XXX: debug - flash('Started new editgroup {}' \ - .format(eg.editgroup_id, eg.editgroup_id)) - # no merge or anything hard to do; just create the entity - entity = form.to_entity() - edit = user_api.create_release(entity, editgroup_id=eg.editgroup_id) - # redirect to new release - return redirect('/release/{}'.format(edit.ident)) - elif form.errors: - print("user form errors: {}".format(form.errors)) - print("didn't validate...") - elif len(form.contribs) == 0: - 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) - @app.route('/release//history', methods=['GET']) def release_history(ident): try: @@ -364,51 +256,6 @@ def release_history(ident): entity=entity, history=history) -# XXX: figure out CSRF stuff for local dev -@login_required -@app.csrf.exempt -@app.route('/release//edit', methods=['GET', 'POST']) -def release_edit(ident): - # TODO: prev_rev interlock - # TODO: factor out editgroup active/creation stuff - try: - entity = api.get_release(ident) - except ApiException as ae: - abort(ae.status) - form = ReleaseEntityForm(csrf_enabled=False) # XXX: - if form.is_submitted(): - if form.validate_on_submit(): - # API on behalf of user - user_api = auth_api(session['api_token']) - if form.editgroup_id.data: - # TODO: error handling - eg = user_api.get_editgroup(form.editgroup_id.data) - else: - # if no editgroup, create one from description - eg = user_api.create_editgroup( - Editgroup(description=form.editgroup_description.data or None)) - # set this session editgroup_id - session['active_editgroup_id'] = eg.editgroup_id - print(eg.editgroup_id) # XXX: debug - flash('Started new editgroup {}' \ - .format(eg.editgroup_id, eg.editgroup_id)) - # all the tricky logic is in the update method - form.update_entity(entity) - edit = user_api.update_release(entity.ident, entity, - editgroup_id=eg.editgroup_id) - # redirect to release revision - # TODO: release_rev_view - return redirect('/release/{}'.format(edit.ident)) - elif form.errors: - print("user form errors (didn't validate): {}".format(form.errors)) - else: - form = ReleaseEntityForm.from_entity(entity) - if not form.is_submitted(): - 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) - @app.route('/release/', methods=['GET']) def release_view(ident): try: @@ -433,10 +280,6 @@ def release_view(ident): return render_template('release_view.html', release=entity, authors=authors, container=container) -@app.route('/work/create', methods=['GET']) -def work_create_view(): - return abort(404) - @app.route('/work//history', methods=['GET']) def work_history(ident): try: @@ -450,14 +293,6 @@ def work_history(ident): entity=entity, history=history) -@app.route('/work//edit', methods=['GET']) -def work_edit_view(ident): - try: - entity = api.get_work(ident) - except ApiException as ae: - abort(ae.status) - return render_template('entity_edit.html') - @app.route('/work/', methods=['GET']) def work_view(ident): try: -- cgit v1.2.3 From 526ee41b187a2373c08679bc9bc582679beaa9ef Mon Sep 17 00:00:00 2001 From: Bryan Newbold Date: Wed, 3 Apr 2019 19:00:11 -0700 Subject: markdown rendering of comments/annotations --- python/Pipfile | 1 + python/Pipfile.lock | 115 +++++++++++++----------- python/fatcat_web/__init__.py | 9 ++ python/fatcat_web/templates/editgroup_view.html | 3 +- 4 files changed, 77 insertions(+), 51 deletions(-) (limited to 'python/fatcat_web/__init__.py') diff --git a/python/Pipfile b/python/Pipfile index 9c108cba..321b2d50 100644 --- a/python/Pipfile +++ b/python/Pipfile @@ -25,6 +25,7 @@ flask-uuid = "*" flask-debugtoolbar = "*" flask-login = "*" flask-wtf = "*" +Flask-Misaka = "*" WTForms = "*" loginpass = "*" requests = ">=2" diff --git a/python/Pipfile.lock b/python/Pipfile.lock index 8b08d613..3aaa0c66 100644 --- a/python/Pipfile.lock +++ b/python/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "f51694c4f6cfb984a07aca94d21f8803eaf381c72e3b35fabeb1fa68294216ba" + "sha256": "fa764b53404517e2f5e60b61fa8083f0ef50499e9b9b537994720abf85f2aac9" }, "pipfile-spec": 6, "requires": { @@ -172,6 +172,15 @@ "index": "pypi", "version": "==0.4.1" }, + "flask-misaka": { + "hashes": [ + "sha256:bcfdacc0803ccea75d377737e82c83489b2153d922c9d9f9eabc5148d216ed70", + "sha256:d0cfb0efd9e5afacda76defd4a605a68390f4fb1bef283c71534fd3ce0d3efb5", + "sha256:f423c3beb5502742a57330a272f81d53223f6f99d45cc45b03926e3a3034f589" + ], + "index": "pypi", + "version": "==1.0.0" + }, "flask-uuid": { "hashes": [ "sha256:f9a8196eb896599ba9e74dcf713cfd1aca4669d418c19069e088620ae6294805" @@ -233,34 +242,34 @@ }, "lxml": { "hashes": [ - "sha256:0358b9e9642bc7d39aac5cffe9884a99a5ca68e5e2c1b89e570ed60da9139908", - "sha256:091a359c4dafebbecd3959d9013f1b896b5371859165e4e50b01607a98d9e3e2", - "sha256:1998e4e60603c64bcc35af61b4331ab3af087457900d3980e18d190e17c3a697", - "sha256:2000b4088dee9a41f459fddaf6609bba48a435ce6374bb254c5ccdaa8928c5ba", - "sha256:2afb0064780d8aaf165875be5898c1866766e56175714fa5f9d055433e92d41d", - "sha256:2d8f1d9334a4e3ff176d096c14ded3100547d73440683567d85b8842a53180bb", - "sha256:2e38db22f6a3199fd63675e1b4bd795d676d906869047398f29f38ca55cb453a", - "sha256:3181f84649c1a1ca62b19ddf28436b1b2cb05ae6c7d2628f33872e713994c364", - "sha256:37462170dfd88af8431d04de6b236e6e9c06cda71e2ca26d88ef2332fd2a5237", - "sha256:3a9d8521c89bf6f2a929c3d12ad3ad7392c774c327ea809fd08a13be6b3bc05f", - "sha256:3d0bbd2e1a28b4429f24fd63a122a450ce9edb7a8063d070790092d7343a1aa4", - "sha256:483d60585ce3ee71929cea70949059f83850fa5e12deb9c094ed1c8c2ec73cbd", - "sha256:4888be27d5cba55ce94209baef5bcd7bbd7314a3d17021a5fc10000b3a5f737d", - "sha256:64b0d62e4209170a2a0c404c446ab83b941a0003e96604d2e4f4cb735f8a2254", - "sha256:68010900898fdf139ac08549c4dba8206c584070a960ffc530aebf0c6f2794ef", - "sha256:872ecb066de602a0099db98bd9e57f4cfc1d62f6093d94460c787737aa08f39e", - "sha256:88a32b03f2e4cd0e63f154cac76724709f40b3fc2f30139eb5d6f900521b44ed", - "sha256:b1dc7683da4e67ab2bebf266afa68098d681ae02ce570f0d1117312273d2b2ac", - "sha256:b29e27ce9371810250cb1528a771d047a9c7b0f79630dc7dc5815ff828f4273b", - "sha256:ce197559596370d985f1ce6b7051b52126849d8159040293bf8b98cb2b3e1f78", - "sha256:d45cf6daaf22584eff2175f48f82c4aa24d8e72a44913c5aff801819bb73d11f", - "sha256:e2ff9496322b2ce947ba4a7a5eb048158de9d6f3fe9efce29f1e8dd6878561e6", - "sha256:f7b979518ec1f294a41a707c007d54d0f3b3e1fd15d5b26b7e99b62b10d9a72e", - "sha256:f9c7268e9d16e34e50f8246c4f24cf7353764affd2bc971f0379514c246e3f6b", - "sha256:f9c839806089d79de588ee1dde2dae05dc1156d3355dfeb2b51fde84d9c960ad", - "sha256:ff962953e2389226adc4d355e34a98b0b800984399153c6678f2367b11b4d4b8" - ], - "version": "==4.3.2" + "sha256:03984196d00670b2ab14ae0ea83d5cc0cfa4f5a42558afa9ab5fa745995328f5", + "sha256:0815b0c9f897468de6a386dc15917a0becf48cc92425613aa8bbfc7f0f82951f", + "sha256:175f3825f075cf02d15099eb52658457cf0ff103dcf11512b5d2583e1d40f58b", + "sha256:30e14c62d88d1e01a26936ecd1c6e784d4afc9aa002bba4321c5897937112616", + "sha256:3210da6f36cf4b835ff1be853962b22cc354d506f493b67a4303c88bbb40d57b", + "sha256:40f60819fbd5bad6e191ba1329bfafa09ab7f3f174b3d034d413ef5266963294", + "sha256:43b26a865a61549919f8a42e094dfdb62847113cf776d84bd6b60e4e3fc20ea3", + "sha256:4a03dd682f8e35a10234904e0b9508d705ff98cf962c5851ed052e9340df3d90", + "sha256:62f382cddf3d2e52cf266e161aa522d54fd624b8cc567bc18f573d9d50d40e8e", + "sha256:7b98f0325be8450da70aa4a796c4f06852949fe031878b4aa1d6c417a412f314", + "sha256:846a0739e595871041385d86d12af4b6999f921359b38affb99cdd6b54219a8f", + "sha256:a3080470559938a09a5d0ec558c005282e99ac77bf8211fb7b9a5c66390acd8d", + "sha256:ad841b78a476623955da270ab8d207c3c694aa5eba71f4792f65926dc46c6ee8", + "sha256:afdd75d9735e44c639ffd6258ce04a2de3b208f148072c02478162d0944d9da3", + "sha256:b4fbf9b552faff54742bcd0791ab1da5863363fb19047e68f6592be1ac2dab33", + "sha256:b90c4e32d6ec089d3fa3518436bdf5ce4d902a0787dbd9bb09f37afe8b994317", + "sha256:b91cfe4438c741aeff662d413fd2808ac901cc6229c838236840d11de4586d63", + "sha256:bdb0593a42070b0a5f138b79b872289ee73c8e25b3f0bea6564e795b55b6bcdd", + "sha256:c4e4bca2bb68ce22320297dfa1a7bf070a5b20bcbaec4ee023f83d2f6e76496f", + "sha256:cec4ab14af9eae8501be3266ff50c3c2aecc017ba1e86c160209bb4f0423df6a", + "sha256:e83b4b2bf029f5104bc1227dbb7bf5ace6fd8fabaebffcd4f8106fafc69fc45f", + "sha256:e995b3734a46d41ae60b6097f7c51ba9958648c6d1e0935b7e0ee446ee4abe22", + "sha256:f679d93dec7f7210575c85379a31322df4c46496f184ef650d3aba1484b38a2d", + "sha256:fd213bb5166e46974f113c8228daaef1732abc47cb561ce9c4c8eaed4bd3b09b", + "sha256:fdcb57b906dbc1f80666e6290e794ab8fb959a2e17aa5aee1758a85d1da4533f", + "sha256:ff424b01d090ffe1947ec7432b07f536912e0300458f9a7f48ea217dd8362b86" + ], + "version": "==4.3.3" }, "markupsafe": { "hashes": [ @@ -295,6 +304,12 @@ ], "version": "==1.1.1" }, + "misaka": { + "hashes": [ + "sha256:62f35254550095d899fc2ab8b33e156fc5e674176f074959cbca43cf7912ecd7" + ], + "version": "==2.1.1" + }, "pycparser": { "hashes": [ "sha256:a988718abfad80b6b157acce7bf130a30876d27603738ac39f140993246b25b3" @@ -367,11 +382,11 @@ }, "python-snappy": { "hashes": [ - "sha256:59c79d83350f931ad5cf8f06ccb1c9bd1087a77c3ca7e00806884cda654a6faf", - "sha256:8a7f803f06083d4106d55387d2daa32c12b5e376c3616b0e2da8b8a87a27d74a" + "sha256:9c0ba725755b749ef9b03f6ed7582cefb957c0d9f6f064a7c4314148a9dbdb61", + "sha256:d9c26532cfa510f45e8d135cde140e8a5603d3fb254cfec273ebc0ecf9f668e2" ], "index": "pypi", - "version": "==0.5.3" + "version": "==0.5.4" }, "raven": { "hashes": [ @@ -406,10 +421,10 @@ }, "soupsieve": { "hashes": [ - "sha256:afa56bf14907bb09403e5d15fbed6275caa4174d36b975226e3b67a3bb6e2c4b", - "sha256:eaed742b48b1f3e2d45ba6f79401b2ed5dc33b2123dfe216adb90d4bfa0ade26" + "sha256:3aef141566afd07201b525c17bfaadd07580a8066f82b57f7c9417f26adbd0a3", + "sha256:e41a65e99bd125972d84221022beb1e4b5cfc68fa12c170c39834ce32d1b294c" ], - "version": "==1.8" + "version": "==1.9" }, "tabulate": { "hashes": [ @@ -433,10 +448,10 @@ }, "werkzeug": { "hashes": [ - "sha256:590abe38f8be026d78457fe3b5200895b3543e58ac3fc1dd792c6333ea11af64", - "sha256:ee11b0f0640c56fb491b43b38356c4b588b3202b415a1e03eacf1c5561c961cf" + "sha256:0a73e8bb2ff2feecfc5d56e6f458f5b99290ef34f565ffb2665801ff7de6af7a", + "sha256:7fad9770a8778f9576693f0cc29c7dcc36964df916b83734f4431c0e612a7fbc" ], - "version": "==0.15.0" + "version": "==0.15.2" }, "wtforms": { "hashes": [ @@ -552,11 +567,11 @@ }, "ipython": { "hashes": [ - "sha256:06de667a9e406924f97781bda22d5d76bfb39762b678762d86a466e63f65dc39", - "sha256:5d3e020a6b5f29df037555e5c45ab1088d6a7cf3bd84f47e0ba501eeb0c3ec82" + "sha256:b038baa489c38f6d853a3cfc4c635b0cda66f2864d136fe8f40c1a6e334e2a6b", + "sha256:f5102c1cd67e399ec8ea66bcebe6e3968ea25a8977e53f012963e5affeb1fe38" ], "index": "pypi", - "version": "==7.3.0" + "version": "==7.4.0" }, "ipython-genutils": { "hashes": [ @@ -567,10 +582,10 @@ }, "isort": { "hashes": [ - "sha256:18c796c2cd35eb1a1d3f012a214a542790a1aed95e29768bdcb9f2197eccbd0b", - "sha256:96151fca2c6e736503981896495d344781b60d18bfda78dc11b290c6125ebdb6" + "sha256:08f8e3f0f0b7249e9fad7e5c41e2113aba44969798a26452ee790c06f155d4ec", + "sha256:4e9e9c4bd1acd66cf6c36973f29b031ec752cbfd991c69695e4e259f9a756927" ], - "version": "==4.3.15" + "version": "==4.3.16" }, "jedi": { "hashes": [ @@ -622,11 +637,11 @@ }, "more-itertools": { "hashes": [ - "sha256:0125e8f60e9e031347105eb1682cef932f5e97d7b9a1a28d9bf00c22a5daef40", - "sha256:590044e3942351a1bdb1de960b739ff4ce277960f2425ad4509446dbace8d9d1" + "sha256:2112d2ca570bb7c3e53ea1a35cd5df42bb0fd10c45f0fb97178679c3c03d64c7", + "sha256:c3e4748ba1aad8dba30a4886b0b1a2004f9a863837b8654e7059eebf727afa5a" ], "markers": "python_version > '2.7'", - "version": "==6.0.0" + "version": "==7.0.0" }, "parso": { "hashes": [ @@ -746,11 +761,11 @@ }, "pytest": { "hashes": [ - "sha256:592eaa2c33fae68c7d75aacf042efc9f77b27c08a6224a4f59beab8d9a420523", - "sha256:ad3ad5c450284819ecde191a654c09b0ec72257a2c711b9633d677c71c9850c4" + "sha256:13c5e9fb5ec5179995e9357111ab089af350d788cbc944c628f3cde72285809b", + "sha256:f21d2f1fb8200830dcbb5d8ec466a9c9120e20d8b53c7585d180125cce1d297a" ], "index": "pypi", - "version": "==4.3.1" + "version": "==4.4.0" }, "pytest-cov": { "hashes": [ diff --git a/python/fatcat_web/__init__.py b/python/fatcat_web/__init__.py index 7d62bb5f..bd0a1888 100644 --- a/python/fatcat_web/__init__.py +++ b/python/fatcat_web/__init__.py @@ -4,6 +4,7 @@ from flask_uuid import FlaskUUID from flask_debugtoolbar import DebugToolbarExtension from flask_login import LoginManager from flask_wtf.csrf import CSRFProtect +from flask_misaka import Misaka from authlib.flask.client import OAuth from loginpass import create_flask_blueprint, Gitlab from raven.contrib.flask import Sentry @@ -19,6 +20,14 @@ toolbar = DebugToolbarExtension(app) FlaskUUID(app) app.csrf = CSRFProtect(app) +# This is the Markdown processor; setting default here +Misaka(app, + autolink=True, + no_intra_emphasis=True, + strikethrough=True, + escape=True, +) + login_manager = LoginManager() login_manager.init_app(app) login_manager.login_view = "/auth/login" diff --git a/python/fatcat_web/templates/editgroup_view.html b/python/fatcat_web/templates/editgroup_view.html index 2f61671d..31f9026f 100644 --- a/python/fatcat_web/templates/editgroup_view.html +++ b/python/fatcat_web/templates/editgroup_view.html @@ -124,7 +124,7 @@ reviewable bundle. {% endif %}
- {{ annotation.comment_markdown }} + {{ annotation.comment_markdown|markdown(escape=True) }}
{% else %} @@ -139,6 +139,7 @@ reviewable bundle.
+ Markdown is allowed -- cgit v1.2.3 From 2f6acbd81618803ef2400bb8a0a5c3684f5641a2 Mon Sep 17 00:00:00 2001 From: Bryan Newbold Date: Wed, 3 Apr 2019 19:55:22 -0700 Subject: create app.log explicitly --- python/fatcat_web/__init__.py | 2 ++ python/fatcat_web/auth.py | 12 ++++++------ python/fatcat_web/editing_routes.py | 28 ++++++++++++++-------------- python/fatcat_web/routes.py | 20 ++++++++++---------- 4 files changed, 32 insertions(+), 30 deletions(-) (limited to 'python/fatcat_web/__init__.py') diff --git a/python/fatcat_web/__init__.py b/python/fatcat_web/__init__.py index bd0a1888..3a332e84 100644 --- a/python/fatcat_web/__init__.py +++ b/python/fatcat_web/__init__.py @@ -1,5 +1,6 @@ from flask import Flask +from flask.logging import create_logger from flask_uuid import FlaskUUID from flask_debugtoolbar import DebugToolbarExtension from flask_login import LoginManager @@ -19,6 +20,7 @@ app.config.from_object(Config) toolbar = DebugToolbarExtension(app) FlaskUUID(app) app.csrf = CSRFProtect(app) +app.log = create_logger(app) # This is the Markdown processor; setting default here Misaka(app, diff --git a/python/fatcat_web/auth.py b/python/fatcat_web/auth.py index 79e7b19e..7f51b970 100644 --- a/python/fatcat_web/auth.py +++ b/python/fatcat_web/auth.py @@ -5,7 +5,7 @@ import pymacaroons from flask import Flask, render_template, send_from_directory, request, \ url_for, abort, g, redirect, jsonify, session, flash from flask_login import logout_user, login_user, UserMixin -from fatcat_web import login_manager, api, priv_api, Config +from fatcat_web import login_manager, app, api, priv_api, Config import fatcat_client def handle_logout(): @@ -20,7 +20,7 @@ def handle_token_login(token): m = pymacaroons.Macaroon.deserialize(token) except pymacaroons.exceptions.MacaroonDeserializationException: # TODO: what kind of Exceptions? - app.logger.warn("auth fail: MacaroonDeserializationException") + app.log.warn("auth fail: MacaroonDeserializationException") return abort(400) # extract editor_id editor_id = None @@ -29,7 +29,7 @@ def handle_token_login(token): if caveat.startswith(b"editor_id = "): editor_id = caveat[12:].decode('utf-8') if not editor_id: - app.logger.warn("auth fail: editor_id missing in macaroon") + app.log.warn("auth fail: editor_id missing in macaroon") abort(400) # fetch editor info editor = api.get_editor(editor_id) @@ -95,11 +95,11 @@ def handle_ia_xauth(email, password): try: flash("Internet Archive email/password didn't match: {}".format(resp.json()['values']['reason'])) except: - app.logger.warn("IA XAuth fail: {}".format(resp.content)) + app.log.warn("IA XAuth fail: {}".format(resp.content)) return render_template('auth_ia_login.html', email=email), resp.status_code elif resp.status_code != 200: flash("Internet Archive login failed (internal error?)") - app.logger.warn("IA XAuth fail: {}".format(resp.content)) + app.log.warn("IA XAuth fail: {}".format(resp.content)) return render_template('auth_ia_login.html', email=email), resp.status_code # Successful login; now fetch info... @@ -113,7 +113,7 @@ def handle_ia_xauth(email, password): }) if resp.status_code != 200: flash("Internet Archive login failed (internal error?)") - app.logger.warn("IA XAuth fail: {}".format(resp.content)) + app.log.warn("IA XAuth fail: {}".format(resp.content)) return render_template('auth_ia_login.html', email=email), resp.status_code ia_info = resp.json()['values'] diff --git a/python/fatcat_web/editing_routes.py b/python/fatcat_web/editing_routes.py index f45c5379..a9b3d326 100644 --- a/python/fatcat_web/editing_routes.py +++ b/python/fatcat_web/editing_routes.py @@ -28,7 +28,7 @@ def form_editgroup_get_or_create(api, edit_form): if ae.status == 404: edit_form.editgroup_id.errors.append("Editgroup does not exist") return None - app.logger.warn(ae) + app.log.warn(ae) abort(ae.status) # TODO: check here that editgroup hasn't been merged already else: @@ -37,7 +37,7 @@ def form_editgroup_get_or_create(api, edit_form): eg = api.create_editgroup( Editgroup(description=edit_form.editgroup_description.data or None)) except ApiException as ae: - app.logger.warn(ae) + app.log.warn(ae) abort(ae.status) # set this session editgroup_id session['active_editgroup_id'] = eg.editgroup_id @@ -62,12 +62,12 @@ def container_create(): try: edit = user_api.create_container(entity, editgroup_id=eg.editgroup_id) except ApiException as ae: - app.logger.warn(ae) + app.log.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)) + app.log.info("form errors (did not validate): {}".format(form.errors)) else: editgroup_id = session.get('active_editgroup_id', None) form.editgroup_id.data = editgroup_id @@ -94,13 +94,13 @@ def container_edit(ident): edit = user_api.update_container(entity.ident, entity, editgroup_id=eg.editgroup_id) except ApiException as ae: - app.logger.warn(ae) + app.log.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)) + app.log.info("form errors (did not validate): {}".format(form.errors)) else: form = ContainerEntityForm.from_entity(entity) if not form.is_submitted(): @@ -131,12 +131,12 @@ def file_create(): try: edit = user_api.create_file(entity, editgroup_id=eg.editgroup_id) except ApiException as ae: - app.logger.warn(ae) + app.log.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)) + app.log.info("form errors (did not validate): {}".format(form.errors)) else: editgroup_id = session.get('active_editgroup_id', None) form.editgroup_id.data = editgroup_id @@ -166,13 +166,13 @@ def file_edit(ident): edit = user_api.update_file(entity.ident, entity, editgroup_id=eg.editgroup_id) except ApiException as ae: - app.logger.warn(ae) + app.log.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)) + app.log.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) @@ -210,12 +210,12 @@ def release_create(): try: edit = user_api.create_release(entity, editgroup_id=eg.editgroup_id) except ApiException as ae: - app.logger.warn(ae) + app.log.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)) + app.log.info("form errors (did not validate): {}".format(form.errors)) else: # not submitted form.contribs.append_entry() editgroup_id = session.get('active_editgroup_id', None) @@ -243,13 +243,13 @@ def release_edit(ident): edit = user_api.update_release(entity.ident, entity, editgroup_id=eg.editgroup_id) except ApiException as ae: - app.logger.warn(ae) + app.log.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)) + app.log.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) diff --git a/python/fatcat_web/routes.py b/python/fatcat_web/routes.py index 7b406ff5..7d7f3feb 100644 --- a/python/fatcat_web/routes.py +++ b/python/fatcat_web/routes.py @@ -23,7 +23,7 @@ def container_history(ident): entity = api.get_container(ident) history = api.get_container_history(ident) except ApiException as ae: - app.logger.info(ae) + app.log.info(ae) abort(ae.status) #print(history) return render_template('entity_history.html', @@ -59,7 +59,7 @@ def container_view(ident): stats = get_elastic_container_stats(entity.issnl) except Exception as e: stats = None - app.logger.error(e) + app.log.error(e) else: stats = None @@ -338,7 +338,7 @@ def editgroup_create_annotation(ident): app.csrf.protect() comment_markdown = request.form.get('comment_markdown') if not comment_markdown: - app.logger.info("empty comment field") + app.log.info("empty comment field") abort(400) # on behalf of user... user_api = auth_api(session['api_token']) @@ -353,7 +353,7 @@ def editgroup_create_annotation(ident): ) user_api.create_editgroup_annotation(eg.editgroup_id, ega) except ApiException as ae: - app.logger.info(ae) + app.log.info(ae) abort(ae.status) return redirect('/editgroup/{}'.format(ident)) @@ -370,7 +370,7 @@ def editgroup_accept(ident): abort(400) user_api.accept_editgroup(str(ident)) except ApiException as ae: - app.logger.info(ae) + app.log.info(ae) abort(ae.status) return redirect('/editgroup/{}'.format(ident)) @@ -387,7 +387,7 @@ def editgroup_unsubmit(ident): abort(400) user_api.update_editgroup(eg.editgroup_id, eg, submit=False) except ApiException as ae: - app.logger.info(ae) + app.log.info(ae) abort(ae.status) return redirect('/editgroup/{}'.format(ident)) @@ -406,7 +406,7 @@ def editgroup_submit(ident): user_api.update_editgroup(eg.editgroup_id, eg, submit=True) except ApiException as ae: print(ae) - app.logger.info(ae) + app.log.info(ae) abort(ae.status) return redirect('/editgroup/{}'.format(ident)) @@ -516,7 +516,7 @@ def stats_page(): stats = get_elastic_entity_stats() stats.update(get_changelog_stats()) except Exception as ae: - app.logger.error(e) + app.log.error(e) abort(503) return render_template('stats.html', stats=stats) @@ -529,7 +529,7 @@ def stats_json(): stats = get_elastic_entity_stats() stats.update(get_changelog_stats()) except Exception as ae: - app.logger.error(e) + app.log.error(e) abort(503) return jsonify(stats) @@ -539,7 +539,7 @@ def container_issnl_stats(issnl): try: stats = get_elastic_container_stats(issnl) except Exception as ae: - app.logger.error(e) + app.log.error(e) abort(503) return jsonify(stats) -- cgit v1.2.3