mirror of
https://github.com/minetest/contentdb.git
synced 2024-11-09 17:13:45 +01:00
Use webp for thumbnails
This commit is contained in:
parent
5ce5684ca6
commit
4578cb157f
@ -426,7 +426,7 @@ def move_to_state(package):
|
||||
if not package.approved_at:
|
||||
post_discord_webhook.delay(package.author.display_name,
|
||||
"New package {}".format(package.get_url("packages.view", absolute=True)), False,
|
||||
package.title, package.short_desc, package.get_thumb_url(2, True))
|
||||
package.title, package.short_desc, package.get_thumb_url(2, True, "png"))
|
||||
package.approved_at = datetime.datetime.now()
|
||||
|
||||
screenshots = PackageScreenshot.query.filter_by(package=package, approved=False).all()
|
||||
@ -437,7 +437,7 @@ def move_to_state(package):
|
||||
elif state == PackageState.READY_FOR_REVIEW:
|
||||
post_discord_webhook.delay(package.author.display_name,
|
||||
"Ready for Review: {}".format(package.get_url("packages.view", absolute=True)), True,
|
||||
package.title, package.short_desc, package.get_thumb_url(2, True))
|
||||
package.title, package.short_desc, package.get_thumb_url(2, True, "png"))
|
||||
|
||||
add_notification(package.maintainers, current_user, NotificationType.PACKAGE_APPROVAL, msg, package.get_url("packages.view"), package)
|
||||
severity = AuditSeverity.NORMAL if current_user in package.maintainers else AuditSeverity.EDITOR
|
||||
@ -480,7 +480,7 @@ def remove(package):
|
||||
|
||||
post_discord_webhook.delay(current_user.username,
|
||||
f"Deleted package {package.author.username}/{package.name} with reason '{reason}'",
|
||||
True, package.title, package.short_desc, package.get_thumb_url(2, True))
|
||||
True, package.title, package.short_desc, package.get_thumb_url(2, True, "png"))
|
||||
|
||||
flash(gettext("Deleted package"), "success")
|
||||
|
||||
@ -500,7 +500,7 @@ def remove(package):
|
||||
|
||||
post_discord_webhook.delay(current_user.username,
|
||||
"Unapproved package with reason {}\n\n{}".format(reason, package.get_url("packages.view", absolute=True)), True,
|
||||
package.title, package.short_desc, package.get_thumb_url(2, True))
|
||||
package.title, package.short_desc, package.get_thumb_url(2, True, "png"))
|
||||
|
||||
flash(gettext("Unapproved package"), "success")
|
||||
|
||||
|
@ -14,15 +14,17 @@
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
from flask import abort, send_file, Blueprint, current_app
|
||||
|
||||
bp = Blueprint("thumbnails", __name__)
|
||||
|
||||
import os
|
||||
from PIL import Image
|
||||
|
||||
ALLOWED_RESOLUTIONS=[(100,67), (270,180), (350,233), (1100,520)]
|
||||
|
||||
bp = Blueprint("thumbnails", __name__)
|
||||
|
||||
|
||||
ALLOWED_RESOLUTIONS = [(100, 67), (270, 180), (350, 233), (1100, 520)]
|
||||
ALLOWED_EXTENSIONS = {"png", "webp"}
|
||||
|
||||
|
||||
def mkdir(path):
|
||||
assert path != "" and path is not None
|
||||
@ -34,10 +36,7 @@ def mkdir(path):
|
||||
|
||||
|
||||
def resize_and_crop(img_path, modified_path, size):
|
||||
try:
|
||||
img = Image.open(img_path)
|
||||
except FileNotFoundError:
|
||||
abort(404)
|
||||
img = Image.open(img_path)
|
||||
|
||||
# Get current and desired ratio for the images
|
||||
img_ratio = img.size[0] / float(img.size[1])
|
||||
@ -64,21 +63,40 @@ def resize_and_crop(img_path, modified_path, size):
|
||||
img.save(modified_path)
|
||||
|
||||
|
||||
def find_source_file(img):
|
||||
upload_dir = current_app.config["UPLOAD_DIR"]
|
||||
source_filepath = os.path.join(upload_dir, img)
|
||||
if os.path.isfile(source_filepath):
|
||||
return source_filepath
|
||||
|
||||
period = source_filepath.rfind(".")
|
||||
start = source_filepath[:period]
|
||||
ext = source_filepath[period + 1:]
|
||||
if ext not in ALLOWED_EXTENSIONS:
|
||||
abort(404)
|
||||
|
||||
for other_ext in ALLOWED_EXTENSIONS:
|
||||
other_path = f"{start}.{other_ext}"
|
||||
if ext != other_ext and os.path.isfile(other_path):
|
||||
return other_path
|
||||
|
||||
abort(404)
|
||||
|
||||
|
||||
@bp.route("/thumbnails/<int:level>/<img>")
|
||||
def make_thumbnail(img, level):
|
||||
if level > len(ALLOWED_RESOLUTIONS) or level <= 0:
|
||||
abort(403)
|
||||
w, h = ALLOWED_RESOLUTIONS[level - 1]
|
||||
|
||||
upload_dir = current_app.config["UPLOAD_DIR"]
|
||||
thumbnail_dir = current_app.config["THUMBNAIL_DIR"]
|
||||
mkdir(thumbnail_dir)
|
||||
|
||||
output_dir = os.path.join(thumbnail_dir, str(level))
|
||||
mkdir(output_dir)
|
||||
|
||||
cache_filepath = os.path.join(output_dir, img)
|
||||
source_filepath = os.path.join(upload_dir, img)
|
||||
cache_filepath = os.path.join(output_dir, img)
|
||||
source_filepath = find_source_file(img)
|
||||
|
||||
resize_and_crop(source_filepath, cache_filepath, (w, h))
|
||||
return send_file(cache_filepath)
|
||||
|
@ -528,7 +528,7 @@ class Package(db.Model):
|
||||
}
|
||||
|
||||
def as_short_dict(self, base_url, version=None, release_id=None, no_load=False):
|
||||
tnurl = self.get_thumb_url(1)
|
||||
tnurl = self.get_thumb_url(1, format="png")
|
||||
|
||||
if release_id is None and no_load == False:
|
||||
release = self.get_download_release(version=version)
|
||||
@ -555,7 +555,7 @@ class Package(db.Model):
|
||||
return ret
|
||||
|
||||
def as_dict(self, base_url, version=None):
|
||||
tnurl = self.get_thumb_url(1)
|
||||
tnurl = self.get_thumb_url(1, format="png")
|
||||
release = self.get_download_release(version=version)
|
||||
return {
|
||||
"author": self.author.username,
|
||||
@ -603,21 +603,21 @@ class Package(db.Model):
|
||||
]
|
||||
}
|
||||
|
||||
def get_thumb_or_placeholder(self, level=2):
|
||||
return self.get_thumb_url(level) or "/static/placeholder.png"
|
||||
def get_thumb_or_placeholder(self, level=2, format="webp"):
|
||||
return self.get_thumb_url(level, False, format) or "/static/placeholder.png"
|
||||
|
||||
def get_thumb_url(self, level=2, abs=False):
|
||||
def get_thumb_url(self, level=2, abs=False, format="webp"):
|
||||
screenshot = self.main_screenshot
|
||||
url = screenshot.get_thumb_url(level) if screenshot is not None else None
|
||||
url = screenshot.get_thumb_url(level, format) if screenshot is not None else None
|
||||
if abs:
|
||||
from app.utils import abs_url
|
||||
return abs_url(url)
|
||||
else:
|
||||
return url
|
||||
|
||||
def get_cover_image_url(self):
|
||||
def get_cover_image_url(self, format="webp"):
|
||||
screenshot = self.cover_image or self.main_screenshot
|
||||
return screenshot and screenshot.get_thumb_url(4)
|
||||
return screenshot and screenshot.get_thumb_url(4, format)
|
||||
|
||||
def get_url(self, endpoint, absolute=False, **kwargs):
|
||||
if absolute:
|
||||
@ -1101,8 +1101,12 @@ class PackageScreenshot(db.Model):
|
||||
name=self.package.name,
|
||||
id=self.id)
|
||||
|
||||
def get_thumb_url(self, level=2):
|
||||
return self.url.replace("/uploads/", "/thumbnails/{:d}/".format(level))
|
||||
def get_thumb_url(self, level=2, format="webp"):
|
||||
url = self.url.replace("/uploads/", "/thumbnails/{:d}/".format(level))
|
||||
if format is not None:
|
||||
start = url[:url.rfind(".")]
|
||||
url = f"{start}.{format}"
|
||||
return url
|
||||
|
||||
def as_dict(self, base_url=""):
|
||||
return {
|
||||
|
@ -9,7 +9,7 @@
|
||||
{%- endblock %}
|
||||
|
||||
{% block headextra %}
|
||||
{% set thumb_url = collection.packages and collection.packages[0].get_thumb_url(3, True) %}
|
||||
{% set thumb_url = collection.packages and collection.packages[0].get_thumb_url(3, True, "png") %}
|
||||
{% if thumb_url -%}
|
||||
<meta name="og:image" content="{{ thumb_url }}">
|
||||
{%- endif %}
|
||||
|
@ -1,6 +1,6 @@
|
||||
{% macro render_pkgtile(package, show_author) -%}
|
||||
<li class="packagetile flex-fill"><a href="{{ package.get_url('packages.view') }}">
|
||||
<img src="{{ package.get_thumb_or_placeholder(2) }}" loading="lazy">
|
||||
<img src="{{ package.get_thumb_or_placeholder() }}" loading="lazy">
|
||||
<div class="packagegridscrub"></div>
|
||||
<div class="packagegridinfo">
|
||||
<h3>
|
||||
|
@ -10,8 +10,8 @@
|
||||
{% endblock %}
|
||||
|
||||
{% block headextra %}
|
||||
{% if package.get_thumb_url(3, True) %}
|
||||
<meta name="og:image" content="{{ package.get_thumb_url(3, True) }}"/>
|
||||
{% if package.get_thumb_url(3, True, "png") %}
|
||||
<meta name="og:image" content="{{ package.get_thumb_url(3, True, "png") }}"/>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
|
@ -9,8 +9,8 @@
|
||||
{% endblock %}
|
||||
|
||||
{% block headextra %}
|
||||
{% if package.get_thumb_url(3, True) -%}
|
||||
<meta name="og:image" content="{{ package.get_thumb_url(3, True) }}"/>
|
||||
{% if package.get_thumb_url(3, True, "png") -%}
|
||||
<meta name="og:image" content="{{ package.get_thumb_url(3, True, "png") }}"/>
|
||||
{%- endif %}
|
||||
{% endblock %}
|
||||
|
||||
|
@ -12,8 +12,8 @@
|
||||
{% endblock %}
|
||||
|
||||
{% block headextra %}
|
||||
{% if package.get_thumb_url(3, True) -%}
|
||||
<meta name="og:image" content="{{ package.get_thumb_url(3, True) }}"/>
|
||||
{% if package.get_thumb_url(3, True, "png") -%}
|
||||
<meta name="og:image" content="{{ package.get_thumb_url(3, True, "png") }}"/>
|
||||
{%- endif %}
|
||||
{% endblock %}
|
||||
|
||||
@ -261,7 +261,7 @@
|
||||
{% if ss.approved or package.check_perm(current_user, "ADD_SCREENSHOTS") %}
|
||||
<div class="carousel-item {% if loop.index == 1 %}active{% endif %}">
|
||||
<a href="{{ ss.url }}" target="_blank">
|
||||
<img class="img-size w-100" src="{{ ss.url }}" alt="{{ ss.title }}" title="{{ ss.title }}" />
|
||||
<img class="img-size w-100" loading="lazy" src="{{ ss.url }}" alt="{{ ss.title }}" title="{{ ss.title }}" />
|
||||
</a>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
Loading…
Reference in New Issue
Block a user