Generate thumbnails on the fly

This commit is contained in:
simon987 2019-03-10 21:09:23 -04:00
parent 746ad25a4e
commit 60349cf954
3 changed files with 41 additions and 30 deletions

View File

@ -169,7 +169,7 @@ class MediaFileParser(GenericFileParser):
"audio/mid", "audio/mpeg", "audio/mp4", "audio/x-aiff", "audio/mid", "audio/mpeg", "audio/mp4", "audio/x-aiff",
"audio/ogg", "audio/vorbis" "audio/x-realaudio", "audio/x-wav", "audio/ogg", "audio/vorbis" "audio/x-realaudio", "audio/x-wav",
"audio/flac", "audio/x-monkeys-audio", "audio/wav", "audio/wave", "audio/flac", "audio/x-monkeys-audio", "audio/wav", "audio/wave",
"audio/x-wav", "audio/x-ms-wma" "audio/x-wav", "audio/x-ms-wma", "audio/x-flac",
] ]
def parse(self, full_path: str): def parse(self, full_path: str):

24
run.py
View File

@ -13,6 +13,7 @@ from crawler import TaskManager
from search import Search from search import Search
from storage import Directory, Option, Task, User from storage import Directory, Option, Task, User
from storage import LocalStorage, DuplicateDirectoryException, DuplicateUserException from storage import LocalStorage, DuplicateDirectoryException, DuplicateUserException
from thumbnail import ThumbnailGenerator
app = Flask(__name__) app = Flask(__name__)
app.secret_key = "A very secret key" app.secret_key = "A very secret key"
@ -174,7 +175,6 @@ def document(doc_id):
@app.route("/dl/<doc_id>") @app.route("/dl/<doc_id>")
def serve_file(doc_id): def serve_file(doc_id):
doc = search.get_doc(doc_id)["_source"] doc = search.get_doc(doc_id)["_source"]
directory = storage.dirs()[doc["directory"]] directory = storage.dirs()[doc["directory"]]
@ -205,16 +205,24 @@ def thumb(doc_id):
doc = search.get_doc(doc_id) doc = search.get_doc(doc_id)
if doc is not None: if doc is not None:
dest_path = "static/thumbnails/" + str(doc["_source"]["directory"])
tn_path = os.path.join("static/thumbnails/", str(doc["_source"]["directory"]), doc_id) os.makedirs(dest_path, exist_ok=True)
print(tn_path) tn_path = os.path.join(dest_path, doc_id)
if os.path.isfile(tn_path): if os.path.isfile(tn_path):
return send_file(tn_path) return send_file(tn_path)
default_thumbnail = BytesIO() directory = storage.dirs()[doc["_source"]["directory"]]
Image.new("RGB", (255, 128), (0, 0, 0)).save(default_thumbnail, "JPEG") extension = "" if doc["_source"]["extension"] is None or doc["_source"]["extension"] == "" else \
default_thumbnail.seek(0) "." + doc["_source"]["extension"]
return send_file(default_thumbnail, "image/jpeg") full_path = os.path.join(directory.path,
doc["_source"]["path"],
doc["_source"]["name"] + extension)
tn_generator = ThumbnailGenerator(int(directory.get_option("ThumbnailSize")),
int(directory.get_option("ThumbnailQuality")),
directory.get_option("ThumbnailColor"))
tn_generator.generate(full_path, tn_path, doc["_source"]["mime"])
if os.path.isfile(tn_path):
return send_file(tn_path)
default_thumbnail = BytesIO() default_thumbnail = BytesIO()
Image.new("RGB", (255, 128), (0, 0, 0)).save(default_thumbnail, "JPEG") Image.new("RGB", (255, 128), (0, 0, 0)).save(default_thumbnail, "JPEG")

View File

@ -24,9 +24,9 @@ class ThumbnailGenerator:
if mime is None: if mime is None:
return return
tmpfile = dest_path + "_tmp"
if mime == "image/svg+xml" and config.cairosvg: if mime == "image/svg+xml" and config.cairosvg:
tmpfile = dest_path + "_tmp"
try: try:
p = Process(target=cairosvg.svg2png, kwargs={"url": path, "write_to": tmpfile}) p = Process(target=cairosvg.svg2png, kwargs={"url": path, "write_to": tmpfile})
p.start() p.start()
@ -54,15 +54,15 @@ class ThumbnailGenerator:
try: try:
(ffmpeg. (ffmpeg.
input(path) input(path)
.output("tmp", vframes=1, f="image2", loglevel="error") .output(tmpfile, vframes=1, f="image2", loglevel="error")
.run() .run()
) )
self.generate_image("tmp", dest_path) self.generate_image(tmpfile, dest_path)
except Exception: except Exception:
print("Couldn't make thumbnail for " + path) print("Couldn't make thumbnail for " + path)
if os.path.exists("tmp"): if os.path.exists(tmpfile):
os.remove("tmp") os.remove(tmpfile)
def worker(self, in_q: Queue, counter: Value, dest_path, directory): def worker(self, in_q: Queue, counter: Value, dest_path, directory):
@ -114,25 +114,28 @@ class ThumbnailGenerator:
def generate_image(self, path, dest_path): def generate_image(self, path, dest_path):
with open(path, "rb") as image_file: try:
with Image.open(image_file) as image: with open(path, "rb") as image_file:
with Image.open(image_file) as image:
# https://stackoverflow.com/questions/43978819 # https://stackoverflow.com/questions/43978819
if image.mode == "I;16": if image.mode == "I;16":
image.mode = "I" image.mode = "I"
image.point(lambda i: i * (1. / 256)).convert('L') image.point(lambda i: i * (1. / 256)).convert('L')
image.thumbnail(self.size, Image.BICUBIC) image.thumbnail(self.size, Image.BICUBIC)
canvas = Image.new("RGB", image.size, self.color) canvas = Image.new("RGB", image.size, self.color)
if image.mode in ('RGBA', 'LA') or (image.mode == 'P' and 'transparency' in image.info): if image.mode in ('RGBA', 'LA') or (image.mode == 'P' and 'transparency' in image.info):
try: try:
canvas.paste(image, mask=image.split()[-1]) canvas.paste(image, mask=image.split()[-1])
except ValueError: except ValueError:
canvas.paste(image)
else:
canvas.paste(image) canvas.paste(image)
else:
canvas.paste(image)
canvas.save(dest_path, "JPEG", quality=self.quality, optimize=True) canvas.save(dest_path, "JPEG", quality=self.quality, optimize=True)
canvas.close() canvas.close()
except Exception as e:
print(e)