diff --git a/README.md b/README.md index b78c80a..c20eca8 100644 --- a/README.md +++ b/README.md @@ -61,7 +61,6 @@ If you are interested in helping, please raise an issue before making any pull r - Currently, the Jinja templates are having a tangling influence on the backend objects, because Jinja cannot import my other modules like bytestring, but it can access the methods of the objects I pass into the template. As a result, the objects have excess helper methods. Consider making them into Jinja filters instead. Which is also kind of ugly but will move that pollution out of the backend at least. - Perhaps instead of actually deleting objects, they should just have a `deleted` flag, to make easy restoration possible. Also consider regrouping the children of restored Groupables if those children haven't already been reassigned somewhere else. - Add a new table to store permanent history of add/remove of tags on photos, so that accidents or trolling can be reversed. -- Photo thumbnail paths should be relative to the data_dir, they are currently one level up. Or maybe should remove the paths entirely and just recalculate it by the ID. Can't think of any reason to have a thumbnail point elsewhere. - Fix album size cache when photo reload metadata and generally improve that validation. - Better bookmark url validation. - Create a textbox which gives autocomplete tag names. diff --git a/etiquette/constants.py b/etiquette/constants.py index 33a6669..80e7633 100644 --- a/etiquette/constants.py +++ b/etiquette/constants.py @@ -21,7 +21,7 @@ FILENAME_BADCHARS = '\\/:*?<>|"' # Note: Setting user_version pragma in init sequence is safe because it only # happens after the out-of-date check occurs, so no chance of accidentally # overwriting it. -DATABASE_VERSION = 9 +DATABASE_VERSION = 10 DB_INIT = ''' PRAGMA count_changes = OFF; PRAGMA cache_size = 10000; @@ -266,7 +266,9 @@ DEFAULT_CONFIGURATION = { 'thumbs.db', ], 'digest_exclude_dirs': [ + '_etiquette', '_site_thumbnails', + 'site_thumbnails', ], 'file_read_chunk': 2 ** 20, diff --git a/etiquette/objects.py b/etiquette/objects.py index fb6c6f1..2018160 100644 --- a/etiquette/objects.py +++ b/etiquette/objects.py @@ -570,7 +570,12 @@ class Photo(ObjectBase): self.width = db_row['width'] self.height = db_row['height'] self.ratio = db_row['ratio'] - self.thumbnail = db_row['thumbnail'] + + if db_row['thumbnail'] is not None: + self.thumbnail = self.photodb.thumbnail_directory.join(db_row['thumbnail']) + else: + self.thumbnail = None + self.searchhidden = db_row['searchhidden'] if self.duration and self.bytes is not None: @@ -697,8 +702,6 @@ class Photo(ObjectBase): For videos, you can provide a `timestamp` to take the thumbnail at. ''' hopeful_filepath = self.make_thumbnail_filepath() - hopeful_filepath = hopeful_filepath.relative_path - #print(hopeful_filepath) return_filepath = None if self.simple_mimetype == 'image': @@ -731,7 +734,7 @@ class Photo(ObjectBase): image = background image = image.convert('RGB') - image.save(hopeful_filepath, quality=50) + image.save(hopeful_filepath.absolute_path, quality=50) return_filepath = hopeful_filepath elif self.simple_mimetype == 'video' and constants.ffmpeg: @@ -757,7 +760,7 @@ class Photo(ObjectBase): timestamp = 2 constants.ffmpeg.thumbnail( self.real_path.absolute_path, - outfile=hopeful_filepath, + outfile=hopeful_filepath.absolute_path, quality=2, size=size, time=timestamp, @@ -770,7 +773,7 @@ class Photo(ObjectBase): if return_filepath != self.thumbnail: data = { 'id': self.id, - 'thumbnail': return_filepath, + 'thumbnail': return_filepath.relative_to(self.photodb.thumbnail_directory), } self.photodb.sql_update(table='photos', pairs=data, where_key='id') self.thumbnail = return_filepath diff --git a/frontends/etiquette_flask/etiquette_flask/common.py b/frontends/etiquette_flask/etiquette_flask/common.py index 9ffe8a3..7b98090 100644 --- a/frontends/etiquette_flask/etiquette_flask/common.py +++ b/frontends/etiquette_flask/etiquette_flask/common.py @@ -95,6 +95,9 @@ def send_file(filepath, override_mimetype=None): ''' Range-enabled file sending. ''' + if isinstance(filepath, pathclass.Path): + filepath = filepath.absolute_path + try: file_size = os.path.getsize(filepath) except FileNotFoundError: diff --git a/utilities/database_upgrader.py b/utilities/database_upgrader.py index e996818..c67525c 100644 --- a/utilities/database_upgrader.py +++ b/utilities/database_upgrader.py @@ -155,6 +155,25 @@ def upgrade_8_to_9(photodb): cur.execute('UPDATE photos SET searchhidden = 0') cur.execute('CREATE INDEX index_photos_searchhidden on photos(searchhidden)') +def upgrade_9_to_10(photodb): + ''' + From now on, the filepath stored in Photo's thumbnail column should be a + relative path where . is the PhotoDB's thumbnail_directory. + Previously, the stored path was unnecessarily high and contained the PDB's + data_directory, reducing portability. + ''' + cur = photodb.sql.cursor() + photos = list(photodb.search(has_thumbnail=True, is_searchhidden=None)) + + # Since we're doing it all at once, I'm going to cheat and skip the + # relative_to() calculation. + thumbnail_dir = photodb.thumbnail_directory.absolute_path + for photo in photos: + new_thumbnail_path = photo.make_thumbnail_filepath() + new_thumbnail_path = new_thumbnail_path.absolute_path + new_thumbnail_path = '.' + new_thumbnail_path.replace(thumbnail_dir, '') + cur.execute('UPDATE photos SET thumbnail = ? WHERE id == ?', [new_thumbnail_path, photo.id]) + def upgrade_all(data_directory): ''' Given the directory containing a phototagger database, apply all of the