Further separate front & back; Create frontends folder
New frontends folder will hold all front-end interfaces for etiquette. Existing flask site moved here and refers to itself as a package with external launcher. etiquette_site renamed to etiquette_flask
|  | @ -1,3 +1,6 @@ | ||||||
| from . import decorators | from . import decorators | ||||||
|  | from . import etiquette_flask | ||||||
| from . import jsonify | from . import jsonify | ||||||
| from . import sessions | from . import sessions | ||||||
|  | 
 | ||||||
|  | site = etiquette_flask.site | ||||||
|  | @ -10,13 +10,16 @@ import warnings | ||||||
| import zipstream | import zipstream | ||||||
| 
 | 
 | ||||||
| import etiquette | import etiquette | ||||||
| import etiquette_flask | 
 | ||||||
|  | from . import decorators | ||||||
|  | from . import jsonify | ||||||
|  | from . import sessions | ||||||
| 
 | 
 | ||||||
| from voussoirkit import pathclass | from voussoirkit import pathclass | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| root_dir = pathclass.Path(__file__).parent | root_dir = pathclass.Path(__file__).parent.parent | ||||||
| 
 | print(root_dir) | ||||||
| TEMPLATE_DIR = root_dir.with_child('templates') | TEMPLATE_DIR = root_dir.with_child('templates') | ||||||
| STATIC_DIR = root_dir.with_child('static') | STATIC_DIR = root_dir.with_child('static') | ||||||
| FAVICON_PATH = STATIC_DIR.with_child('favicon.png') | FAVICON_PATH = STATIC_DIR.with_child('favicon.png') | ||||||
|  | @ -37,7 +40,7 @@ site.debug = True | ||||||
| 
 | 
 | ||||||
| P = etiquette.photodb.PhotoDB() | P = etiquette.photodb.PhotoDB() | ||||||
| 
 | 
 | ||||||
| session_manager = etiquette_flask.sessions.SessionManager() | session_manager = sessions.SessionManager() | ||||||
| 
 | 
 | ||||||
| #################################################################################################### | #################################################################################################### | ||||||
| #################################################################################################### | #################################################################################################### | ||||||
|  | @ -86,7 +89,7 @@ def P_wrapper(function): | ||||||
|                 flask.abort(status, e.error_message) |                 flask.abort(status, e.error_message) | ||||||
|             else: |             else: | ||||||
|                 response = etiquette.jsonify.exception(e) |                 response = etiquette.jsonify.exception(e) | ||||||
|                 response = etiquette_flask.jsonify.make_json_response(response, status=status) |                 response = jsonify.make_json_response(response, status=status) | ||||||
|                 flask.abort(response) |                 flask.abort(response) | ||||||
| 
 | 
 | ||||||
|         except Exception as e: |         except Exception as e: | ||||||
|  | @ -213,12 +216,12 @@ def get_register(): | ||||||
| 
 | 
 | ||||||
| @site.route('/login', methods=['POST']) | @site.route('/login', methods=['POST']) | ||||||
| @session_manager.give_token | @session_manager.give_token | ||||||
| @etiquette_flask.decorators.required_fields(['username', 'password']) | @decorators.required_fields(['username', 'password']) | ||||||
| def post_login(): | def post_login(): | ||||||
|     if session_manager.get(request): |     if session_manager.get(request): | ||||||
|         e = etiquette.exceptions.AlreadySignedIn() |         e = etiquette.exceptions.AlreadySignedIn() | ||||||
|         response = etiquette.jsonify.exception(e) |         response = etiquette.jsonify.exception(e) | ||||||
|         return etiquette_flask.jsonify.make_json_response(response, status=403) |         return jsonify.make_json_response(response, status=403) | ||||||
| 
 | 
 | ||||||
|     username = request.form['username'] |     username = request.form['username'] | ||||||
|     password = request.form['password'] |     password = request.form['password'] | ||||||
|  | @ -232,19 +235,19 @@ def post_login(): | ||||||
|     except (etiquette.exceptions.NoSuchUser, etiquette.exceptions.WrongLogin): |     except (etiquette.exceptions.NoSuchUser, etiquette.exceptions.WrongLogin): | ||||||
|         e = etiquette.exceptions.WrongLogin() |         e = etiquette.exceptions.WrongLogin() | ||||||
|         response = etiquette.jsonify.exception(e) |         response = etiquette.jsonify.exception(e) | ||||||
|         return etiquette_flask.jsonify.make_json_response(response, status=422) |         return jsonify.make_json_response(response, status=422) | ||||||
|     session = etiquette_flask.sessions.Session(request, user) |     session = sessions.Session(request, user) | ||||||
|     session_manager.add(session) |     session_manager.add(session) | ||||||
|     return etiquette_flask.jsonify.make_json_response({}) |     return jsonify.make_json_response({}) | ||||||
| 
 | 
 | ||||||
