[enh] Same cache logic for thumbs and fullsize pictures
- store gm settings in the cache as a dict - generalize usage of the gm settings to resize - can be used to resize fullsize versions of the pictures - without -quality switch, gm defaults to -quality 75. use -define jpeg:preserve-settings for fullsize versions to avoid altering them - do not store "name" in the cache, because when the same image is used in a gallery and as the cover, it invalidates the cache entry and becomes always generated
This commit is contained in:
parent
31298be91b
commit
947bbe9470
@ -3,6 +3,10 @@ import json
|
|||||||
|
|
||||||
CACHE_VERSION = 1
|
CACHE_VERSION = 1
|
||||||
|
|
||||||
|
def remove_name(options):
|
||||||
|
noname_options = options.copy()
|
||||||
|
del noname_options["name"]
|
||||||
|
return noname_options
|
||||||
|
|
||||||
class Cache(object):
|
class Cache(object):
|
||||||
cache_file_path = os.path.join(os.getcwd(), ".prosopopee_cache")
|
cache_file_path = os.path.join(os.getcwd(), ".prosopopee_cache")
|
||||||
@ -22,39 +26,23 @@ class Cache(object):
|
|||||||
print "info: cache format as changed, prune cache"
|
print "info: cache format as changed, prune cache"
|
||||||
self.cache = {"version": CACHE_VERSION}
|
self.cache = {"version": CACHE_VERSION}
|
||||||
|
|
||||||
def thumbnail_needs_to_be_generated(self, source, target, image):
|
|
||||||
|
def needs_to_be_generated(self, source, target, options):
|
||||||
if not os.path.exists(target):
|
if not os.path.exists(target):
|
||||||
return True
|
return True
|
||||||
|
|
||||||
if target not in self.cache:
|
if target not in self.cache:
|
||||||
return True
|
return True
|
||||||
|
|
||||||
cached_thumbnail = self.cache[target]
|
cached_picture = self.cache[target]
|
||||||
|
|
||||||
if cached_thumbnail["size"] != os.path.getsize(source) or cached_thumbnail["options"] != image.options:
|
if cached_picture["size"] != os.path.getsize(source) or cached_picture["options"] != remove_name(options):
|
||||||
return True
|
return True
|
||||||
|
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def image_needs_to_be_oritend(self, source, target, command):
|
def cache_picture(self, source, target, options):
|
||||||
if not os.path.exists(target):
|
self.cache[target] = {"size": os.path.getsize(source), "options": remove_name(options)}
|
||||||
return True
|
|
||||||
|
|
||||||
if target not in self.cache:
|
|
||||||
return True
|
|
||||||
|
|
||||||
cached_image = self.cache[target]
|
|
||||||
|
|
||||||
if cached_image["size"] != os.path.getsize(source) or cached_image["command"] != command:
|
|
||||||
return True
|
|
||||||
|
|
||||||
return False
|
|
||||||
|
|
||||||
def cache_thumbnail(self, source, target, image):
|
|
||||||
self.cache[target] = {"size": os.path.getsize(source), "options": image.options}
|
|
||||||
|
|
||||||
def cache_auto_oriented_image(self, source, target, command):
|
|
||||||
self.cache[target] = {"size": os.path.getsize(source), "command": command}
|
|
||||||
|
|
||||||
def __del__(self):
|
def __del__(self):
|
||||||
self.json.dump(self.cache, open(self.cache_file_path, "w"))
|
self.json.dump(self.cache, open(self.cache_file_path, "w"))
|
||||||
|
@ -19,7 +19,9 @@ SETTINGS = {
|
|||||||
"show_date": True,
|
"show_date": True,
|
||||||
"gm": {
|
"gm": {
|
||||||
"quality": 75,
|
"quality": 75,
|
||||||
"auto-orient": True
|
"auto-orient": True,
|
||||||
|
"strip": True,
|
||||||
|
"resize": None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -46,6 +48,24 @@ class Image(object):
|
|||||||
def autoorient(self):
|
def autoorient(self):
|
||||||
return self.options["auto-orient"]
|
return self.options["auto-orient"]
|
||||||
|
|
||||||
|
def gm(self, source, target, options):
|
||||||
|
if CACHE.needs_to_be_generated(source, target, options):
|
||||||
|
gm_switches = {
|
||||||
|
"source": source,
|
||||||
|
"target": target,
|
||||||
|
"auto-orient" : "-auto-orient" if options["auto-orient"] else "",
|
||||||
|
"strip": "-strip" if options["strip"] else "",
|
||||||
|
"quality": "-quality %s" % options["quality"] if options.has_key("quality") else "-define jpeg:preserve-settings",
|
||||||
|
"resize": "-resize %s" % options["resize"] if options.has_key("resize") else ""
|
||||||
|
}
|
||||||
|
command = "gm convert {source} {auto-orient} {strip} {quality} {resize} {target}".format(**gm_switches)
|
||||||
|
print command
|
||||||
|
os.system(command)
|
||||||
|
CACHE.cache_picture(source, target, options)
|
||||||
|
else:
|
||||||
|
print "skipped %s since it's already generated (based on source unchanged size and images options set in your gallery's settings.yaml)" % target
|
||||||
|
|
||||||
|
|
||||||
def copy(self):
|
def copy(self):
|
||||||
source, target = os.path.join(self.base_dir, self.name), os.path.join(self.target_dir, self.name)
|
source, target = os.path.join(self.base_dir, self.name), os.path.join(self.target_dir, self.name)
|
||||||
|
|
||||||
@ -53,40 +73,26 @@ class Image(object):
|
|||||||
# if os.path.exists(target) and os.path.getsize(source) == os.path.getsize(target):
|
# if os.path.exists(target) and os.path.getsize(source) == os.path.getsize(target):
|
||||||
# print "Skipped %s since the file hasn't been modified based on file size" % source
|
# print "Skipped %s since the file hasn't been modified based on file size" % source
|
||||||
# return ""
|
# return ""
|
||||||
if not self.autoorient:
|
|
||||||
|
options = self.options.copy()
|
||||||
|
if not options["auto-orient"] and not options["strip"]:
|
||||||
shutil.copyfile(source, target)
|
shutil.copyfile(source, target)
|
||||||
print source, "->", target
|
print source, "->", target
|
||||||
return ""
|
|
||||||
|
|
||||||
command = "gm convert %s -strip -auto-orient %s" % (source, target)
|
|
||||||
|
|
||||||
if CACHE.image_needs_to_be_oritend(source, target, command):
|
|
||||||
print command
|
|
||||||
os.system(command)
|
|
||||||
CACHE.cache_auto_oriented_image(source, target, command)
|
|
||||||
else:
|
else:
|
||||||
print "skipped %s since it's already generated (based on source unchanged size and images options)" % target
|
# Do not consider quality settings here, since we aim to copy the input image
|
||||||
|
# better to preserve input encoding setting
|
||||||
|
del options["quality"]
|
||||||
|
self.gm(source, target, options)
|
||||||
return ""
|
return ""
|
||||||
|
|
||||||
def generate_thumbnail(self, gm_geometry):
|
def generate_thumbnail(self, gm_geometry):
|
||||||
thumbnail_name = self.name.split(".")
|
thumbnail_name = self.name.split(".")
|
||||||
thumbnail_name[-2] += "-%s" % gm_geometry
|
thumbnail_name[-2] += "-%s" % gm_geometry
|
||||||
thumbnail_name = ".".join(thumbnail_name)
|
thumbnail_name = ".".join(thumbnail_name)
|
||||||
|
|
||||||
source, target = os.path.join(self.base_dir, self.name), os.path.join(self.target_dir, thumbnail_name)
|
source, target = os.path.join(self.base_dir, self.name), os.path.join(self.target_dir, thumbnail_name)
|
||||||
|
options = self.options.copy()
|
||||||
if CACHE.thumbnail_needs_to_be_generated(source, target, self):
|
options.update({"resize": gm_geometry})
|
||||||
gm_options = ""
|
self.gm(source, target, options)
|
||||||
if self.autoorient:
|
|
||||||
gm_options = "-auto-orient"
|
|
||||||
command = "gm convert %s -strip %s -resize %s -quality %s %s" % (source, gm_options, gm_geometry, self.quality, target)
|
|
||||||
print command
|
|
||||||
os.system(command)
|
|
||||||
CACHE.cache_thumbnail(source, target, self)
|
|
||||||
else:
|
|
||||||
print "skipped %s since it's already generated (based on source unchanged size and images options set in your gallery's settings.yaml)" % target
|
|
||||||
|
|
||||||
return thumbnail_name
|
return thumbnail_name
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
|
Loading…
x
Reference in New Issue
Block a user