diff --git a/etiquette.py b/etiquette.py index 5c7aa0f..5a12e82 100644 --- a/etiquette.py +++ b/etiquette.py @@ -182,10 +182,10 @@ def post_login(): username = request.form['username'] password = request.form['password'] - user = P.get_user(username=username) try: + user = P.get_user(username=username) user = P.login(user.id, password) - except exceptions.WrongLogin: + except (exceptions.NoSuchUser, exceptions.WrongLogin): flask.abort(422, 'Wrong login.') session = sessions.Session(request, user) session_manager.add(session) diff --git a/exceptions.py b/exceptions.py index d109629..8471d07 100644 --- a/exceptions.py +++ b/exceptions.py @@ -33,6 +33,9 @@ class UserExists(Exception): # TAG ERRORS +class CantSynonymSelf(Exception): + pass + class RecursiveGrouping(Exception): pass @@ -42,9 +45,6 @@ class TagTooLong(Exception): class TagTooShort(Exception): pass -class CantSynonymSelf(Exception): - pass - # USER ERRORS class InvalidUsernameChars(Exception): diff --git a/helpers.py b/helpers.py index 6a53624..99d114e 100644 --- a/helpers.py +++ b/helpers.py @@ -50,6 +50,25 @@ def album_zip_filenames(album, recursive=True): return arcnames +def binding_filler(column_names, values, require_all=True): + ''' + Manually aligning question marks and bindings is annoying. + Given the table's column names and a dictionary of {column: value}, + return the question marks and the list of bindings in the right order. + ''' + values = values.copy() + for column in column_names: + if column in values: + continue + if require_all: + raise ValueError('Missing column "%s"' % column) + else: + values.setdefault(column, None) + qmarks = '?' * len(column_names) + qmarks = ', '.join(qmarks) + bindings = [values[column] for column in column_names] + return (qmarks, bindings) + def chunk_sequence(sequence, chunk_length, allow_incomplete=True): ''' Given a sequence, divide it into sequences of length `chunk_length`. diff --git a/objects.py b/objects.py index 06ec54a..73c30a7 100644 --- a/objects.py +++ b/objects.py @@ -281,23 +281,24 @@ class Photo(ObjectBase): if isinstance(row_tuple, (list, tuple)): row_tuple = {constants.SQL_PHOTO_COLUMNS[index]: value for (index, value) in enumerate(row_tuple)} - self.id = row_tuple['id'] - self.real_filepath = row_tuple['filepath'] - self.real_filepath = helpers.normalize_filepath(self.real_filepath, allowed=':\\/') + self.real_filepath = helpers.normalize_filepath(row_tuple['filepath'], allowed=':\\/') self.real_path = pathclass.Path(self.real_filepath) - self.filepath = row_tuple['override_filename'] or self.real_filepath - self.basename = row_tuple['override_filename'] or os.path.basename(self.real_filepath) + + self.id = row_tuple['id'] + self.created = row_tuple['created'] + self.author_id = row_tuple['author_id'] + self.filepath = row_tuple['override_filename'] or self.real_path.absolute_path + self.basename = row_tuple['override_filename'] or self.real_path.basename self.extension = row_tuple['extension'] - self.width = row_tuple['width'] - self.height = row_tuple['height'] - self.ratio = row_tuple['ratio'] + self.tagged_at = row_tuple['tagged_at'] + self.area = row_tuple['area'] self.bytes = row_tuple['bytes'] self.duration = row_tuple['duration'] - self.created = row_tuple['created'] + self.width = row_tuple['width'] + self.height = row_tuple['height'] + self.ratio = row_tuple['ratio'] self.thumbnail = row_tuple['thumbnail'] - self.tagged_at = row_tuple['tagged_at'] - self.author_id = row_tuple['author_id'] def __reinit__(self): ''' diff --git a/phototagger.py b/phototagger.py index 881db73..90e8db4 100644 --- a/phototagger.py +++ b/phototagger.py @@ -124,25 +124,6 @@ def _helper_filenamefilter(subject, terms): basename = subject.lower() return all(term in basename for term in terms) -def binding_filler(column_names, values, require_all=True): - ''' - Manually aligning question marks and bindings is annoying. - Given the table's column names and a dictionary of {column: value}, - return the question marks and the list of bindings in the right order. - ''' - values = values.copy() - for column in column_names: - if column in values: - continue - if require_all: - raise ValueError('Missing column "%s"' % column) - else: - values.setdefault(column, None) - qmarks = '?' * len(column_names) - qmarks = ', '.join(qmarks) - bindings = [values[column] for column in column_names] - return (qmarks, bindings) - def operate(operand_stack, operator_stack): #print('before:', operand_stack, operator_stack) operator = operator_stack.pop() @@ -379,7 +360,7 @@ class PDBAlbumMixin: 'associated_directory': associated_directory, } - (qmarks, bindings) = binding_filler(constants.SQL_ALBUM_COLUMNS, data) + (qmarks, bindings) = helpers.binding_filler(constants.SQL_ALBUM_COLUMNS, data) query = 'INSERT INTO albums VALUES(%s)' % qmarks self.cur.execute(query, bindings) @@ -496,7 +477,7 @@ class PDBPhotoMixin: 'thumbnail': None, } - (qmarks, bindings) = binding_filler(constants.SQL_PHOTO_COLUMNS, data) + (qmarks, bindings) = helpers.binding_filler(constants.SQL_PHOTO_COLUMNS, data) query = 'INSERT INTO photos VALUES(%s)' % qmarks self.cur.execute(query, bindings) photo = objects.Photo(self, data) @@ -937,7 +918,7 @@ class PDBUserMixin: 'created': created, } - (qmarks, bindings) = binding_filler(constants.SQL_USER_COLUMNS, data) + (qmarks, bindings) = helpers.binding_filler(constants.SQL_USER_COLUMNS, data) query = 'INSERT INTO users VALUES(%s)' % qmarks self.cur.execute(query, bindings) diff --git a/templates/login.html b/templates/login.html index 36750ac..be8a169 100644 --- a/templates/login.html +++ b/templates/login.html @@ -53,7 +53,7 @@ button