| @site.route('/register', methods=['POST']) | @site.route('/register', methods=['POST']) | ||||||
| @session_manager.give_token | @session_manager.give_token | ||||||
| @etiquette_flask.decorators.required_fields(['username', 'password_1', 'password_2']) | @decorators.required_fields(['username', 'password_1', 'password_2']) | ||||||
| def post_register(): | def post_register(): | ||||||
|     if session_manager.get(request): |     if session_manager.get(request): | ||||||
|         e = etiquette.exceptions.AlreadySignedIn() |         e = etiquette.exceptions.AlreadySignedIn() | ||||||
|         response = etiquette.jsonify.exception(e) |         response = etiquette.jsonify.exception(e) | ||||||
|         return etiquette_flask.jsonify.make_json_response(response, status=403) |         return jsonify.make_json_response(response, status=403) | ||||||
| 
 | 
 | ||||||
|     username = request.form['username'] |     username = request.form['username'] | ||||||
|     password_1 = request.form['password_1'] |     password_1 = request.form['password_1'] | ||||||
|  | @ -255,17 +258,17 @@ def post_register(): | ||||||
|             'error_type': 'PASSWORDS_DONT_MATCH', |             'error_type': 'PASSWORDS_DONT_MATCH', | ||||||
|             'error_message': 'Passwords do not match.', |             'error_message': 'Passwords do not match.', | ||||||
|         } |         } | ||||||
|         return etiquette_flask.jsonify.make_json_response(response, status=422) |         return jsonify.make_json_response(response, status=422) | ||||||
| 
 | 
 | ||||||
|     try: |     try: | ||||||
|         user = P.register_user(username, password_1) |         user = P.register_user(username, password_1) | ||||||
|     except etiquette.exceptions.EtiquetteException as e: |     except etiquette.exceptions.EtiquetteException as e: | ||||||
|         response = etiquette.jsonify.exception(e) |         response = etiquette.jsonify.exception(e) | ||||||
|         return etiquette_flask.jsonify.make_json_response(response, status=400) |         return jsonify.make_json_response(response, status=400) | ||||||
| 
 | 
 | ||||||
|     session = etiquette_flask.sessions.Session(request, user) |     session = sessions.Session(request, user) | ||||||
|     session_manager.add(session) |     session_manager.add(session) | ||||||
|     return etiquette_flask.jsonify.make_json_response({}) |     return jsonify.make_json_response({}) | ||||||
| 
 | 
 | ||||||
| @site.route('/logout', methods=['GET', 'POST']) | @site.route('/logout', methods=['GET', 'POST']) | ||||||
| @session_manager.give_token | @session_manager.give_token | ||||||
|  | @ -306,7 +309,7 @@ def get_album_json(albumid): | ||||||
|     album['sub_albums'] = [P_album(x) for x in album['sub_albums']] |     album['sub_albums'] = [P_album(x) for x in album['sub_albums']] | ||||||
|     album['sub_albums'].sort(key=lambda x: (x.title or x.id).lower()) |     album['sub_albums'].sort(key=lambda x: (x.title or x.id).lower()) | ||||||
|     album['sub_albums'] = [etiquette.jsonify.album(x, minimal=True) for x in album['sub_albums']] |     album['sub_albums'] = [etiquette.jsonify.album(x, minimal=True) for x in album['sub_albums']] | ||||||
|     return etiquette_flask.jsonify.make_json_response(album) |     return jsonify.make_json_response(album) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| @site.route('/album/<albumid>.zip') | @site.route('/album/<albumid>.zip') | ||||||
|  | @ -370,7 +373,7 @@ def get_albums_html(): | ||||||
| def get_albums_json(): | def get_albums_json(): | ||||||
|     albums = get_albums_core() |     albums = get_albums_core() | ||||||
|     albums = [etiquette.jsonify.album(album, minimal=True) for album in albums] |     albums = [etiquette.jsonify.album(album, minimal=True) for album in albums] | ||||||
|     return etiquette_flask.jsonify.make_json_response(albums) |     return jsonify.make_json_response(albums) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| @site.route('/bookmarks') | @site.route('/bookmarks') | ||||||
|  | @ -419,7 +422,7 @@ def get_photo_html(photoid): | ||||||
| def get_photo_json(photoid): | def get_photo_json(photoid): | ||||||
|     photo = P_photo(photoid, response_type='json') |     photo = P_photo(photoid, response_type='json') | ||||||
|     photo = etiquette.jsonify.photo(photo) |     photo = etiquette.jsonify.photo(photo) | ||||||
|     photo = etiquette_flask.jsonify.make_json_response(photo) |     photo = jsonify.make_json_response(photo) | ||||||
|     return photo |     return photo | ||||||
| 
 | 
 | ||||||
