diff --git a/etiquette/exceptions.py b/etiquette/exceptions.py index d150cad..46cc303 100644 --- a/etiquette/exceptions.py +++ b/etiquette/exceptions.py @@ -6,59 +6,74 @@ def pascal_to_loudsnakes(text): text = text.upper() return text +def with_error_type(cls): + cls.error_type = pascal_to_loudsnakes(cls.__name__) + return cls + class EtiquetteException(Exception): error_message = '' - def __init__(self, *args): - self.error_type = pascal_to_loudsnakes(type(self).__name__) - Exception.__init__(self, *args) class WithFormat(EtiquetteException): def __init__(self, *args, **kwargs): + self.given_args = args + self.given_kwargs = kwargs self.error_message = self.error_message.format(*args, **kwargs) EtiquetteException.__init__(self, self.error_message) # NO SUCH +@with_error_type class NoSuch(WithFormat): pass +@with_error_type class NoSuchAlbum(NoSuch): error_message = 'Album "{}" does not exist.' +@with_error_type class NoSuchBookmark(NoSuch): error_message = 'Bookmark "{}" does not exist.' +@with_error_type class NoSuchGroup(NoSuch): error_message = 'Group "{}" does not exist.' +@with_error_type class NoSuchPhoto(NoSuch): error_message = 'Photo "{}" does not exist.' +@with_error_type class NoSuchSynonym(NoSuch): error_message = 'Synonym "{}" does not exist.' +@with_error_type class NoSuchTag(NoSuch): error_message = 'Tag "{}" does not exist.' +@with_error_type class NoSuchUser(NoSuch): error_message = 'User "{}" does not exist.' # EXISTS +@with_error_type class GroupExists(WithFormat): error_message = '{member} already in group {group}' +@with_error_type class PhotoExists(WithFormat): error_message = 'Photo "{}" already exists.' def __init__(self, photo): self.photo = photo WithFormat.__init__(self, photo.id) +@with_error_type class TagExists(WithFormat): error_message = 'Tag "{}" already exists.' def __init__(self, tag): self.tag = tag WithFormat.__init__(self, tag.name) +@with_error_type class UserExists(WithFormat): error_message = 'User "{}" already exists.' def __init__(self, user): @@ -67,43 +82,61 @@ class UserExists(WithFormat): # TAG ERRORS +@with_error_type class CantSynonymSelf(EtiquetteException): error_message = 'Cannot apply synonym to self.' +@with_error_type +class EasyBakeError(EtiquetteException): + error_message = '' + def __init__(self, message): + self.error_message = message + EtiquetteException.__init__(self) + +@with_error_type class RecursiveGrouping(EtiquetteException): error_message = '{group} is an ancestor of {member}.' +@with_error_type class TagTooLong(WithFormat): error_message = 'Tag "{}" is too long.' +@with_error_type class TagTooShort(WithFormat): error_message = 'Tag "{}" has too few valid characters.' # USER ERRORS +@with_error_type class InvalidUsernameChars(WithFormat): error_message = 'Username "{username}" contains invalid characters: {badchars}.' +@with_error_type class PasswordTooShort(WithFormat): error_message = 'Password is shorter than the minimum of {min_length}.' +@with_error_type class UsernameTooLong(WithFormat): error_message = 'Username "{username}" is longer than maximum of {max_length}.' +@with_error_type class UsernameTooShort(WithFormat): error_message = 'Username "{username}" is shorter than minimum of {min_length}.' +@with_error_type class WrongLogin(EtiquetteException): error_message = 'Wrong username-password combination.' # GENERAL ERRORS +@with_error_type class NotExclusive(EtiquetteException): ''' For when two or more mutually exclusive actions have been requested. ''' pass +@with_error_type class OutOfOrder(WithFormat): ''' For when a requested minmax range (a, b) has b > a diff --git a/etiquette/objects.py b/etiquette/objects.py index 4689e43..3904782 100644 --- a/etiquette/objects.py +++ b/etiquette/objects.py @@ -813,11 +813,11 @@ class Tag(ObjectBase, GroupableMixin): raise exceptions.CantSynonymSelf() try: - self.photodb.get_tag_by_name(synname) + existing_tag = self.photodb.get_tag_by_name(synname) except exceptions.NoSuchTag: pass else: - raise exceptions.TagExists(synname) + raise exceptions.TagExists(existing_tag) self.photodb._cached_frozen_children = None cur = self.photodb.sql.cursor() @@ -926,11 +926,11 @@ class Tag(ObjectBase, GroupableMixin): return try: - self.photodb.get_tag(new_name) + existing_tag = self.photodb.get_tag(new_name) except exceptions.NoSuchTag: pass else: - raise exceptions.TagExists(new_name) + raise exceptions.TagExists(existing_tag) self._cached_qualified_name = None self.photodb._cached_frozen_children = None diff --git a/etiquette/photodb.py b/etiquette/photodb.py index 3566868..ae8ae00 100644 --- a/etiquette/photodb.py +++ b/etiquette/photodb.py @@ -912,11 +912,11 @@ class PDBTagMixin: ''' tagname = self.normalize_tagname(tagname) try: - self.get_tag_by_name(tagname) + existing_tag = self.get_tag_by_name(tagname) except exceptions.NoSuchTag: pass else: - raise exceptions.TagExists(tagname) + raise exceptions.TagExists(existing_tag) tagid = self.generate_id('tags') self._cached_frozen_children = None @@ -1051,10 +1051,12 @@ class PDBUserMixin: if len(password) < self.config['min_password_length']: raise exceptions.PasswordTooShort(min_length=self.config['min_password_length']) - cur = self.sql.cursor() - cur.execute('SELECT * FROM users WHERE username == ?', [username]) - if cur.fetchone() is not None: - raise exceptions.UserExists(username) + try: + existing_user = self.get_user(username=username) + except exceptions.NoSuchUser: + pass + else: + raise exceptions.UserExists(existing_user) user_id = self.generate_user_id() hashed_password = bcrypt.hashpw(password, bcrypt.gensalt()) @@ -1291,10 +1293,10 @@ class PhotoDB(PDBAlbumMixin, PDBBookmarkMixin, PDBPhotoMixin, PDBTagMixin, PDBUs ebstring = ebstring.strip() ebstring = ebstring.strip('.+=') if ebstring == '': - return output_notes + raise exceptions.EasyBakeError('No tag supplied') if '=' in ebstring and '+' in ebstring: - raise ValueError('Cannot rename and assign snynonym at once') + raise exceptions.EasyBakeError('Cannot rename and assign snynonym at once') rename_parts = ebstring.split('=') if len(rename_parts) == 2: @@ -1303,7 +1305,7 @@ class PhotoDB(PDBAlbumMixin, PDBBookmarkMixin, PDBPhotoMixin, PDBTagMixin, PDBUs ebstring = rename_parts[0] rename_to = None else: - raise ValueError('Too many equals signs') + raise exceptions.EasyBakeError('Too many equals signs') create_parts = ebstring.split('+') if len(create_parts) == 2: @@ -1312,10 +1314,10 @@ class PhotoDB(PDBAlbumMixin, PDBBookmarkMixin, PDBPhotoMixin, PDBTagMixin, PDBUs tag = create_parts[0] synonym = None else: - raise ValueError('Too many plus signs') + raise exceptions.EasyBakeError('Too many plus signs') if not tag: - return output_notes + raise exceptions.EasyBakeError('No tag supplied') if rename_to: tag = self.get_tag(tag) @@ -1335,13 +1337,10 @@ class PhotoDB(PDBAlbumMixin, PDBBookmarkMixin, PDBPhotoMixin, PDBTagMixin, PDBUs tag = tags[-1] if synonym: - try: - tag.add_synonym(synonym) - note = ('new_synonym', '%s+%s' % (tag.name, synonym)) - output_notes.append(note) - print('New syn %s' % synonym) - except exceptions.TagExists: - pass + tag.add_synonym(synonym) + note = ('new_synonym', '%s+%s' % (tag.name, synonym)) + output_notes.append(note) + print('New syn %s' % synonym) return output_notes def generate_id(self, table): diff --git a/etiquette_site.py b/etiquette_site.py index 8882e8e..b2226cb 100644 --- a/etiquette_site.py +++ b/etiquette_site.py @@ -65,7 +65,10 @@ def delete_synonym(synonym): synonym = synonym.split('+')[-1].split('.')[-1] synonym = P.normalize_tagname(synonym) - master_tag = P.get_tag(synonym) + try: + master_tag = P.get_tag(synonym) + except exceptions.NoSuchTag as e: + raise exceptions.NoSuchSynonym(*e.given_args, **e.given_kwargs) master_tag.remove_synonym(synonym) return {'action':'delete_synonym', 'synonym': synonym} @@ -694,6 +697,7 @@ def post_photo_refresh_metadata(photoid): photo.reload_metadata() return jsonify.make_json_response({}) + def post_tag_create_delete_core(tagname, function): try: response = function(tagname) @@ -704,6 +708,7 @@ def post_tag_create_delete_core(tagname, function): 'error_message': e.error_message, } status = 400 + print(response) return jsonify.make_json_response(response, status=status) diff --git a/templates/tags.html b/templates/tags.html index 0113edf..c68f4ca 100644 --- a/templates/tags.html +++ b/templates/tags.html @@ -67,13 +67,13 @@ body {% for tag in tags %} {% set qualname = tag.qualified_name() %}