From 6a13dca2d511bd790e718be34f8a66bfc4cb525e Mon Sep 17 00:00:00 2001 From: rubenwardy Date: Tue, 29 May 2018 16:19:17 +0100 Subject: [PATCH] Add thumbnail support --- .gitignore | 1 + app/models.py | 17 ++++++--- app/templates/macros/packagegridtile.html | 2 +- app/views/__init__.py | 2 +- app/views/thumbnails.py | 45 +++++++++++++++++++++++ requirements.txt | 1 + 6 files changed, 60 insertions(+), 8 deletions(-) create mode 100644 app/views/thumbnails.py diff --git a/.gitignore b/.gitignore index b37ffcc9..57dae518 100644 --- a/.gitignore +++ b/.gitignore @@ -6,6 +6,7 @@ tmp log.txt *.rdb uploads +thumbnails # Created by https://www.gitignore.io/api/linux,macos,python,windows diff --git a/app/models.py b/app/models.py index d414589a..b3a6d5ad 100644 --- a/app/models.py +++ b/app/models.py @@ -374,9 +374,18 @@ class Package(db.Model): "repo": self.repo, "url": base_url + self.getDownloadURL(), "release": self.getDownloadRelease().id if self.getDownloadRelease() is not None else None, - "screenshots": [base_url + ss.url for ss in self.screenshots] + "screenshots": [base_url + ss.url for ss in self.screenshots], + "thumbnail": base_url + self.getThumbnailURL() } + def getThumbnailURL(self): + screenshot = self.screenshots.filter_by(approved=True).first() + return screenshot.getThumbnailURL() if screenshot is not None else None + + def getMainScreenshotURL(self): + screenshot = self.screenshots.filter_by(approved=True).first() + return screenshot.url if screenshot is not None else None + def getDetailsURL(self): return url_for("package_page", author=self.author.username, name=self.name) @@ -409,10 +418,6 @@ class Package(db.Model): return url_for("package_download_page", author=self.author.username, name=self.name) - def getMainScreenshotURL(self): - screenshot = self.screenshots.filter_by(approved=True).first() - return screenshot.url if screenshot is not None else None - def getDownloadRelease(self): for rel in self.releases: if rel.approved: @@ -575,7 +580,7 @@ class PackageScreenshot(db.Model): id=self.id) def getThumbnailURL(self): - return self.url # TODO + return self.url.replace("/uploads/", "/thumbnails/332x221/") class EditRequest(db.Model): id = db.Column(db.Integer, primary_key=True) diff --git a/app/templates/macros/packagegridtile.html b/app/templates/macros/packagegridtile.html index 0ba39dbb..45f1f459 100644 --- a/app/templates/macros/packagegridtile.html +++ b/app/templates/macros/packagegridtile.html @@ -1,6 +1,6 @@ {% macro render_pkgtile(package) -%}
  • + style="background-image: url({{ package.getThumbnailURL() or '/static/placeholder.png' }});">

    {{ package.title }} by {{ package.author.display_name }}

    diff --git a/app/views/__init__.py b/app/views/__init__.py index c28ff56e..21ed40d8 100644 --- a/app/views/__init__.py +++ b/app/views/__init__.py @@ -51,7 +51,7 @@ def home_page(): packages = query.order_by(db.desc(Package.created_at)).limit(15).all() return render_template("index.html", packages=packages, count=count) -from . import users, githublogin, packages, sass, tasks, admin, notifications, tagseditor, meta +from . import users, githublogin, packages, sass, tasks, admin, notifications, tagseditor, meta, thumbnails @menu.register_menu(app, ".help", "Help", order=19, endpoint_arguments_constructor=lambda: { 'path': 'help' }) @app.route('//') diff --git a/app/views/thumbnails.py b/app/views/thumbnails.py new file mode 100644 index 00000000..d33e74cb --- /dev/null +++ b/app/views/thumbnails.py @@ -0,0 +1,45 @@ +# Content DB +# Copyright (C) 2018 rubenwardy +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + + +from flask import * +from app import app + +import glob, os +from PIL import Image + +ALLOWED_RESOLUTIONS=[(332,221)] + +def mkdir(path): + if not os.path.isdir(path): + os.mkdir(path) + +@app.route("/thumbnails/") +@app.route("/thumbnails/x/") +def make_thumbnail(img, w=332, h=221): + if not (w, h) in ALLOWED_RESOLUTIONS: + abort(403) + + mkdir("app/public/thumbnails/") + mkdir("app/public/thumbnails/332x221/") + + cache_filepath = "public/thumbnails/{}x{}/{}".format(w, h, img) + source_filepath = "public/uploads/" + img + + im = Image.open("app/" + source_filepath) + im.thumbnail((w, h), Image.ANTIALIAS) + im.save("app/" + cache_filepath, optimize=True) + return send_file(cache_filepath) diff --git a/requirements.txt b/requirements.txt index 49751a6e..2caa7fc8 100644 --- a/requirements.txt +++ b/requirements.txt @@ -12,3 +12,4 @@ beautifulsoup4==4.6.0 lxml==4.2.1 Flask-FlatPages==0.6 Flask-Migrate==2.1.1 +pillow==5.1.0