| def get_search_core(): | def get_search_core(): | ||||||
|  | @ -584,7 +587,7 @@ def get_search_json(): | ||||||
|     search_results['photos'] = [ |     search_results['photos'] = [ | ||||||
|         etiquette.jsonify.photo(photo, include_albums=False) for photo in search_results['photos'] |         etiquette.jsonify.photo(photo, include_albums=False) for photo in search_results['photos'] | ||||||
|     ] |     ] | ||||||
|     return etiquette_flask.jsonify.make_json_response(search_results) |     return jsonify.make_json_response(search_results) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| def get_tags_core(specific_tag=None): | def get_tags_core(specific_tag=None): | ||||||
|  | @ -624,7 +627,7 @@ def get_tags_json(specific_tag=None): | ||||||
|     include_synonyms = request.args.get('synonyms') |     include_synonyms = request.args.get('synonyms') | ||||||
|     include_synonyms = include_synonyms is None or etiquette.helpers.truthystring(include_synonyms) |     include_synonyms = include_synonyms is None or etiquette.helpers.truthystring(include_synonyms) | ||||||
|     tags = [etiquette.jsonify.tag(tag, include_synonyms=include_synonyms) for tag in tags] |     tags = [etiquette.jsonify.tag(tag, include_synonyms=include_synonyms) for tag in tags] | ||||||
|     return etiquette_flask.jsonify.make_json_response(tags) |     return jsonify.make_json_response(tags) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| @site.route('/thumbnail/<photoid>') | @site.route('/thumbnail/<photoid>') | ||||||
|  | @ -654,7 +657,7 @@ def get_user_html(username): | ||||||
| def get_user_json(username): | def get_user_json(username): | ||||||
|     user = get_user_core(username) |     user = get_user_core(username) | ||||||
|     user = etiquette.jsonify.user(user) |     user = etiquette.jsonify.user(user) | ||||||
|     user = etiquette_flask.jsonify.make_json_response(user) |     user = jsonify.make_json_response(user) | ||||||
|     return user |     return user | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | @ -672,13 +675,13 @@ def post_album_add_tag(albumid): | ||||||
|         tag = P_tag(tag) |         tag = P_tag(tag) | ||||||
|     except etiquette.exceptions.NoSuchTag as e: |     except etiquette.exceptions.NoSuchTag as e: | ||||||
|         response = etiquette.jsonify.exception(e) |         response = etiquette.jsonify.exception(e) | ||||||
|         return etiquette_flask.jsonify.make_json_response(response, status=404) |         return jsonify.make_json_response(response, status=404) | ||||||
|     recursive = request.form.get('recursive', False) |     recursive = request.form.get('recursive', False) | ||||||
|     recursive = etiquette.helpers.truthystring(recursive) |     recursive = etiquette.helpers.truthystring(recursive) | ||||||
|     album.add_tag_to_all(tag, nested_children=recursive) |     album.add_tag_to_all(tag, nested_children=recursive) | ||||||
|     response['action'] = 'add_tag' |     response['action'] = 'add_tag' | ||||||
|     response['tagname'] = tag.name |     response['tagname'] = tag.name | ||||||
|     return etiquette_flask.jsonify.make_json_response(response) |     return jsonify.make_json_response(response) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| @site.route('/album/<albumid>/edit', methods=['POST']) | @site.route('/album/<albumid>/edit', methods=['POST']) | ||||||
|  | @ -693,7 +696,7 @@ def post_album_edit(albumid): | ||||||
|     description = request.form.get('description', None) |     description = request.form.get('description', None) | ||||||
|     album.edit(title=title, description=description) |     album.edit(title=title, description=description) | ||||||
|     response = {'title': album.title, 'description': album.description} |     response = {'title': album.title, 'description': album.description} | ||||||
|     return etiquette_flask.jsonify.make_json_response(response) |     return jsonify.make_json_response(response) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| def post_photo_add_remove_tag_core(photoid, tagname, add_or_remove): | def post_photo_add_remove_tag_core(photoid, tagname, add_or_remove): | ||||||
|  | @ -707,14 +710,14 @@ def post_photo_add_remove_tag_core(photoid, tagname, add_or_remove): | ||||||
|             photo.remove_tag(tag) |             photo.remove_tag(tag) | ||||||
|     except etiquette.exceptions.EtiquetteException as e: |     except etiquette.exceptions.EtiquetteException as e: | ||||||
|         response = etiquette.jsonify.exception(e) |         response = etiquette.jsonify.exception(e) | ||||||
|         response = etiquette_flask.jsonify.make_json_response(response, status=400) |         response = jsonify.make_json_response(response, status=400) | ||||||
|         flask.abort(response) |         flask.abort(response) | ||||||
| 
 | 
 | ||||||
