Browse Source

Split input and output size

pull/421/head
Simon Conseil 5 years ago
parent
commit
154e4e2e34
  1. 7
      sigal/gallery.py
  2. 84
      sigal/plugins/encrypt/encrypt.py
  3. 2
      tests/sample/sigal.conf.py
  4. 5
      tests/test_gallery.py

7
sigal/gallery.py

@ -237,6 +237,11 @@ class Image(Media):
"""The dimensions of the resized image."""
return get_size(self.dst_path)
@cached_property
def input_size(self):
"""The dimensions of the input image."""
return get_size(self.src_path)
@cached_property
def thumb_size(self):
"""The dimensions of the thumbnail image."""
@ -479,7 +484,7 @@ class Album:
# Use f.size if available as it is quicker (in cache), but
# fallback to the size of src_path if dst_path is missing
size = f.size
size = f.input_size
if size is None:
size = f.file_metadata['size']

84
sigal/plugins/encrypt/encrypt.py

@ -30,20 +30,25 @@ from click import progressbar
from sigal import signals
from sigal.settings import get_thumb
from sigal.utils import copy, url_from_path
from sigal.utils import copy
from .endec import encrypt, kdf_gen_key
logger = logging.getLogger(__name__)
ASSETS_PATH = os.path.normpath(os.path.join(
os.path.abspath(os.path.dirname(__file__)), 'static'))
ASSETS_PATH = os.path.normpath(
os.path.join(os.path.abspath(os.path.dirname(__file__)), 'static'))
class Abort(Exception):
pass
def gen_rand_string(length=16):
return "".join(random.SystemRandom().choices(string.ascii_letters + string.digits, k=length))
return "".join(random.SystemRandom().choices(string.ascii_letters +
string.digits,
k=length))
def get_options(settings, cache):
if "encrypt_options" not in settings:
@ -58,7 +63,7 @@ def get_options(settings, cache):
table = str.maketrans({'"': r'\"', '\\': r'\\'})
if "password" not in settings["encrypt_options"] \
or len(settings["encrypt_options"]["password"]) == 0:
or len(settings["encrypt_options"]["password"]) == 0:
logger.error("Encrypt: no password provided")
raise ValueError("no password provided")
else:
@ -66,8 +71,10 @@ def get_options(settings, cache):
options["escaped_password"] = options["password"].translate(table)
if "ask_password" not in options:
options["ask_password"] = settings["encrypt_options"].get("ask_password", False)
options["filtered_password"] = "" if options["ask_password"] else options["escaped_password"]
options["ask_password"] = settings["encrypt_options"].get(
"ask_password", False)
options["filtered_password"] = "" if options["ask_password"] else options[
"escaped_password"]
if "gcm_tag" not in options:
options["gcm_tag"] = gen_rand_string()
@ -83,7 +90,8 @@ def get_options(settings, cache):
if "kdf_iters" not in options:
options["kdf_iters"] = 10000
# in case any of the credentials are newly generated, write them back to cache
# in case any of the credentials are newly generated, write them back
# to cache
cache["credentials"] = {
"gcm_tag": options["gcm_tag"],
"kdf_salt": options["kdf_salt"],
@ -93,9 +101,11 @@ def get_options(settings, cache):
return options
def cache_key(media):
return os.path.join(media.path, media.filename)
def save_property(cache, media):
key = cache_key(media)
if key not in cache:
@ -104,16 +114,20 @@ def save_property(cache, media):
cache[key]["thumb_size"] = media.thumb_size
cache[key]["encrypted"] = set()
def get_encrypt_list(settings, media):
to_encrypt = []
to_encrypt.append(media.filename) #resized image or in case of "use_orig", the original
# resized image or in case of "use_orig", the original
to_encrypt.append(media.filename)
if settings["make_thumbs"]:
to_encrypt.append(get_thumb(settings, media.filename)) #thumbnail
to_encrypt.append(get_thumb(settings, media.filename)) # thumbnail
if media.big is not None and not settings["use_orig"]:
to_encrypt.append(media.big) #original image
to_encrypt = list(map(lambda path: os.path.join(media.path, path), to_encrypt))
to_encrypt.append(media.big) # original image
to_encrypt = list(
map(lambda path: os.path.join(media.path, path), to_encrypt))
return to_encrypt
def load_property(album):
gallery = album.gallery
cache = load_cache(gallery.settings)
@ -125,21 +139,25 @@ def load_property(album):
media.size = cache[key]["size"]
media.thumb_size = cache[key]["thumb_size"]
def load_cache(settings):
cachePath = os.path.join(settings["destination"], ".encryptCache")
try:
with open(cachePath, "rb") as cacheFile:
encryptCache = pickle.load(cacheFile)
logger.debug("Loaded encryption cache with %d entries", len(encryptCache))
logger.debug("Loaded encryption cache with %d entries",
len(encryptCache))
return encryptCache
except FileNotFoundError:
encryptCache = {}
return encryptCache
except Exception as e:
logger.error("Could not load encryption cache: %s", e)
logger.error("Giving up encryption. You may have to delete and rebuild the entire gallery.")
logger.error("Giving up encryption. You may have to delete and "
"rebuild the entire gallery.")
raise Abort
def save_cache(settings, cache):
cachePath = os.path.join(settings["destination"], ".encryptCache")
try:
@ -150,6 +168,7 @@ def save_cache(settings, cache):
logger.warning("Could not store encryption cache: %s", e)
logger.warning("Next build of the gallery is likely to fail!")
def encrypt_gallery(gallery):
albums = gallery.albums
settings = gallery.settings
@ -163,19 +182,26 @@ def encrypt_gallery(gallery):
encrypt_files(settings, config, cache, albums, gallery.progressbar_target)
save_cache(settings, cache)
def encrypt_files(settings, config, cache, albums, progressbar_target):
if settings["keep_orig"] and settings["orig_link"]:
logger.warning("Original images are symlinked! Encryption is aborted. Please set \"orig_link\" to False and restart gallery build.")
logger.warning(
"Original images are symlinked! Encryption is aborted. "
"Please set 'orig_link' to False and restart gallery build.")
raise Abort
key = kdf_gen_key(config["password"], config["kdf_salt"], config["kdf_iters"])
key = kdf_gen_key(config["password"], config["kdf_salt"],
config["kdf_iters"])
gcm_tag = config["gcm_tag"].encode("utf-8")
medias = list(chain.from_iterable(albums.values()))
with progressbar(medias, label="%16s" % "Encrypting files", file=progressbar_target, show_eta=True) as medias:
with progressbar(medias,
label="%16s" % "Encrypting files",
file=progressbar_target,
show_eta=True) as medias:
for media in medias:
if media.type != "image":
logger.info("Skipping non-image file %s", media.filename)
logger.info("Skipping non-image file %s", media.src_filename)
continue
save_property(cache, media)
@ -196,9 +222,11 @@ def encrypt_files(settings, config, cache, albums, progressbar_target):
save_cache(settings, cache)
raise Abort
key_check_path = os.path.join(settings["destination"], 'static', 'keycheck.txt')
key_check_path = os.path.join(settings["destination"], 'static',
'keycheck.txt')
encrypt_file("keycheck.txt", key_check_path, key, gcm_tag)
def encrypt_file(filename, full_path, key, gcm_tag):
with BytesIO() as outBuffer:
try:
@ -217,16 +245,28 @@ def encrypt_file(filename, full_path, key, gcm_tag):
return False
return True
def copy_assets(settings):
theme_path = os.path.join(settings["destination"], 'static')
copy(os.path.join(ASSETS_PATH, "decrypt.js"), theme_path, symlink=False, rellink=False)
copy(os.path.join(ASSETS_PATH, "keycheck.txt"), theme_path, symlink=False, rellink=False)
copy(os.path.join(ASSETS_PATH, "sw.js"), settings["destination"], symlink=False, rellink=False)
copy(os.path.join(ASSETS_PATH, "decrypt.js"),
theme_path,
symlink=False,
rellink=False)
copy(os.path.join(ASSETS_PATH, "keycheck.txt"),
theme_path,
symlink=False,
rellink=False)
copy(os.path.join(ASSETS_PATH, "sw.js"),
settings["destination"],
symlink=False,
rellink=False)
def inject_scripts(context):
cache = load_cache(context['settings'])
context["encrypt_options"] = get_options(context['settings'], cache)
def register(settings):
signals.gallery_build.connect(encrypt_gallery)
signals.album_initialized.connect(load_property)

2
tests/sample/sigal.conf.py

@ -4,7 +4,7 @@ source = 'pictures'
thumb_suffix = '.tn'
keep_orig = True
thumb_video_delay = 5
img_format = 'jpeg'
# img_format = 'jpeg'
links = [('Example link', 'http://example.org'),
('Another link', 'http://example.org')]

5
tests/test_gallery.py

@ -141,8 +141,11 @@ def test_image(settings, tmpdir):
def test_video(settings, tmpdir):
settings['destination'] = str(tmpdir)
m = Video('example video.ogv', 'video', settings)
src_path = join('video', 'example video.ogv')
assert str(m) == src_path
file_path = join('video', 'example video.webm')
assert str(m) == file_path
assert m.dst_path == join(settings['destination'], file_path)
os.makedirs(join(settings['destination'], 'video', 'thumbnails'))

Loading…
Cancel
Save