Include album info as txt in zip; fix normalize_filepath bugs
This commit is contained in:
		
							parent
							
								
									e992b76db0
								
							
						
					
					
						commit
						af40f24dd8
					
				
					 4 changed files with 62 additions and 34 deletions
				
			
		
							
								
								
									
										19
									
								
								etiquette.py
									
									
									
									
									
								
							
							
						
						
									
										19
									
								
								etiquette.py
									
									
									
									
									
								
							|  | @ -279,11 +279,20 @@ def get_album_zip(albumid): | |||
|     for (real_filepath, arcname) in arcnames.items(): | ||||
|         streamed_zip.write(real_filepath, arcname=arcname) | ||||
| 
 | ||||
|     #if album.description: | ||||
|     #    streamed_zip.writestr( | ||||
|     #        arcname='%s.txt' % album.id, | ||||
|     #        data=album.description.encode('utf-8'), | ||||
|     #    ) | ||||
|     directories = helpers.album_zip_directories(album, recursive=recursive) | ||||
|     for (inner_album, directory) in directories.items(): | ||||
|         text = [] | ||||
|         if inner_album.title: | ||||
|             text.append(inner_album.title) | ||||
|         if inner_album.description: | ||||
|             text.append(inner_album.description) | ||||
|         if not text: | ||||
|             continue | ||||
|         text = '\r\n\r\n'.join(text) | ||||
|         streamed_zip.writestr( | ||||
|             arcname=os.path.join(directory, '%s.txt' % inner_album.id), | ||||
|             data=text.encode('utf-8'), | ||||
|         ) | ||||
| 
 | ||||
|     if album.title: | ||||
|         download_as = '%s - %s.zip' % (album.id, album.title) | ||||
|  |  | |||
							
								
								
									
										62
									
								
								helpers.py
									
									
									
									
									
								
							
							
						
						
									
										62
									
								
								helpers.py
									
									
									
									
									
								
							|  | @ -9,6 +9,27 @@ import exceptions | |||
| 
 | ||||
| from voussoirkit import bytestring | ||||
| 
 | ||||
| def album_zip_directories(album, recursive=True): | ||||
|     ''' | ||||
|     Given an album, produce a dictionary mapping Album objects to directory | ||||
|     names as they will appear inside the zip archive. | ||||
|     Sub-albums become subfolders. | ||||
|     ''' | ||||
|     directories = {} | ||||
|     if album.title: | ||||
|         root_folder = '%s - %s' % (album.id, normalize_filepath(album.title)) | ||||
|     else: | ||||
|         root_folder = '%s' % album.id | ||||
| 
 | ||||
|     directories[album] = root_folder | ||||
|     if recursive: | ||||
|         for child_album in album.children(): | ||||
|             child_directories = album_zip_directories(child_album, recursive=True) | ||||
|             for (child_album, child_directory) in child_directories.items(): | ||||
|                 child_directory = os.path.join(root_folder, child_directory) | ||||
|                 directories[child_album] = child_directory | ||||
|     return directories | ||||
|      | ||||
| def album_zip_filenames(album, recursive=True): | ||||
|     ''' | ||||
|     Given an album, produce a dictionary mapping local filepaths to the filenames | ||||
|  | @ -17,25 +38,16 @@ def album_zip_filenames(album, recursive=True): | |||
| 
 | ||||
|     If a photo appears in multiple albums, only the first is used. | ||||
|     ''' | ||||
|     if album.title: | ||||
|         root_folder = '%s - %s' % (album.id, normalize_filepath(album.title)) | ||||
|     else: | ||||
|         root_folder = '%s' % album.id | ||||
| 
 | ||||
|     photos = album.photos() | ||||
|     arcnames = {} | ||||
|     directories = album_zip_directories(album, recursive=recursive) | ||||
|     for (album, directory) in directories.items(): | ||||
|         photos = album.photos() | ||||
|         for photo in photos: | ||||
|         photo_name = '%s - %s' % (photo.id, photo.basename) | ||||
|         arcnames[photo.real_filepath] = os.path.join(root_folder, photo_name) | ||||
| 
 | ||||