|     response = {'tagname': tag.name} |     response = {'tagname': tag.name} | ||||||
|     return etiquette_flask.jsonify.make_json_response(response) |     return jsonify.make_json_response(response) | ||||||
| 
 | 
 | ||||||
| @site.route('/photo/<photoid>/add_tag', methods=['POST']) | @site.route('/photo/<photoid>/add_tag', methods=['POST']) | ||||||
| @etiquette_flask.decorators.required_fields(['tagname'], forbid_whitespace=True) | @decorators.required_fields(['tagname'], forbid_whitespace=True) | ||||||
| def post_photo_add_tag(photoid): | def post_photo_add_tag(photoid): | ||||||
|     ''' |     ''' | ||||||
|     Add a tag to this photo. |     Add a tag to this photo. | ||||||
|  | @ -722,7 +725,7 @@ def post_photo_add_tag(photoid): | ||||||
|     return post_photo_add_remove_tag_core(photoid, request.form['tagname'], 'add') |     return post_photo_add_remove_tag_core(photoid, request.form['tagname'], 'add') | ||||||
| 
 | 
 | ||||||
| @site.route('/photo/<photoid>/remove_tag', methods=['POST']) | @site.route('/photo/<photoid>/remove_tag', methods=['POST']) | ||||||
| @etiquette_flask.decorators.required_fields(['tagname'], forbid_whitespace=True) | @decorators.required_fields(['tagname'], forbid_whitespace=True) | ||||||
| def post_photo_remove_tag(photoid): | def post_photo_remove_tag(photoid): | ||||||
|     ''' |     ''' | ||||||
|     Remove a tag from this photo. |     Remove a tag from this photo. | ||||||
|  | @ -740,9 +743,9 @@ def post_photo_refresh_metadata(photoid): | ||||||
|         photo.reload_metadata() |         photo.reload_metadata() | ||||||
|     except etiquette.exceptions.EtiquetteException as e: |     except etiquette.exceptions.EtiquetteException as e: | ||||||
|         response = etiquette.jsonify.exception(e) |         response = etiquette.jsonify.exception(e) | ||||||
|         response = etiquette_flask.jsonify.make_json_response(response, status=400) |         response = jsonify.make_json_response(response, status=400) | ||||||
|         flask.abort(response) |         flask.abort(response) | ||||||
|     return etiquette_flask.jsonify.make_json_response({}) |     return jsonify.make_json_response({}) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| def post_tag_create_delete_core(tagname, function): | def post_tag_create_delete_core(tagname, function): | ||||||
|  | @ -754,10 +757,10 @@ def post_tag_create_delete_core(tagname, function): | ||||||
|         status = 400 |         status = 400 | ||||||
|     #print(response) |     #print(response) | ||||||
| 
 | 
 | ||||||
|     return etiquette_flask.jsonify.make_json_response(response, status=status) |     return jsonify.make_json_response(response, status=status) | ||||||
| 
 | 
 | ||||||
| @site.route('/tags/create_tag', methods=['POST']) | @site.route('/tags/create_tag', methods=['POST']) | ||||||
| @etiquette_flask.decorators.required_fields(['tagname'], forbid_whitespace=True) | @decorators.required_fields(['tagname'], forbid_whitespace=True) | ||||||
| def post_tag_create(): | def post_tag_create(): | ||||||
|     ''' |     ''' | ||||||
|     Create a tag. |     Create a tag. | ||||||
|  | @ -765,7 +768,7 @@ def post_tag_create(): | ||||||
|     return post_tag_create_delete_core(request.form['tagname'], create_tag) |     return post_tag_create_delete_core(request.form['tagname'], create_tag) | ||||||
| 
 | 
 | ||||||
