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:
		
							parent
							
								
									c80e2003ff
								
							
						
					
					
						commit
						5404a1d411
					
				
					 4 changed files with 44 additions and 73 deletions
				
			
		|  | @ -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__() | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
|  | @ -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" %} | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue