diff --git a/etiquette/__init__.py b/etiquette/__init__.py index a06b92d..503d295 100644 --- a/etiquette/__init__.py +++ b/etiquette/__init__.py @@ -2,7 +2,6 @@ from . import constants from . import decorators from . import exceptions from . import helpers -from . import jsonify from . import objects from . import photodb from . import searchhelpers diff --git a/etiquette/exceptions.py b/etiquette/exceptions.py index 028592a..bcd74ec 100644 --- a/etiquette/exceptions.py +++ b/etiquette/exceptions.py @@ -35,6 +35,14 @@ class EtiquetteException(Exception, metaclass=ErrorTypeAdder): def __str__(self): return self.error_type + '\n' + self.error_message + def jsonify(self): + j = { + 'type': 'error', + 'error_type': self.error_type, + 'error_message': self.error_message, + } + return j + # NO SUCH ########################################################################################## class NoSuch(EtiquetteException): diff --git a/etiquette/jsonify.py b/etiquette/jsonify.py deleted file mode 100644 index 094bb24..0000000 --- a/etiquette/jsonify.py +++ /dev/null @@ -1,95 +0,0 @@ -''' -This file provides functions that convert the Etiquette objects into -dictionaries suitable for JSON serializing. -''' - -def album(a, minimal=False): - j = { - 'type': 'album', - 'id': a.id, - 'description': a.description, - 'title': a.title, - 'author': user_or_none(a.get_author()), - } - if not minimal: - j['photos'] = [photo(p) for p in a.get_photos()] - j['parents'] = [album(p, minimal=True) for p in a.get_parents()] - j['sub_albums'] = [album(c, minimal=True) for c in a.get_children()] - - return j - -def bookmark(b): - j = { - 'type': 'bookmark', - 'id': b.id, - 'author': user_or_none(b.get_author()), - 'url': b.url, - 'title': b.title, - } - return j - -def exception(e): - j = { - 'type': 'error', - 'error_type': e.error_type, - 'error_message': e.error_message, - } - return j - -def photo(p, include_albums=True, include_tags=True): - j = { - 'type': 'photo', - 'id': p.id, - 'author': user_or_none(p.get_author()), - 'extension': p.extension, - 'width': p.width, - 'height': p.height, - 'ratio': p.ratio, - 'area': p.area, - 'bytes': p.bytes, - 'duration_str': p.duration_string, - 'duration': p.duration, - 'bytes_str': p.bytestring, - 'has_thumbnail': bool(p.thumbnail), - 'created': p.created, - 'filename': p.basename, - 'mimetype': p.mimetype, - 'searchhidden': bool(p.searchhidden), - } - if include_albums: - j['albums'] = [album(a, minimal=True) for a in p.get_containing_albums()] - - if include_tags: - j['tags'] = [tag(t, minimal=True) for t in p.get_tags()] - - return j - -def tag(t, include_synonyms=False, minimal=False): - j = { - 'type': 'tag', - 'id': t.id, - 'name': t.name, - } - if not minimal: - j['author'] = user_or_none(t.get_author()) - j['description'] = t.description - j['children'] = [tag(c, minimal=True) for c in t.get_children()] - - if include_synonyms: - j['synonyms'] = list(t.get_synonyms()) - return j - -def user(u): - j = { - 'type': 'user', - 'id': u.id, - 'username': u.username, - 'created': u.created, - 'display_name': u.display_name, - } - return j - -def user_or_none(u): - if u is None: - return None - return user(u) diff --git a/etiquette/objects.py b/etiquette/objects.py index de51c07..6360932 100644 --- a/etiquette/objects.py +++ b/etiquette/objects.py @@ -514,6 +514,21 @@ class Album(ObjectBase, GroupableMixin): ) return row is not None + def jsonify(self, minimal=False): + j = { + 'type': 'album', + 'id': self.id, + 'description': self.description, + 'title': self.title, + 'author': self.get_author().jsonify() if self.author_id else None, + } + if not minimal: + j['photos'] = [photo.jsonify(include_albums=False) for photo in self.get_photos()] + j['parents'] = [parent.jsonify(minimal=True) for parent in self.get_parents()] + j['sub_albums'] = [child.jsonify(minimal=True) for child in self.get_children()] + + return j + @decorators.required_feature('album.edit') @decorators.transaction def remove_child(self, *args, **kwargs): @@ -674,6 +689,16 @@ class Bookmark(ObjectBase): self.title = title self.url = url + def jsonify(self): + j = { + 'type': 'bookmark', + 'id': self.id, + 'author': self.get_author().jsonify() if self.author_id else None, + 'url': self.url, + 'title': self.title, + } + return j + class Photo(ObjectBase): ''' A PhotoDB entry containing information about an image file. @@ -959,6 +984,34 @@ class Photo(ObjectBase): return tag_by_id[rel_row[0]] + def jsonify(self, include_albums=True, include_tags=True): + j = { + 'type': 'photo', + 'id': self.id, + 'author': self.get_author().jsonify() if self.author_id else None, + 'extension': self.extension, + 'width': self.width, + 'height': self.height, + 'ratio': self.ratio, + 'area': self.area, + 'bytes': self.bytes, + 'duration_str': self.duration_string, + 'duration': self.duration, + 'bytes_str': self.bytestring, + 'has_thumbnail': bool(self.thumbnail), + 'created': self.created, + 'filename': self.basename, + 'mimetype': self.mimetype, + 'searchhidden': bool(self.searchhidden), + } + if include_albums: + j['albums'] = [album.jsonify(minimal=True) for album in self.get_containing_albums()] + + if include_tags: + j['tags'] = [tag.jsonify(minimal=True) for tag in self.get_tags()] + + return j + def make_thumbnail_filepath(self): ''' Create the filepath that should be the location of our thumbnail. @@ -1468,6 +1521,22 @@ class Tag(ObjectBase, GroupableMixin): synonyms = set(name for (name,) in syn_rows) return synonyms + def jsonify(self, include_synonyms=False, minimal=False): + j = { + 'type': 'tag', + 'id': self.id, + 'name': self.name, + } + if not minimal: + j['author'] = self.get_author().jsonify() if self.author_id else None, + j['description'] = self.description + j['children'] = [child.jsonify(minimal=True) for child in self.get_children()] + + if include_synonyms: + j['synonyms'] = list(self.get_synonyms()) + + return j + @decorators.required_feature('tag.edit') @decorators.transaction def remove_child(self, *args, **kwargs): @@ -1592,6 +1661,16 @@ class User(ObjectBase): else: return self._display_name + def jsonify(self): + j = { + 'type': 'user', + 'id': self.id, + 'username': self.username, + 'created': self.created, + 'display_name': self.display_name, + } + return j + @decorators.required_feature('user.edit') @decorators.transaction def set_display_name(self, display_name): diff --git a/frontends/etiquette_flask/backend/common.py b/frontends/etiquette_flask/backend/common.py index c354aae..0cac7fb 100644 --- a/frontends/etiquette_flask/backend/common.py +++ b/frontends/etiquette_flask/backend/common.py @@ -132,7 +132,7 @@ def P_wrapper(function): if response_type == 'html': flask.abort(status, exc.error_message) else: - response = etiquette.jsonify.exception(exc) + response = exc.jsonify() response = jsonify.make_json_response(response, status=status) flask.abort(response) diff --git a/frontends/etiquette_flask/backend/decorators.py b/frontends/etiquette_flask/backend/decorators.py index 41be014..43fab22 100644 --- a/frontends/etiquette_flask/backend/decorators.py +++ b/frontends/etiquette_flask/backend/decorators.py @@ -20,7 +20,7 @@ def catch_etiquette_exception(function): status = 404 else: status = 400 - response = etiquette.jsonify.exception(exc) + response = exc.jsonify() response = jsonify.make_json_response(response, status=status) flask.abort(response) return wrapped diff --git a/frontends/etiquette_flask/backend/endpoints/album_endpoints.py b/frontends/etiquette_flask/backend/endpoints/album_endpoints.py index 9520a12..74e0559 100644 --- a/frontends/etiquette_flask/backend/endpoints/album_endpoints.py +++ b/frontends/etiquette_flask/backend/endpoints/album_endpoints.py @@ -30,7 +30,7 @@ def get_album_html(album_id): @site.route('/album/.json') def get_album_json(album_id): album = common.P_album(album_id, response_type='json') - album = etiquette.jsonify.album(album) + album = album.jsonify() return jsonify.make_json_response(album) @site.route('/album/.zip') @@ -65,7 +65,7 @@ def post_album_add_child(album_id): children = list(common.P_albums(child_ids, response_type='json')) print(children) album.add_children(children, commit=True) - response = etiquette.jsonify.album(album) + response = album.jsonify() return jsonify.make_json_response(response) @site.route('/album//remove_child', methods=['POST']) @@ -76,7 +76,7 @@ def post_album_remove_child(album_id): child_ids = stringtools.comma_space_split(request.form['child_id']) children = list(common.P_albums(child_ids, response_type='json')) album.remove_children(children, commit=True) - response = etiquette.jsonify.album(album) + response = album.jsonify() return jsonify.make_json_response(response) @site.route('/album//refresh_directories', methods=['POST']) @@ -101,7 +101,7 @@ def post_album_add_photo(album_id): photo_ids = stringtools.comma_space_split(request.form['photo_id']) photos = list(common.P_photos(photo_ids, response_type='json')) album.add_photos(photos, commit=True) - response = etiquette.jsonify.album(album) + response = album.jsonify() return jsonify.make_json_response(response) @site.route('/album//remove_photo', methods=['POST']) @@ -115,7 +115,7 @@ def post_album_remove_photo(album_id): photo_ids = stringtools.comma_space_split(request.form['photo_id']) photos = list(common.P_photos(photo_ids, response_type='json')) album.remove_photos(photos, commit=True) - response = etiquette.jsonify.album(album) + response = album.jsonify() return jsonify.make_json_response(response) # Album tag operations ############################################################################# @@ -132,7 +132,7 @@ def post_album_add_tag(album_id): try: tag = common.P_tag(tag, response_type='json') except etiquette.exceptions.NoSuchTag as exc: - response = etiquette.jsonify.exception(exc) + response = exc.jsonify() return jsonify.make_json_response(response, status=404) recursive = request.form.get('recursive', False) recursive = etiquette.helpers.truthystring(recursive) @@ -153,7 +153,7 @@ def post_album_edit(album_id): title = request.form.get('title', None) description = request.form.get('description', None) album.edit(title=title, description=description, commit=True) - response = etiquette.jsonify.album(album, minimal=True) + response = album.jsonify(minimal=True) return jsonify.make_json_response(response) # Album listings ################################################################################### @@ -184,7 +184,7 @@ def get_albums_html(): @site.route('/albums.json') def get_albums_json(): albums = get_albums_core() - albums = [etiquette.jsonify.album(album, minimal=True) for album in albums] + albums = [album.jsonify(minimal=True) for album in albums] return jsonify.make_json_response(albums) # Album create and delete ########################################################################## @@ -204,7 +204,7 @@ def post_albums_create(): parent.add_child(album) common.P.commit('create album endpoint') - response = etiquette.jsonify.album(album, minimal=False) + response = album.jsonify(minimal=False) return jsonify.make_json_response(response) @site.route('/album//delete', methods=['POST']) diff --git a/frontends/etiquette_flask/backend/endpoints/bookmark_endpoints.py b/frontends/etiquette_flask/backend/endpoints/bookmark_endpoints.py index f6d6b82..73a6cc6 100644 --- a/frontends/etiquette_flask/backend/endpoints/bookmark_endpoints.py +++ b/frontends/etiquette_flask/backend/endpoints/bookmark_endpoints.py @@ -14,7 +14,7 @@ session_manager = common.session_manager @site.route('/bookmark/.json') def get_bookmark_json(bookmark_id): bookmark = common.P_bookmark(bookmark_id, response_type='json') - response = etiquette.jsonify.bookmark(bookmark) + response = bookmark.jsonify() return jsonify.make_json_response(response) @site.route('/bookmark//edit', methods=['POST']) @@ -25,7 +25,7 @@ def post_bookmark_edit(bookmark_id): url = request.form.get('url', None) or None bookmark.edit(title=title, url=url, commit=True) - response = etiquette.jsonify.bookmark(bookmark) + response = bookmark.jsonify() response = jsonify.make_json_response(response) return response @@ -38,7 +38,7 @@ def get_bookmarks_html(): @site.route('/bookmarks.json') def get_bookmarks_json(): - bookmarks = [etiquette.jsonify.bookmark(b) for b in common.P.get_bookmarks()] + bookmarks = [b.jsonify() for b in common.P.get_bookmarks()] return jsonify.make_json_response(bookmarks) # Bookmark create and delete ####################################################################### @@ -50,7 +50,7 @@ def post_bookmark_create(): title = request.form.get('title', None) user = session_manager.get(request).user bookmark = common.P.new_bookmark(url=url, title=title, author=user, commit=True) - response = etiquette.jsonify.bookmark(bookmark) + response = bookmark.jsonify() response = jsonify.make_json_response(response) return response diff --git a/frontends/etiquette_flask/backend/endpoints/photo_endpoints.py b/frontends/etiquette_flask/backend/endpoints/photo_endpoints.py index b2cfde6..dcec347 100644 --- a/frontends/etiquette_flask/backend/endpoints/photo_endpoints.py +++ b/frontends/etiquette_flask/backend/endpoints/photo_endpoints.py @@ -26,7 +26,7 @@ def get_photo_html(photo_id): @site.route('/photo/.json') def get_photo_json(photo_id): photo = common.P_photo(photo_id, response_type='json') - photo = etiquette.jsonify.photo(photo) + photo = photo.jsonify() photo = jsonify.make_json_response(photo) return photo @@ -488,12 +488,12 @@ def get_search_json(): search_kwargs['tag_forbids'] = tagname_helper(search_kwargs['tag_forbids']) search_results['results'] = [ - etiquette.jsonify.photo(result, include_albums=False) + result.jsonify(include_albums=False) if isinstance(result, etiquette.objects.Photo) else - etiquette.jsonify.album(result, minimal=True) + result.jsonify(minimal=True) for result in search_results['results'] ] search_results['total_tags'] = [ - etiquette.jsonify.tag(tag, minimal=True) for tag in search_results['total_tags'] + tag.jsonify(minimal=True) for tag in search_results['total_tags'] ] return jsonify.make_json_response(search_results) diff --git a/frontends/etiquette_flask/backend/endpoints/tag_endpoints.py b/frontends/etiquette_flask/backend/endpoints/tag_endpoints.py index 477cb0a..577fdc3 100644 --- a/frontends/etiquette_flask/backend/endpoints/tag_endpoints.py +++ b/frontends/etiquette_flask/backend/endpoints/tag_endpoints.py @@ -40,7 +40,7 @@ def post_tag_edit(tagname): description = request.form.get('description', None) tag.edit(description=description, commit=True) - response = etiquette.jsonify.tag(tag) + response = tag.jsonify() response = jsonify.make_json_response(response) return response @@ -129,7 +129,7 @@ def get_tags_json(specific_tag_name=None): else: tags = list(specific_tag.walk_children()) - tags = [etiquette.jsonify.tag(tag, include_synonyms=include_synonyms) for tag in tags] + tags = [tag.jsonify(include_synonyms=include_synonyms) for tag in tags] return jsonify.make_json_response(tags) # Tag create and delete ############################################################################ @@ -141,7 +141,7 @@ def post_tag_create(): description = request.form.get('description', None) tag = common.P.new_tag(name, description, author=session_manager.get(request).user, commit=True) - response = etiquette.jsonify.tag(tag) + response = tag.jsonify() return jsonify.make_json_response(response) @site.route('/tags/easybake', methods=['POST']) diff --git a/frontends/etiquette_flask/backend/endpoints/user_endpoints.py b/frontends/etiquette_flask/backend/endpoints/user_endpoints.py index d8a8c3d..cdec035 100644 --- a/frontends/etiquette_flask/backend/endpoints/user_endpoints.py +++ b/frontends/etiquette_flask/backend/endpoints/user_endpoints.py @@ -20,7 +20,7 @@ def get_user_html(username): @site.route('/user/.json') def get_user_json(username): user = common.P_user(username, response_type='json') - user = etiquette.jsonify.user(user) + user = user.jsonify() return jsonify.make_json_response(user) @site.route('/userid/') @@ -53,7 +53,7 @@ def post_login(): session = session_manager.get(request) if session.user: exc = etiquette.exceptions.AlreadySignedIn() - response = etiquette.jsonify.exception(exc) + response = exc.jsonify() return jsonify.make_json_response(response, status=403) username = request.form['username'] @@ -66,10 +66,10 @@ def post_login(): user = common.P.login(username=username, password=password) except (etiquette.exceptions.NoSuchUser, etiquette.exceptions.WrongLogin): exc = etiquette.exceptions.WrongLogin() - response = etiquette.jsonify.exception(exc) + response = exc.jsonify() return jsonify.make_json_response(response, status=422) except etiquette.exceptions.FeatureDisabled as exc: - response = etiquette.jsonify.exception(exc) + response = exc.jsonify() return jsonify.make_json_response(response, status=400) session = sessions.Session(request, user) session_manager.add(session) @@ -93,7 +93,7 @@ def post_register(): session = session_manager.get(request) if session.user: exc = etiquette.exceptions.AlreadySignedIn() - response = etiquette.jsonify.exception(exc) + response = exc.jsonify() return jsonify.make_json_response(response, status=403) username = request.form['username']