| @site.route('/tags/delete_tag', methods=['POST']) | @site.route('/tags/delete_tag', methods=['POST']) | ||||||
| @etiquette_flask.decorators.required_fields(['tagname'], forbid_whitespace=True) | @decorators.required_fields(['tagname'], forbid_whitespace=True) | ||||||
| def post_tag_delete(): | def post_tag_delete(): | ||||||
|     ''' |     ''' | ||||||
|     Delete a tag. |     Delete a tag. | ||||||
|  | @ -773,7 +776,7 @@ def post_tag_delete(): | ||||||
|     return post_tag_create_delete_core(request.form['tagname'], delete_tag) |     return post_tag_create_delete_core(request.form['tagname'], delete_tag) | ||||||
| 
 | 
 | ||||||
| @site.route('/tags/delete_synonym', methods=['POST']) | @site.route('/tags/delete_synonym', methods=['POST']) | ||||||
| @etiquette_flask.decorators.required_fields(['tagname'], forbid_whitespace=True) | @decorators.required_fields(['tagname'], forbid_whitespace=True) | ||||||
| def post_tag_delete_synonym(): | def post_tag_delete_synonym(): | ||||||
|     ''' |     ''' | ||||||
|     Delete a synonym. |     Delete a synonym. | ||||||
|  | @ -1,7 +1,7 @@ | ||||||
| import gevent.monkey | import gevent.monkey | ||||||
| gevent.monkey.patch_all() | gevent.monkey.patch_all() | ||||||
| 
 | 
 | ||||||
| import etiquette_site | import etiquette_flask | ||||||
| import gevent.pywsgi | import gevent.pywsgi | ||||||
| import gevent.wsgi | import gevent.wsgi | ||||||
| import sys | import sys | ||||||
|  | @ -14,14 +14,14 @@ else: | ||||||
| if port == 443: | if port == 443: | ||||||
|     http = gevent.pywsgi.WSGIServer( |     http = gevent.pywsgi.WSGIServer( | ||||||
|         listener=('0.0.0.0', port), |         listener=('0.0.0.0', port), | ||||||
|         application=etiquette_site.site, |         application=etiquette_flask.site, | ||||||
|         keyfile='C:\\git\\etiquette\\etiquette\\https\\etiquette.key', |         keyfile='C:\\git\\etiquette\\etiquette\\https\\etiquette.key', | ||||||
|         certfile='C:\\git\\etiquette\\etiquette\\https\\etiquette.crt', |         certfile='C:\\git\\etiquette\\etiquette\\https\\etiquette.crt', | ||||||
|     ) |     ) | ||||||
| else: | else: | ||||||
|     http = gevent.pywsgi.WSGIServer( |     http = gevent.pywsgi.WSGIServer( | ||||||
|         listener=('0.0.0.0', port), |         listener=('0.0.0.0', port), | ||||||
|         application=etiquette_site.site, |         application=etiquette_flask.site, | ||||||
|     ) |     ) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| Before Width: | Height: | Size: 49 KiB After Width: | Height: | Size: 49 KiB | 
| Before Width: | Height: | Size: 8.9 KiB After Width: | Height: | Size: 8.9 KiB | 
| Before Width: | Height: | Size: 63 KiB After Width: | Height: | Size: 63 KiB | 
| Before Width: | Height: | Size: 9.4 KiB After Width: | Height: | Size: 9.4 KiB | 
| Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 19 KiB | 
| Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.8 KiB | 
| Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 22 KiB | 
| Before Width: | Height: | Size: 29 KiB After Width: | Height: | Size: 29 KiB | 
| Before Width: | Height: | Size: 5.3 KiB After Width: | Height: | Size: 5.3 KiB | 
| Before Width: | Height: | Size: 21 KiB After Width: | Height: | Size: 21 KiB | 
| Before Width: | Height: | Size: 21 KiB After Width: | Height: | Size: 21 KiB | 
| Before Width: | Height: | Size: 2 KiB After Width: | Height: | Size: 2 KiB | 
| Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB | 
| Before Width: | Height: | Size: 7 KiB After Width: | Height: | Size: 7 KiB |