checkpoint

fix bug in which renaming photo causes os.remove even when it's an in-place rename on case-insensitive systems; incorporate expressionmatch for filename search; minor comment cleanup
This commit is contained in:
voussoir 2017-02-25 22:47:20 -08:00
parent c80e2003ff
commit 5404a1d411
4 changed files with 44 additions and 73 deletions

View file

@ -606,7 +606,7 @@ class Photo(ObjectBase):
except:
traceback.print_exc()
elif self.mimetype == 'audio':
elif self.mimetype == 'audio' and constants.ffmpeg:
try:
probe = constants.ffmpeg.probe(self.real_filepath)
if probe and probe.audio:
@ -671,12 +671,11 @@ class Photo(ObjectBase):
os.makedirs(new_path.parent.absolute_path, exist_ok=True)
if new_path != old_path:
# This is different than the absolute == absolute check above,
# because this normalizes the paths. It's possible on
# case-insensitive systems to have the paths point to the same place
# while being differently cased, thus we couldn't make the
# intermediate link.
if new_path.normcase != old_path.normcase:
# It's possible on case-insensitive systems to have the paths point
# to the same place while being differently cased, thus we couldn't
# make the intermediate link.
# Instead, we will do a simple rename in just a moment.
try:
os.link(old_path.absolute_path, new_path.absolute_path)
except OSError:
@ -688,18 +687,21 @@ class Photo(ObjectBase):
[new_path.absolute_path, old_path.absolute_path]
)
if commit:
if new_path == old_path:
# If they are equivalent but differently cased paths, just
# rename.
os.rename(old_path.absolute_path, new_path.absolute_path)
if new_path.normcase == old_path.normcase:
# If they are equivalent but differently cased, just rename.
action = os.rename
args = [old_path.absolute_path, new_path.absolute_path]
else:
# Delete the original hardlink or copy.
os.remove(old_path.absolute_path)
# Delete the original, leaving only the new copy / hardlink.
action = os.remove
args = [old_path.absolute_path]
if commit:
action(*args)
self.photodb.log.debug('Committing - rename file')
self.photodb.commit()
else:
queue_action = {'action': os.remove, 'args': [old_path.absolute_path]}
queue_action = {'action': args, 'args': args}
self.photodb.on_commit_queue.append(queue_action)
self.__reinit__()

View file

@ -719,6 +719,19 @@ class PDBPhotoMixin:
expression_tree = expressionmatch.ExpressionTree.parse(tag_expression)
expression_tree.map(self.normalize_tagname)
expression_matcher = searchhelpers.tag_expression_matcher_builder(frozen_children, warning_bag)
for node in expression_tree.walk_leaves():
if node.token in frozen_children:
continue
if warning_bag is not None:
warning_bag.add(constants.WARNING_NO_SUCH_TAG.format(tag=node.token))
node.token = None
else:
raise_no_such_thing(exceptions.NoSuchTag, thing_name=node.token)
expression_tree.prune()
if filename:
filename_tree = expressionmatch.ExpressionTree.parse(filename)
filename_tree.map(lambda x: x.lower())
photos_received = 0
@ -749,7 +762,7 @@ class PDBPhotoMixin:
#print('Failed author')
continue
if filename and not _helper_filenamefilter(subject=photo.basename, terms=filename):
if filename and not filename_tree.evaluate(photo.basename.lower()):
#print('Failed filename')
continue
@ -924,6 +937,7 @@ class PDBTagMixin:
else:
return tagname
class PDBUserMixin:
def generate_user_id(self):
'''
@ -1228,48 +1242,6 @@ class PhotoDB(PDBAlbumMixin, PDBBookmarkMixin, PDBPhotoMixin, PDBTagMixin, PDBUs
else:
return None
# def digest_new_files(
# self,
# directory,
# exclude_directories=None,
# exclude_filenames=None,
# recurse=False,
# commit=True
# ):
# '''
# Walk the directory and add new files as Photos.
# Does NOT create or modify any albums like `digest_directory` does.
# '''
# if not os.path.isdir(directory):
# raise ValueError('Not a directory: %s' % directory)
# if exclude_directories is None:
# exclude_directories = self.config['digest_exclude_dirs']
# if exclude_filenames is None:
# exclude_filenames = self.config['digest_exclude_files']
# directory = spinal.str_to_fp(directory)
# generator = spinal.walk_generator(
# directory,
# exclude_directories=exclude_directories,
# exclude_filenames=exclude_filenames,
# recurse=recurse,
# yield_style='flat',
# )
# for filepath in generator:
# filepath = filepath.absolute_path
# try:
# self.get_photo_by_path(filepath)
# except exceptions.NoSuchPhoto:
# # This is what we want.
# pass
# else:
# continue
# photo = self.new_photo(filepath, commit=False)
# if commit:
# self.log.debug('Committing - digest_new_files')
# self.commit()
def easybake(self, ebstring):
'''
Easily create tags, groups, and synonyms with a string like

View file

@ -153,7 +153,7 @@ def normalize_filename(filename_terms):
filename_terms = ' '.join(filename_terms)
filename_terms = filename_terms.strip()
filename_terms = [term.lower() for term in shlex.split(filename_terms)]
filename_terms = shlex.split(filename_terms)
if not filename_terms:
return None
@ -331,14 +331,7 @@ def tag_expression_matcher_builder(frozen_children, warning_bag=None):
if not photo_tags:
return False
try:
options = frozen_children[tagname]
except KeyError:
if warning_bag is not None:
warning_bag.add(constants.WARNING_NO_SUCH_TAG.format(tag=tagname))
return False
else:
raise exceptions.NoSuchTag(tagname)
return any(option in photo_tags for option in options)
return matcher

View file

@ -15,8 +15,6 @@
/* Override common.css */
flex-direction: row;
flex: 1;
/*height: 100%;
width: 100%;*/
}
#left
{
@ -78,8 +76,6 @@
flex-direction: column;
justify-content: center;
align-items: center;
/* height: 100%;
width: 100%;*/
}
.photo_viewer a
{
@ -174,7 +170,15 @@
<!-- THE PHOTO ITSELF -->
<div class="photo_viewer">
{% if photo.mimetype == "image" %}
<div id="photo_img_holder"><img id="photo_img" src="{{link}}" onclick="toggle_hoverzoom()" onload="this.style.opacity=0.99"></div>
<div id="photo_img_holder">
<img
id="photo_img"
src="{{link}}"
alt="{{photo.basename}}"
onclick="toggle_hoverzoom()"
onload="this.style.opacity=0.99"
>
</div>
{% elif photo.mimetype == "video" %}
<video src="{{link}}" controls preload=none {%if photo.thumbnail%}poster="/thumbnail/{{photo.id}}.jpg"{%endif%}></video>
{% elif photo.mimetype == "audio" %}