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():
|
for (real_filepath, arcname) in arcnames.items():
|
||||||
streamed_zip.write(real_filepath, arcname=arcname)
|
streamed_zip.write(real_filepath, arcname=arcname)
|
||||||
|
|
||||||
#if album.description:
|
directories = helpers.album_zip_directories(album, recursive=recursive)
|
||||||
# streamed_zip.writestr(
|
for (inner_album, directory) in directories.items():
|
||||||
# arcname='%s.txt' % album.id,
|
text = []
|
||||||
# data=album.description.encode('utf-8'),
|
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:
|
if album.title:
|
||||||
download_as = '%s - %s.zip' % (album.id, 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
|
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):
|
def album_zip_filenames(album, recursive=True):
|
||||||
'''
|
'''
|
||||||
Given an album, produce a dictionary mapping local filepaths to the filenames
|
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 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 = {}
|
arcnames = {}
|
||||||
|
directories = album_zip_directories(album, recursive=recursive)
|
||||||
|
for (album, directory) in directories.items():
|
||||||
|
photos = album.photos()
|
||||||
for photo in photos:
|
for photo in photos:
|
||||||
photo_name = '%s - %s' % (photo.id, photo.basename)
|
if photo.real_filepath in arcnames:
|
||||||
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:
|
|
||||||
continue
|
continue
|
||||||
arcname = os.path.join(root_folder, arcname)
|
photo_name = '%s - %s' % (photo.id, photo.basename)
|
||||||
arcnames[filepath] = arcname
|
arcnames[photo.real_filepath] = os.path.join(directory, photo_name)
|
||||||
|
|
||||||
return arcnames
|
return arcnames
|
||||||
|
|
||||||
def chunk_sequence(sequence, chunk_length, allow_incomplete=True):
|
def chunk_sequence(sequence, chunk_length, allow_incomplete=True):
|
||||||
|
@ -165,13 +177,8 @@ def normalize_filepath(filepath, allowed=''):
|
||||||
'''
|
'''
|
||||||
Remove some bad characters.
|
Remove some bad characters.
|
||||||
'''
|
'''
|
||||||
badchars = constants.FILENAME_BADCHARS
|
badchars = remove_characters(constants.FILENAME_BADCHARS, allowed)
|
||||||
for character in allowed:
|
filepath = remove_characters(filepath, badchars)
|
||||||
badchars = badchars.replace(allowed, '')
|
|
||||||
|
|
||||||
filepath = remove_control_characters(filepath)
|
|
||||||
badchars = dict.fromkeys(badchars)
|
|
||||||
filepath = filepath.translate(badchars)
|
|
||||||
|
|
||||||
filepath = filepath.replace('/', os.sep)
|
filepath = filepath.replace('/', os.sep)
|
||||||
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
|
yield chunk
|
||||||
sent_amount += len(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):
|
def remove_control_characters(text):
|
||||||
'''
|
'''
|
||||||
Thanks SilentGhost
|
Thanks SilentGhost
|
||||||
http://stackoverflow.com/a/4324823
|
http://stackoverflow.com/a/4324823
|
||||||
'''
|
'''
|
||||||
kill = dict.fromkeys(range(32))
|
translator = dict.fromkeys(range(32))
|
||||||
text = text.translate(kill)
|
text = text.translate(translator)
|
||||||
return text
|
return text
|
||||||
|
|
||||||
def seconds_to_hms(seconds):
|
def seconds_to_hms(seconds):
|
||||||
|
|
|
@ -175,6 +175,9 @@ class Album(ObjectBase, GroupableMixin):
|
||||||
self.name = 'Album %s' % self.id
|
self.name = 'Album %s' % self.id
|
||||||
self.group_getter = self.photodb.get_album
|
self.group_getter = self.photodb.get_album
|
||||||
|
|
||||||
|
def __hash__(self):
|
||||||
|
return hash(self.id)
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return 'Album:{id}'.format(id=self.id)
|
return 'Album:{id}'.format(id=self.id)
|
||||||
|
|
||||||
|
@ -280,7 +283,7 @@ class Photo(ObjectBase):
|
||||||
|
|
||||||
self.id = row_tuple['id']
|
self.id = row_tuple['id']
|
||||||
self.real_filepath = row_tuple['filepath']
|
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.real_path = pathclass.Path(self.real_filepath)
|
||||||
self.filepath = row_tuple['override_filename'] or 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)
|
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 = self.real_path
|
||||||
old_path.correct_case()
|
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) == '':
|
if os.path.dirname(new_filename) == '':
|
||||||
new_path = old_path.parent.with_child(new_filename)
|
new_path = old_path.parent.with_child(new_filename)
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -47,7 +47,11 @@ p
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</ul>
|
</ul>
|
||||||
{% endif %}
|
{% 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() %}
|
{% set photos = album.photos() %}
|
||||||
{% if photos %}
|
{% if photos %}
|
||||||
<h3>Photos</h3>
|
<h3>Photos</h3>
|
||||||
|
|
Loading…
Reference in a new issue