Move cached_endpoint, required_fields to flasktools.
This commit is contained in:
parent
e883409daf
commit
d4025e865b
6 changed files with 27 additions and 143 deletions
|
@ -1,93 +1,11 @@
|
||||||
import flask; from flask import request
|
import flask; from flask import request
|
||||||
import functools
|
import functools
|
||||||
import time
|
|
||||||
import werkzeug.datastructures
|
import werkzeug.datastructures
|
||||||
|
|
||||||
from voussoirkit import dotdict
|
|
||||||
from voussoirkit import flasktools
|
from voussoirkit import flasktools
|
||||||
from voussoirkit import passwordy
|
|
||||||
from voussoirkit import sentinel
|
|
||||||
|
|
||||||
import etiquette
|
import etiquette
|
||||||
|
|
||||||
NOT_CACHED = sentinel.Sentinel('not cached', truthyness=False)
|
|
||||||
|
|
||||||
def cached_endpoint(max_age):
|
|
||||||
'''
|
|
||||||
The cached_endpoint decorator can be used on slow endpoints that don't need
|
|
||||||
to be constantly updated or endpoints that produce large, static responses.
|
|
||||||
|
|
||||||
WARNING: The return value of the endpoint is shared with all users.
|
|
||||||
You should never use this cache on an endpoint that provides private
|
|
||||||
or personalized data, and you should not try to pass other headers through
|
|
||||||
the response.
|
|
||||||
|
|
||||||
When the function is run, its return value is stored and a random etag is
|
|
||||||
generated so that subsequent runs can respond with 304. This way, large
|
|
||||||
response bodies do not need to be transmitted often.
|
|
||||||
|
|
||||||
Given a nonzero max_age, the endpoint will only be run once per max_age
|
|
||||||
seconds on a global basis (not per-user). This way, you can prevent a slow
|
|
||||||
function from being run very often. In-between requests will just receive
|
|
||||||
the previous return value (still using 200 or 304 as appropriate for the
|
|
||||||
client's provided etag).
|
|
||||||
|
|
||||||
With max_age=0, the function will be run every time to check if the value
|
|
||||||
has changed, but if it hasn't changed then we can still send a 304 response,
|
|
||||||
saving bandwidth.
|
|
||||||
|
|
||||||
An example use case would be large-sized data dumps that don't need to be
|
|
||||||
precisely up to date every time.
|
|
||||||
'''
|
|
||||||
if max_age < 0:
|
|
||||||
raise ValueError(f'max_age should be positive, not {max_age}.')
|
|
||||||
|
|
||||||
state = dotdict.DotDict({
|
|
||||||
'max_age': max_age,
|
|
||||||
'stored_value': NOT_CACHED,
|
|
||||||
'stored_etag': None,
|
|
||||||
'headers': {'ETag': None, 'Cache-Control': f'max-age={max_age}'},
|
|
||||||
'last_run': 0,
|
|
||||||
})
|
|
||||||
|
|
||||||
def wrapper(function):
|
|
||||||
def get_value(*args, **kwargs):
|
|
||||||
can_bail = (
|
|
||||||
state.stored_value is not NOT_CACHED and
|
|
||||||
state.max_age != 0 and
|
|
||||||
(time.time() - state.last_run) < state.max_age
|
|
||||||
)
|
|
||||||
if can_bail:
|
|
||||||
return state.stored_value
|
|
||||||
|
|
||||||
value = function(*args, **kwargs)
|
|
||||||
if isinstance(value, flask.Response):
|
|
||||||
if value.headers.get('Content-Type'):
|
|
||||||
state.headers['Content-Type'] = value.headers.get('Content-Type')
|
|
||||||
value = value.response
|
|
||||||
|
|
||||||
if value != state.stored_value:
|
|
||||||
state.stored_value = value
|
|
||||||
state.stored_etag = passwordy.random_hex(20)
|
|
||||||
state.headers['ETag'] = state.stored_etag
|
|
||||||
|
|
||||||
state.last_run = time.time()
|
|
||||||
return value
|
|
||||||
|
|
||||||
@functools.wraps(function)
|
|
||||||
def wrapped(*args, **kwargs):
|
|
||||||
value = get_value(*args, **kwargs)
|
|
||||||
|
|
||||||
client_etag = request.headers.get('If-None-Match', None)
|
|
||||||
if client_etag == state.stored_etag:
|
|
||||||
response = flask.Response(status=304, headers=state.headers)
|
|
||||||
else:
|
|
||||||
response = flask.Response(value, status=200, headers=state.headers)
|
|
||||||
|
|
||||||
return response
|
|
||||||
return wrapped
|
|
||||||
return wrapper
|
|
||||||
|
|
||||||
def catch_etiquette_exception(function):
|
def catch_etiquette_exception(function):
|
||||||
'''
|
'''
|
||||||
If an EtiquetteException is raised, automatically catch it and convert it
|
If an EtiquetteException is raised, automatically catch it and convert it
|
||||||
|
@ -128,32 +46,3 @@ def give_theme_cookie(function):
|
||||||
|
|
||||||
return response
|
return response
|
||||||
return wrapped
|
return wrapped
|
||||||
|
|
||||||
def required_fields(fields, forbid_whitespace=False):
|
|
||||||
'''
|
|
||||||
Declare that the endpoint requires certain POST body fields. Without them,
|
|
||||||
we respond with 400 and a message.
|
|
||||||
|
|
||||||
forbid_whitespace:
|
|
||||||
If True, then providing the field is not good enough. It must also
|
|
||||||
contain at least some non-whitespace characters.
|
|
||||||
'''
|
|
||||||
def wrapper(function):
|
|
||||||
@functools.wraps(function)
|
|
||||||
def wrapped(*args, **kwargs):
|
|
||||||
for requirement in fields:
|
|
||||||
missing = (
|
|
||||||
requirement not in request.form or
|
|
||||||
(forbid_whitespace and request.form[requirement].strip() == '')
|
|
||||||
)
|
|
||||||
if missing:
|
|
||||||
response = {
|
|
||||||
'error_type': 'MISSING_FIELDS',
|
|
||||||
'error_message': 'Required fields: %s' % ', '.join(fields),
|
|
||||||
}
|
|
||||||
response = flasktools.make_json_response(response, status=400)
|
|
||||||
return response
|
|
||||||
|
|
||||||
return function(*args, **kwargs)
|
|
||||||
return wrapped
|
|
||||||
return wrapper
|
|
||||||
|
|
|
@ -9,7 +9,6 @@ from voussoirkit import stringtools
|
||||||
import etiquette
|
import etiquette
|
||||||
|
|
||||||
from .. import common
|
from .. import common
|
||||||
from .. import decorators
|
|
||||||
|
|
||||||
site = common.site
|
site = common.site
|
||||||
session_manager = common.session_manager
|
session_manager = common.session_manager
|
||||||
|
@ -57,7 +56,7 @@ def get_album_zip(album_id):
|
||||||
return flask.Response(streamed_zip, headers=outgoing_headers)
|
return flask.Response(streamed_zip, headers=outgoing_headers)
|
||||||
|
|
||||||
@site.route('/album/<album_id>/add_child', methods=['POST'])
|
@site.route('/album/<album_id>/add_child', methods=['POST'])
|
||||||
@decorators.required_fields(['child_id'], forbid_whitespace=True)
|
@flasktools.required_fields(['child_id'], forbid_whitespace=True)
|
||||||
def post_album_add_child(album_id):
|
def post_album_add_child(album_id):
|
||||||
album = common.P_album(album_id, response_type='json')
|
album = common.P_album(album_id, response_type='json')
|
||||||
|
|
||||||
|
@ -69,7 +68,7 @@ def post_album_add_child(album_id):
|
||||||
return flasktools.make_json_response(response)
|
return flasktools.make_json_response(response)
|
||||||
|
|
||||||
@site.route('/album/<album_id>/remove_child', methods=['POST'])
|
@site.route('/album/<album_id>/remove_child', methods=['POST'])
|
||||||
@decorators.required_fields(['child_id'], forbid_whitespace=True)
|
@flasktools.required_fields(['child_id'], forbid_whitespace=True)
|
||||||
def post_album_remove_child(album_id):
|
def post_album_remove_child(album_id):
|
||||||
album = common.P_album(album_id, response_type='json')
|
album = common.P_album(album_id, response_type='json')
|
||||||
|
|
||||||
|
@ -98,7 +97,7 @@ def post_album_refresh_directories(album_id):
|
||||||
return flasktools.make_json_response({})
|
return flasktools.make_json_response({})
|
||||||
|
|
||||||
@site.route('/album/<album_id>/set_thumbnail_photo', methods=['POST'])
|
@site.route('/album/<album_id>/set_thumbnail_photo', methods=['POST'])
|
||||||
@decorators.required_fields(['photo_id'], forbid_whitespace=True)
|
@flasktools.required_fields(['photo_id'], forbid_whitespace=True)
|
||||||
def post_album_set_thumbnail_photo(album_id):
|
def post_album_set_thumbnail_photo(album_id):
|
||||||
album = common.P_album(album_id, response_type='json')
|
album = common.P_album(album_id, response_type='json')
|
||||||
photo = common.P_photo(request.form['photo_id'], response_type='json')
|
photo = common.P_photo(request.form['photo_id'], response_type='json')
|
||||||
|
@ -109,7 +108,7 @@ def post_album_set_thumbnail_photo(album_id):
|
||||||
# Album photo operations ###########################################################################
|
# Album photo operations ###########################################################################
|
||||||
|
|
||||||
@site.route('/album/<album_id>/add_photo', methods=['POST'])
|
@site.route('/album/<album_id>/add_photo', methods=['POST'])
|
||||||
@decorators.required_fields(['photo_id'], forbid_whitespace=True)
|
@flasktools.required_fields(['photo_id'], forbid_whitespace=True)
|
||||||
def post_album_add_photo(album_id):
|
def post_album_add_photo(album_id):
|
||||||
'''
|
'''
|
||||||
Add a photo or photos to this album.
|
Add a photo or photos to this album.
|
||||||
|
@ -123,7 +122,7 @@ def post_album_add_photo(album_id):
|
||||||
return flasktools.make_json_response(response)
|
return flasktools.make_json_response(response)
|
||||||
|
|
||||||
@site.route('/album/<album_id>/remove_photo', methods=['POST'])
|
@site.route('/album/<album_id>/remove_photo', methods=['POST'])
|
||||||
@decorators.required_fields(['photo_id'], forbid_whitespace=True)
|
@flasktools.required_fields(['photo_id'], forbid_whitespace=True)
|
||||||
def post_album_remove_photo(album_id):
|
def post_album_remove_photo(album_id):
|
||||||
'''
|
'''
|
||||||
Remove a photo or photos from this album.
|
Remove a photo or photos from this album.
|
||||||
|
@ -195,7 +194,7 @@ def post_album_show_in_folder(album_id):
|
||||||
# Album listings ###################################################################################
|
# Album listings ###################################################################################
|
||||||
|
|
||||||
@site.route('/all_albums.json')
|
@site.route('/all_albums.json')
|
||||||
@decorators.cached_endpoint(max_age=15)
|
@flasktools.cached_endpoint(max_age=15)
|
||||||
def get_all_album_names():
|
def get_all_album_names():
|
||||||
all_albums = {album.id: album.display_name for album in common.P.get_albums()}
|
all_albums = {album.id: album.display_name for album in common.P.get_albums()}
|
||||||
response = {'albums': all_albums}
|
response = {'albums': all_albums}
|
||||||
|
|
|
@ -5,7 +5,6 @@ from voussoirkit import flasktools
|
||||||
import etiquette
|
import etiquette
|
||||||
|
|
||||||
from .. import common
|
from .. import common
|
||||||
from .. import decorators
|
|
||||||
|
|
||||||
site = common.site
|
site = common.site
|
||||||
session_manager = common.session_manager
|
session_manager = common.session_manager
|
||||||
|
@ -45,7 +44,7 @@ def get_bookmarks_json():
|
||||||
# Bookmark create and delete #######################################################################
|
# Bookmark create and delete #######################################################################
|
||||||
|
|
||||||
@site.route('/bookmarks/create_bookmark', methods=['POST'])
|
@site.route('/bookmarks/create_bookmark', methods=['POST'])
|
||||||
@decorators.required_fields(['url'], forbid_whitespace=True)
|
@flasktools.required_fields(['url'], forbid_whitespace=True)
|
||||||
def post_bookmark_create():
|
def post_bookmark_create():
|
||||||
url = request.form['url']
|
url = request.form['url']
|
||||||
title = request.form.get('title', None)
|
title = request.form.get('title', None)
|
||||||
|
|
|
@ -10,7 +10,6 @@ from voussoirkit import stringtools
|
||||||
import etiquette
|
import etiquette
|
||||||
|
|
||||||
from .. import common
|
from .. import common
|
||||||
from .. import decorators
|
|
||||||
from .. import helpers
|
from .. import helpers
|
||||||
|
|
||||||
site = common.site
|
site = common.site
|
||||||
|
@ -98,7 +97,7 @@ def post_photo_add_remove_tag_core(photo_ids, tagname, add_or_remove):
|
||||||
return flasktools.make_json_response(response)
|
return flasktools.make_json_response(response)
|
||||||
|
|
||||||
@site.route('/photo/<photo_id>/add_tag', methods=['POST'])
|
@site.route('/photo/<photo_id>/add_tag', methods=['POST'])
|
||||||
@decorators.required_fields(['tagname'], forbid_whitespace=True)
|
@flasktools.required_fields(['tagname'], forbid_whitespace=True)
|
||||||
def post_photo_add_tag(photo_id):
|
def post_photo_add_tag(photo_id):
|
||||||
'''
|
'''
|
||||||
Add a tag to this photo.
|
Add a tag to this photo.
|
||||||
|
@ -111,7 +110,7 @@ def post_photo_add_tag(photo_id):
|
||||||
return response
|
return response
|
||||||
|
|
||||||
@site.route('/photo/<photo_id>/copy_tags', methods=['POST'])
|
@site.route('/photo/<photo_id>/copy_tags', methods=['POST'])
|
||||||
@decorators.required_fields(['other_photo'], forbid_whitespace=True)
|
@flasktools.required_fields(['other_photo'], forbid_whitespace=True)
|
||||||
def post_photo_copy_tags(photo_id):
|
def post_photo_copy_tags(photo_id):
|
||||||
'''
|
'''
|
||||||
Copy the tags from another photo.
|
Copy the tags from another photo.
|
||||||
|
@ -123,7 +122,7 @@ def post_photo_copy_tags(photo_id):
|
||||||
return flasktools.make_json_response([tag.jsonify(minimal=True) for tag in photo.get_tags()])
|
return flasktools.make_json_response([tag.jsonify(minimal=True) for tag in photo.get_tags()])
|
||||||
|
|
||||||
@site.route('/photo/<photo_id>/remove_tag', methods=['POST'])
|
@site.route('/photo/<photo_id>/remove_tag', methods=['POST'])
|
||||||
@decorators.required_fields(['tagname'], forbid_whitespace=True)
|
@flasktools.required_fields(['tagname'], forbid_whitespace=True)
|
||||||
def post_photo_remove_tag(photo_id):
|
def post_photo_remove_tag(photo_id):
|
||||||
'''
|
'''
|
||||||
Remove a tag from this photo.
|
Remove a tag from this photo.
|
||||||
|
@ -136,7 +135,7 @@ def post_photo_remove_tag(photo_id):
|
||||||
return response
|
return response
|
||||||
|
|
||||||
@site.route('/batch/photos/add_tag', methods=['POST'])
|
@site.route('/batch/photos/add_tag', methods=['POST'])
|
||||||
@decorators.required_fields(['photo_ids', 'tagname'], forbid_whitespace=True)
|
@flasktools.required_fields(['photo_ids', 'tagname'], forbid_whitespace=True)
|
||||||
def post_batch_photos_add_tag():
|
def post_batch_photos_add_tag():
|
||||||
response = post_photo_add_remove_tag_core(
|
response = post_photo_add_remove_tag_core(
|
||||||
photo_ids=request.form['photo_ids'],
|
photo_ids=request.form['photo_ids'],
|
||||||
|
@ -146,7 +145,7 @@ def post_batch_photos_add_tag():
|
||||||
return response
|
return response
|
||||||
|
|
||||||
@site.route('/batch/photos/remove_tag', methods=['POST'])
|
@site.route('/batch/photos/remove_tag', methods=['POST'])
|
||||||
@decorators.required_fields(['photo_ids', 'tagname'], forbid_whitespace=True)
|
@flasktools.required_fields(['photo_ids', 'tagname'], forbid_whitespace=True)
|
||||||
def post_batch_photos_remove_tag():
|
def post_batch_photos_remove_tag():
|
||||||
response = post_photo_add_remove_tag_core(
|
response = post_photo_add_remove_tag_core(
|
||||||
photo_ids=request.form['photo_ids'],
|
photo_ids=request.form['photo_ids'],
|
||||||
|
@ -194,7 +193,7 @@ def post_photo_refresh_metadata(photo_id):
|
||||||
return response
|
return response
|
||||||
|
|
||||||
@site.route('/batch/photos/refresh_metadata', methods=['POST'])
|
@site.route('/batch/photos/refresh_metadata', methods=['POST'])
|
||||||
@decorators.required_fields(['photo_ids'], forbid_whitespace=True)
|
@flasktools.required_fields(['photo_ids'], forbid_whitespace=True)
|
||||||
def post_batch_photos_refresh_metadata():
|
def post_batch_photos_refresh_metadata():
|
||||||
response = post_photo_refresh_metadata_core(photo_ids=request.form['photo_ids'])
|
response = post_photo_refresh_metadata_core(photo_ids=request.form['photo_ids'])
|
||||||
return response
|
return response
|
||||||
|
@ -238,14 +237,14 @@ def post_photo_show_in_folder(photo_id):
|
||||||
flask.abort(501)
|
flask.abort(501)
|
||||||
|
|
||||||
@site.route('/batch/photos/set_searchhidden', methods=['POST'])
|
@site.route('/batch/photos/set_searchhidden', methods=['POST'])
|
||||||
@decorators.required_fields(['photo_ids'], forbid_whitespace=True)
|
@flasktools.required_fields(['photo_ids'], forbid_whitespace=True)
|
||||||
def post_batch_photos_set_searchhidden():
|
def post_batch_photos_set_searchhidden():
|
||||||
photo_ids = request.form['photo_ids']
|
photo_ids = request.form['photo_ids']
|
||||||
response = post_batch_photos_searchhidden_core(photo_ids=photo_ids, searchhidden=True)
|
response = post_batch_photos_searchhidden_core(photo_ids=photo_ids, searchhidden=True)
|
||||||
return response
|
return response
|
||||||
|
|
||||||
@site.route('/batch/photos/unset_searchhidden', methods=['POST'])
|
@site.route('/batch/photos/unset_searchhidden', methods=['POST'])
|
||||||
@decorators.required_fields(['photo_ids'], forbid_whitespace=True)
|
@flasktools.required_fields(['photo_ids'], forbid_whitespace=True)
|
||||||
def post_batch_photos_unset_searchhidden():
|
def post_batch_photos_unset_searchhidden():
|
||||||
photo_ids = request.form['photo_ids']
|
photo_ids = request.form['photo_ids']
|
||||||
response = post_batch_photos_searchhidden_core(photo_ids=photo_ids, searchhidden=False)
|
response = post_batch_photos_searchhidden_core(photo_ids=photo_ids, searchhidden=False)
|
||||||
|
@ -258,7 +257,7 @@ def get_clipboard_page():
|
||||||
return common.render_template(request, 'clipboard.html')
|
return common.render_template(request, 'clipboard.html')
|
||||||
|
|
||||||
@site.route('/batch/photos', methods=['POST'])
|
@site.route('/batch/photos', methods=['POST'])
|
||||||
@decorators.required_fields(['photo_ids'], forbid_whitespace=True)
|
@flasktools.required_fields(['photo_ids'], forbid_whitespace=True)
|
||||||
def post_batch_photos():
|
def post_batch_photos():
|
||||||
'''
|
'''
|
||||||
Return a list of photo.jsonify() for each requested photo id.
|
Return a list of photo.jsonify() for each requested photo id.
|
||||||
|
@ -273,7 +272,7 @@ def post_batch_photos():
|
||||||
return response
|
return response
|
||||||
|
|
||||||
@site.route('/batch/photos/photo_card', methods=['POST'])
|
@site.route('/batch/photos/photo_card', methods=['POST'])
|
||||||
@decorators.required_fields(['photo_ids'], forbid_whitespace=True)
|
@flasktools.required_fields(['photo_ids'], forbid_whitespace=True)
|
||||||
def post_batch_photos_photo_cards():
|
def post_batch_photos_photo_cards():
|
||||||
photo_ids = request.form['photo_ids']
|
photo_ids = request.form['photo_ids']
|
||||||
|
|
||||||
|
@ -328,7 +327,7 @@ def get_batch_photos_download_zip(zip_token):
|
||||||
return flask.Response(streamed_zip, headers=outgoing_headers)
|
return flask.Response(streamed_zip, headers=outgoing_headers)
|
||||||
|
|
||||||
@site.route('/batch/photos/download_zip', methods=['POST'])
|
@site.route('/batch/photos/download_zip', methods=['POST'])
|
||||||
@decorators.required_fields(['photo_ids'], forbid_whitespace=True)
|
@flasktools.required_fields(['photo_ids'], forbid_whitespace=True)
|
||||||
def post_batch_photos_download_zip():
|
def post_batch_photos_download_zip():
|
||||||
'''
|
'''
|
||||||
Initiating file downloads via POST requests is a bit clunky and unreliable,
|
Initiating file downloads via POST requests is a bit clunky and unreliable,
|
||||||
|
|
|
@ -5,7 +5,6 @@ from voussoirkit import flasktools
|
||||||
import etiquette
|
import etiquette
|
||||||
|
|
||||||
from .. import common
|
from .. import common
|
||||||
from .. import decorators
|
|
||||||
|
|
||||||
site = common.site
|
site = common.site
|
||||||
session_manager = common.session_manager
|
session_manager = common.session_manager
|
||||||
|
@ -57,7 +56,7 @@ def post_tag_edit(tagname):
|
||||||
return response
|
return response
|
||||||
|
|
||||||
@site.route('/tag/<tagname>/add_child', methods=['POST'])
|
@site.route('/tag/<tagname>/add_child', methods=['POST'])
|
||||||
@decorators.required_fields(['child_name'], forbid_whitespace=True)
|
@flasktools.required_fields(['child_name'], forbid_whitespace=True)
|
||||||
def post_tag_add_child(tagname):
|
def post_tag_add_child(tagname):
|
||||||
parent = common.P_tag(tagname, response_type='json')
|
parent = common.P_tag(tagname, response_type='json')
|
||||||
child = common.P_tag(request.form['child_name'], response_type='json')
|
child = common.P_tag(request.form['child_name'], response_type='json')
|
||||||
|
@ -66,7 +65,7 @@ def post_tag_add_child(tagname):
|
||||||
return flasktools.make_json_response(response)
|
return flasktools.make_json_response(response)
|
||||||
|
|
||||||
@site.route('/tag/<tagname>/add_synonym', methods=['POST'])
|
@site.route('/tag/<tagname>/add_synonym', methods=['POST'])
|
||||||
@decorators.required_fields(['syn_name'], forbid_whitespace=True)
|
@flasktools.required_fields(['syn_name'], forbid_whitespace=True)
|
||||||
def post_tag_add_synonym(tagname):
|
def post_tag_add_synonym(tagname):
|
||||||
syn_name = request.form['syn_name']
|
syn_name = request.form['syn_name']
|
||||||
|
|
||||||
|
@ -77,7 +76,7 @@ def post_tag_add_synonym(tagname):
|
||||||
return flasktools.make_json_response(response)
|
return flasktools.make_json_response(response)
|
||||||
|
|
||||||
@site.route('/tag/<tagname>/remove_child', methods=['POST'])
|
@site.route('/tag/<tagname>/remove_child', methods=['POST'])
|
||||||
@decorators.required_fields(['child_name'], forbid_whitespace=True)
|
@flasktools.required_fields(['child_name'], forbid_whitespace=True)
|
||||||
def post_tag_remove_child(tagname):
|
def post_tag_remove_child(tagname):
|
||||||
parent = common.P_tag(tagname, response_type='json')
|
parent = common.P_tag(tagname, response_type='json')
|
||||||
child = common.P_tag(request.form['child_name'], response_type='json')
|
child = common.P_tag(request.form['child_name'], response_type='json')
|
||||||
|
@ -86,7 +85,7 @@ def post_tag_remove_child(tagname):
|
||||||
return flasktools.make_json_response(response)
|
return flasktools.make_json_response(response)
|
||||||
|
|
||||||
@site.route('/tag/<tagname>/remove_synonym', methods=['POST'])
|
@site.route('/tag/<tagname>/remove_synonym', methods=['POST'])
|
||||||
@decorators.required_fields(['syn_name'], forbid_whitespace=True)
|
@flasktools.required_fields(['syn_name'], forbid_whitespace=True)
|
||||||
def post_tag_remove_synonym(tagname):
|
def post_tag_remove_synonym(tagname):
|
||||||
syn_name = request.form['syn_name']
|
syn_name = request.form['syn_name']
|
||||||
|
|
||||||
|
@ -99,7 +98,7 @@ def post_tag_remove_synonym(tagname):
|
||||||
# Tag listings #####################################################################################
|
# Tag listings #####################################################################################
|
||||||
|
|
||||||
@site.route('/all_tags.json')
|
@site.route('/all_tags.json')
|
||||||
@decorators.cached_endpoint(max_age=15)
|
@flasktools.cached_endpoint(max_age=15)
|
||||||
def get_all_tag_names():
|
def get_all_tag_names():
|
||||||
all_tags = list(common.P.get_all_tag_names())
|
all_tags = list(common.P.get_all_tag_names())
|
||||||
all_synonyms = common.P.get_all_synonyms()
|
all_synonyms = common.P.get_all_synonyms()
|
||||||
|
@ -158,7 +157,7 @@ def get_tags_json():
|
||||||
# Tag create and delete ############################################################################
|
# Tag create and delete ############################################################################
|
||||||
|
|
||||||
@site.route('/tags/create_tag', methods=['POST'])
|
@site.route('/tags/create_tag', methods=['POST'])
|
||||||
@decorators.required_fields(['name'], forbid_whitespace=True)
|
@flasktools.required_fields(['name'], forbid_whitespace=True)
|
||||||
def post_tag_create():
|
def post_tag_create():
|
||||||
name = request.form['name']
|
name = request.form['name']
|
||||||
description = request.form.get('description', None)
|
description = request.form.get('description', None)
|
||||||
|
@ -168,7 +167,7 @@ def post_tag_create():
|
||||||
return flasktools.make_json_response(response)
|
return flasktools.make_json_response(response)
|
||||||
|
|
||||||
@site.route('/tags/easybake', methods=['POST'])
|
@site.route('/tags/easybake', methods=['POST'])
|
||||||
@decorators.required_fields(['easybake_string'], forbid_whitespace=True)
|
@flasktools.required_fields(['easybake_string'], forbid_whitespace=True)
|
||||||
def post_tag_easybake():
|
def post_tag_easybake():
|
||||||
easybake_string = request.form['easybake_string']
|
easybake_string = request.form['easybake_string']
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,6 @@ from voussoirkit import flasktools
|
||||||
import etiquette
|
import etiquette
|
||||||
|
|
||||||
from .. import common
|
from .. import common
|
||||||
from .. import decorators
|
|
||||||
from .. import sessions
|
from .. import sessions
|
||||||
|
|
||||||
site = common.site
|
site = common.site
|
||||||
|
@ -67,7 +66,7 @@ def get_login():
|
||||||
return response
|
return response
|
||||||
|
|
||||||
@site.route('/login', methods=['POST'])
|
@site.route('/login', methods=['POST'])
|
||||||
@decorators.required_fields(['username', 'password'])
|
@flasktools.required_fields(['username', 'password'])
|
||||||
def post_login():
|
def post_login():
|
||||||
session = session_manager.get(request)
|
session = session_manager.get(request)
|
||||||
if session.user:
|
if session.user:
|
||||||
|
@ -107,7 +106,7 @@ def get_register():
|
||||||
return flask.redirect('/login')
|
return flask.redirect('/login')
|
||||||
|
|
||||||
@site.route('/register', methods=['POST'])
|
@site.route('/register', methods=['POST'])
|
||||||
@decorators.required_fields(['username', 'password_1', 'password_2'])
|
@flasktools.required_fields(['username', 'password_1', 'password_2'])
|
||||||
def post_register():
|
def post_register():
|
||||||
session = session_manager.get(request)
|
session = session_manager.get(request)
|
||||||
if session.user:
|
if session.user:
|
||||||
|
|
Loading…
Reference in a new issue