Fix digest second-scan bug; Break down into smaller functions.
There was a bug where moving an album out of its determined parent caused future digests to fail because I wanted to use the GroupExists for control flow, but due to the @transaction decorator it was rolling back the changes. Moved some of the logical pieces of the function into subfunctions as a visual and readability aid.
This commit is contained in:
parent
d548e09a96
commit
6f371701e4
2 changed files with 47 additions and 44 deletions
|
@ -9,7 +9,7 @@ Etiquette is a tag-based file organization system with a web front-end.
|
||||||
|
|
||||||
Documentation is still a work in progress. In general,
|
Documentation is still a work in progress. In general,
|
||||||
|
|
||||||
- You must make the `etiquette` package importable by placing it in one of your lib paths. I use filesystem junctions for this purpose.
|
- You must make the `etiquette` package importable by placing it in one of your lib paths because I have not made a setup.py yet. Rather than actually moving the folder I just use filesystem junctions.
|
||||||
- Run `python etiquette_flask_launch.py [port]` to launch the flask server. Port defaults to 5000 if not provided.
|
- Run `python etiquette_flask_launch.py [port]` to launch the flask server. Port defaults to 5000 if not provided.
|
||||||
- Run `python -i etiquette_repl.py` to launch the Python interpreter with the PhotoDB pre-loaded into a variable called `P`. Try things like `P.new_photo` or `P.digest_directory`.
|
- Run `python -i etiquette_repl.py` to launch the Python interpreter with the PhotoDB pre-loaded into a variable called `P`. Try things like `P.new_photo` or `P.digest_directory`.
|
||||||
|
|
||||||
|
@ -81,6 +81,7 @@ If you are interested in helping, please raise an issue before making any pull r
|
||||||
- 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.
|
- 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.
|
- Add a new table to store permanent history of add/remove of tags on photos, so that accidents or trolling can be reversed.
|
||||||
- Currently, the photo clipboard only stores IDs and therefore when we construct the clipboard tray elements we cannot provide more rich information like filename, the user is only presented with a list of IDs which they probably don't care about. Should the localstorage cache some other more user-friendly information?
|
- Currently, the photo clipboard only stores IDs and therefore when we construct the clipboard tray elements we cannot provide more rich information like filename, the user is only presented with a list of IDs which they probably don't care about. Should the localstorage cache some other more user-friendly information?
|
||||||
|
- Improve transaction rollbacking. I'm not satisfied with the @transaction decorator because sometimes I want to use exceptions as control flow without them rolling things back. Context managers are good but it's a matter of how abstracted they should be.
|
||||||
|
|
||||||
### To do list: User permissions
|
### To do list: User permissions
|
||||||
Here are some thoughts about the kinds of features that need to exist within the permission system. I don't know how I'll actually manage it just yet. Possibly a `permissions` table in the database with `user_id | permission` where `permission` is some reliably-formatted string.
|
Here are some thoughts about the kinds of features that need to exist within the permission system. I don't know how I'll actually manage it just yet. Possibly a `permissions` table in the database with `user_id | permission` where `permission` is some reliably-formatted string.
|
||||||
|
|
|
@ -1232,9 +1232,41 @@ class PhotoDB(PDBAlbumMixin, PDBBookmarkMixin, PDBPhotoMixin, PDBTagMixin, PDBUs
|
||||||
If a Photo object already exists for a file, it will be added to the
|
If a Photo object already exists for a file, it will be added to the
|
||||||
correct album.
|
correct album.
|
||||||
'''
|
'''
|
||||||
|
def create_or_fetch_photos(files):
|
||||||
|
photos = []
|
||||||
|
for filepath in files:
|
||||||
|
try:
|
||||||
|
photo = self.get_photo_by_path(filepath)
|
||||||
|
except exceptions.NoSuchPhoto:
|
||||||
|
photo = self.new_photo(filepath.absolute_path, commit=False, **new_photo_kwargs)
|
||||||
|
|
||||||
|
photos.append(photo)
|
||||||
|
return photos
|
||||||
|
|
||||||
|
def create_or_fetch_current_album(albums_by_path, current_directory):
|
||||||
|
current_album = albums_by_path.get(current_directory.absolute_path, None)
|
||||||
|
if current_album is None:
|
||||||
|
try:
|
||||||
|
current_album = self.get_album_by_path(current_directory.absolute_path)
|
||||||
|
except exceptions.NoSuchAlbum:
|
||||||
|
current_album = self.new_album(
|
||||||
|
associated_directory=current_directory.absolute_path,
|
||||||
|
commit=False,
|
||||||
|
title=current_directory.basename,
|
||||||
|
)
|
||||||
|
albums_by_path[current_directory.absolute_path] = current_album
|
||||||
|
return current_album
|
||||||
|
|
||||||
|
def orphan_join_parent_album(albums_by_path, current_album, current_directory):
|
||||||
|
if current_album.parent() is None:
|
||||||
|
parent = albums_by_path.get(current_directory.parent.absolute_path, None)
|
||||||
|
if parent is not None:
|
||||||
|
parent.add_child(current_album, commit=False)
|
||||||
|
|
||||||
directory = pathclass.Path(directory)
|
directory = pathclass.Path(directory)
|
||||||
if not directory.is_dir:
|
if not directory.is_dir:
|
||||||
raise ValueError('Not a directory: %s' % directory)
|
raise ValueError('Not a directory: %s' % directory)
|
||||||
|
directory.correct_case()
|
||||||
|
|
||||||
if exclude_directories is None:
|
if exclude_directories is None:
|
||||||
exclude_directories = self.config['digest_exclude_dirs']
|
exclude_directories = self.config['digest_exclude_dirs']
|
||||||
|
@ -1246,15 +1278,6 @@ class PhotoDB(PDBAlbumMixin, PDBBookmarkMixin, PDBPhotoMixin, PDBTagMixin, PDBUs
|
||||||
if 'filepath' in new_photo_kwargs:
|
if 'filepath' in new_photo_kwargs:
|
||||||
new_photo_kwargs.pop('filepath')
|
new_photo_kwargs.pop('filepath')
|
||||||
|
|
||||||
directory.correct_case()
|
|
||||||
generator = spinal.walk_generator(
|
|
||||||
directory,
|
|
||||||
exclude_directories=exclude_directories,
|
|
||||||
exclude_filenames=exclude_filenames,
|
|
||||||
recurse=recurse,
|
|
||||||
yield_style='nested',
|
|
||||||
)
|
|
||||||
|
|
||||||
if make_albums:
|
if make_albums:
|
||||||
try:
|
try:
|
||||||
album = self.get_album_by_path(directory.absolute_path)
|
album = self.get_album_by_path(directory.absolute_path)
|
||||||
|
@ -1264,47 +1287,26 @@ class PhotoDB(PDBAlbumMixin, PDBBookmarkMixin, PDBPhotoMixin, PDBTagMixin, PDBUs
|
||||||
commit=False,
|
commit=False,
|
||||||
title=directory.basename,
|
title=directory.basename,
|
||||||
)
|
)
|
||||||
albums = {directory.absolute_path: album}
|
albums_by_path = {directory.absolute_path: album}
|
||||||
|
|
||||||
for (current_location, directories, files) in generator:
|
walk_generator = spinal.walk_generator(
|
||||||
# Create the photo object
|
directory,
|
||||||
new_photos = []
|
exclude_directories=exclude_directories,
|
||||||
for filepath in files:
|
exclude_filenames=exclude_filenames,
|
||||||
try:
|
recurse=recurse,
|
||||||
photo = self.get_photo_by_path(filepath)
|
yield_style='nested',
|
||||||
except exceptions.NoSuchPhoto:
|
)
|
||||||
makenew = True
|
|
||||||
else:
|
|
||||||
makenew = False
|
|
||||||
|
|
||||||
if makenew:
|
for (current_directory, subdirectories, files) in walk_generator:
|
||||||
photo = self.new_photo(filepath.absolute_path, commit=False, **new_photo_kwargs)
|
photos = create_or_fetch_photos(files)
|
||||||
|
|
||||||
new_photos.append(photo)
|
|
||||||
|
|
||||||
if not make_albums:
|
if not make_albums:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# Ensure that the current directory is an album.
|
current_album = create_or_fetch_current_album(albums_by_path, current_directory)
|
||||||
current_album = albums.get(current_location.absolute_path, None)
|
orphan_join_parent_album(albums_by_path, current_album, current_directory)
|
||||||
if current_album is None:
|
|
||||||
try:
|
|
||||||
current_album = self.get_album_by_path(current_location.absolute_path)
|
|
||||||
except exceptions.NoSuchAlbum:
|
|
||||||
current_album = self.new_album(
|
|
||||||
associated_directory=current_location.absolute_path,
|
|
||||||
commit=False,
|
|
||||||
title=current_location.basename,
|
|
||||||
)
|
|
||||||
albums[current_location.absolute_path] = current_album
|
|
||||||
|
|
||||||
parent = albums.get(current_location.parent.absolute_path, None)
|
for photo in photos:
|
||||||
if parent is not None:
|
|
||||||
try:
|
|
||||||
parent.add_child(current_album, commit=False)
|
|
||||||
except exceptions.GroupExists:
|
|
||||||
pass
|
|
||||||
for photo in new_photos:
|
|
||||||
current_album.add_photo(photo, commit=False)
|
current_album.add_photo(photo, commit=False)
|
||||||
|
|
||||||
if commit:
|
if commit:
|
||||||
|
|
Loading…
Reference in a new issue