105 lines
3.7 KiB
Python
105 lines
3.7 KiB
Python
|
import codecs
|
||
|
import os
|
||
|
import re
|
||
|
from PIL import Image, ExifTags
|
||
|
'''
|
||
|
# You can edit the following line with login details
|
||
|
#REMOTE_PATH = 'user@server:path-to-galleryAlbums/'
|
||
|
if not REMOTE_PATH.endswith('/'):
|
||
|
REMOTE_PATH += '/'
|
||
|
'''
|
||
|
# Size of thumbnails
|
||
|
SIZE_THUMBNAIL = 256
|
||
|
# Size of low-resolution images
|
||
|
SIZE_SMALL = 1080
|
||
|
|
||
|
def create_directory(path):
|
||
|
dirname = os.path.dirname(path)
|
||
|
if not os.path.exists(dirname):
|
||
|
os.mkdir(dirname)
|
||
|
|
||
|
def write_html(source, target, html, title=''):
|
||
|
with codecs.open(source, 'r', encoding='utf-8') as f:
|
||
|
html_original = f.read()
|
||
|
html_original = re.sub('\{title\}', title.title(), html_original)
|
||
|
indent = html_original.split('<!--#')[0].split('\n')[-1]
|
||
|
html = re.sub('\n', '\n{}'.format(indent), '\n{}\n'.format(html))
|
||
|
with codecs.open(target, 'w', encoding='utf-8') as f:
|
||
|
f.write(re.sub(
|
||
|
'(?<=#-->).*?(?=<!--#)', html, html_original, flags=re.DOTALL
|
||
|
))
|
||
|
|
||
|
html_index = '<ul>'
|
||
|
# For each album
|
||
|
for path in [f for f in sorted(os.listdir('./')) if os.path.isdir(f) and f != '!' and f.lower() != 'videos' and f.lower() != 'js']:
|
||
|
html_index += ('\n <li><a href="{0}">{0}</a></li>'.format(path))
|
||
|
html_album = ''
|
||
|
# For each image
|
||
|
for name in [f for f in sorted(os.listdir(path)) if f.lower().endswith('.jpg')]:
|
||
|
path_large = os.path.join(path, name)
|
||
|
path_small = os.path.join(path, str(SIZE_SMALL), name)
|
||
|
path_thumbnail = os.path.join(path, str(SIZE_THUMBNAIL), name)
|
||
|
print(path_large)
|
||
|
image = Image.open(path_large)
|
||
|
# Fix orientation
|
||
|
exif = {
|
||
|
ExifTags.TAGS[k]: v
|
||
|
for k, v in (image._getexif() or {}).items()
|
||
|
if k in ExifTags.TAGS
|
||
|
}
|
||
|
orientation = exif.get('Orientation', 1)
|
||
|
if orientation == 6:
|
||
|
image = image.rotate(-90, expand=True)
|
||
|
elif orientation == 8:
|
||
|
image = image.rotate(90, expand=True)
|
||
|
if orientation != 1:
|
||
|
image.save(path_large)
|
||
|
ratio = image.size[0] / image.size[1]
|
||
|
# Create low-resolution image
|
||
|
if not os.path.exists(path_small):
|
||
|
create_directory(path_small)
|
||
|
image.resize(
|
||
|
(int(round(SIZE_SMALL * ratio)), SIZE_SMALL)
|
||
|
if ratio > 1 else
|
||
|
(SIZE_SMALL, int(round(SIZE_SMALL / ratio))),
|
||
|
Image.ANTIALIAS
|
||
|
).save(path_small)
|
||
|
# Create thumbnail
|
||
|
if not os.path.exists(path_thumbnail):
|
||
|
create_directory(path_thumbnail)
|
||
|
image.resize(
|
||
|
(SIZE_THUMBNAIL, int(round(SIZE_THUMBNAIL / ratio)))
|
||
|
if ratio > 1 else
|
||
|
(int(round(SIZE_THUMBNAIL * ratio)), SIZE_THUMBNAIL),
|
||
|
Image.ANTIALIAS
|
||
|
).save(path_thumbnail)
|
||
|
# Create HTML
|
||
|
html_album += (
|
||
|
'{0}<div><a href="../!/#{1}/{2}">'
|
||
|
'<img class="{3}" src="{4}/{2}"/></a></div>'
|
||
|
).format(
|
||
|
'' if not html_album else '\n', path, name,
|
||
|
'landscape' if ratio > 1 else 'portrait', SIZE_THUMBNAIL
|
||
|
)
|
||
|
# Cleanup
|
||
|
for p in [
|
||
|
os.path.join(path, str(SIZE_SMALL)),
|
||
|
os.path.join(path, str(SIZE_THUMBNAIL))
|
||
|
]:
|
||
|
for n in [f for f in os.listdir(p) if f.lower().endswith('.jpg')]:
|
||
|
if not os.path.exists(os.path.join(path, n)):
|
||
|
os.remove(os.path.join(p, n))
|
||
|
# Write album HTML
|
||
|
write_html(
|
||
|
'album.html', os.path.join(path, 'index.html'), html_album, path
|
||
|
)
|
||
|
html_index += '\n</ul>'
|
||
|
# Write index HTML
|
||
|
write_html('index.html', 'index.html', html_index)
|
||
|
|
||
|
# Alternatively, you can comment this out and use FTP / run rsync separately
|
||
|
'''
|
||
|
print("Syncing albums...")
|
||
|
os.system('rsync -av --ignore-existing ./ "{}"'.format(REMOTE_PATH))
|
||
|
'''
|