|     if recursive: | ||||
|         for child_album in album.children(): | ||||
|             child_arcnames = album_zip_filenames(child_album) | ||||
|             for (filepath, arcname) in child_arcnames.items(): | ||||
|                 if filepath in arcnames: | ||||
|             if photo.real_filepath in arcnames: | ||||
|                 continue | ||||
|                 arcname = os.path.join(root_folder, arcname) | ||||
|                 arcnames[filepath] = arcname | ||||
|             photo_name = '%s - %s' % (photo.id, photo.basename) | ||||
|             arcnames[photo.real_filepath] = os.path.join(directory, photo_name) | ||||
| 
 | ||||
|     return arcnames | ||||
| 
 | ||||
| def chunk_sequence(sequence, chunk_length, allow_incomplete=True): | ||||
|  | @ -165,13 +177,8 @@ def normalize_filepath(filepath, allowed=''): | |||
|     ''' | ||||
|     Remove some bad characters. | ||||
|     ''' | ||||
|     badchars = constants.FILENAME_BADCHARS | ||||
|     for character in allowed: | ||||
|         badchars = badchars.replace(allowed, '') | ||||
| 
 | ||||
|     filepath = remove_control_characters(filepath) | ||||
|     badchars = dict.fromkeys(badchars) | ||||
|     filepath = filepath.translate(badchars) | ||||
|     badchars = remove_characters(constants.FILENAME_BADCHARS, allowed) | ||||
|     filepath = remove_characters(filepath, badchars) | ||||
| 
 | ||||
|     filepath = filepath.replace('/', os.sep) | ||||
|     filepath = filepath.replace('\\', os.sep) | ||||
|  | @ -206,13 +213,18 @@ def read_filebytes(filepath, range_min, range_max, chunk_size=2 ** 20): | |||
|             yield chunk | ||||
|             sent_amount += len(chunk) | ||||
| 
 | ||||
| def remove_characters(text, characters): | ||||
|     translator = {ord(c): None for c in characters} | ||||
|     text = text.translate(translator) | ||||
|     return text | ||||
| 
 | ||||
| def remove_control_characters(text): | ||||
|     ''' | ||||
|     Thanks SilentGhost | ||||
|     http://stackoverflow.com/a/4324823 | ||||
|     ''' | ||||
|     kill = dict.fromkeys(range(32)) | ||||
|     text = text.translate(kill) | ||||
|     translator = dict.fromkeys(range(32)) | ||||
|     text = text.translate(translator) | ||||
|     return text | ||||
| 
 | ||||
| def seconds_to_hms(seconds): | ||||
|  |  | |||
|  | @ -175,6 +175,9 @@ class Album(ObjectBase, GroupableMixin): | |||
|         self.name = 'Album %s' % self.id | ||||
|         self.group_getter = self.photodb.get_album | ||||
| 
 | ||||
|     def __hash__(self): | ||||
|         return hash(self.id) | ||||
| 
 | ||||
|     def __repr__(self): | ||||
|         return 'Album:{id}'.format(id=self.id) | ||||
| 
 | ||||
|  | @ -280,7 +283,7 @@ class Photo(ObjectBase): | |||
| 
 | ||||
|         self.id = row_tuple['id'] | ||||
|         self.real_filepath = row_tuple['filepath'] | ||||
|         self.real_filepath = helpers.normalize_filepath(self.real_filepath) | ||||
|         self.real_filepath = helpers.normalize_filepath(self.real_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) | ||||
|  | @ -572,7 +575,7 @@ class Photo(ObjectBase): | |||
|         old_path = self.real_path | ||||
|         old_path.correct_case() | ||||
| 
 | ||||
|         new_filename = helpers.normalize_filepath(new_filename) | ||||
|         new_filename = helpers.normalize_filepath(new_filename, allowed=':\\/') | ||||
|         if os.path.dirname(new_filename) == '': | ||||
|             new_path = old_path.parent.with_child(new_filename) | ||||
|         else: | ||||
|  |  | |||
|  | @ -47,7 +47,11 @@ p | |||
|         {% endfor %} | ||||
|     </ul> | ||||
|     {% endif %} | ||||
|     <span><a href="/album/{{album.id}}.zip">(download .zip)</a></span> | ||||
|     <span> | ||||
|         Download: | ||||
|         <a href="/album/{{album.id}}.zip?recursive=no">These files</a> | ||||
|         {% if sub_albums %} | <a href="/album/{{album.id}}.zip?recursive=yes">Include children</a>{% endif %} | ||||
|     </span> | ||||
|     {% set photos = album.photos() %} | ||||
|     {% if photos %} | ||||
|     <h3>Photos</h3> | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue