contentdb/app/logic/screenshots.py

104 lines
3.5 KiB
Python
Raw Normal View History

2023-06-19 20:32:36 +02:00
# ContentDB
# Copyright (C) rubenwardy
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero 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 Affero General Public License for more details.
#
# 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/>.
import datetime, json
from flask_babel import lazy_gettext
2021-02-02 18:09:25 +01:00
from app.logic.LogicError import LogicError
from app.logic.uploads import upload_file
2021-02-02 18:29:03 +01:00
from app.models import User, Package, PackageScreenshot, Permission, NotificationType, db, AuditSeverity
2023-06-19 22:27:49 +02:00
from app.utils import add_notification, add_audit_log
2022-01-26 03:51:40 +01:00
from app.utils.image import get_image_size
2022-02-02 02:29:14 +01:00
def do_create_screenshot(user: User, package: Package, title: str, file, is_cover_image: bool, reason: str = None):
2021-02-02 18:09:28 +01:00
thirty_minutes_ago = datetime.datetime.now() - datetime.timedelta(minutes=30)
count = package.screenshots.filter(PackageScreenshot.created_at > thirty_minutes_ago).count()
if count >= 20:
2022-01-14 19:25:28 +01:00
raise LogicError(429, lazy_gettext("Too many requests, please wait before trying again"))
2021-02-02 18:09:28 +01:00
2023-12-15 17:23:07 +01:00
uploaded_url, uploaded_path = upload_file(file, "image", lazy_gettext("a PNG, JPEG, or WebP image file"))
counter = 1
2021-02-02 18:09:28 +01:00
for screenshot in package.screenshots.all():
screenshot.order = counter
counter += 1
ss = PackageScreenshot()
ss.package = package
ss.title = title or "Untitled"
ss.url = uploaded_url
ss.approved = package.check_perm(user, Permission.APPROVE_SCREENSHOT)
ss.order = counter
2022-01-26 03:51:40 +01:00
ss.width, ss.height = get_image_size(uploaded_path)
if ss.is_too_small():
raise LogicError(429,
lazy_gettext("Screenshot is too small, it should be at least %(width)s by %(height)s pixels",
width=PackageScreenshot.HARD_MIN_SIZE[0], height=PackageScreenshot.HARD_MIN_SIZE[1]))
db.session.add(ss)
2021-02-02 18:29:03 +01:00
if reason is None:
msg = "Created screenshot {}".format(ss.title)
else:
msg = "Created screenshot {} ({})".format(ss.title, reason)
2023-06-19 22:27:49 +02:00
add_notification(package.maintainers, user, NotificationType.PACKAGE_EDIT, msg, package.get_url("packages.view"), package)
add_audit_log(AuditSeverity.NORMAL, user, msg, package.get_url("packages.view"), package)
2021-02-02 18:29:03 +01:00
db.session.commit()
2022-02-02 02:29:14 +01:00
if is_cover_image:
package.cover_image = ss
db.session.commit()
return ss
2021-02-02 18:09:25 +01:00
def do_order_screenshots(_user: User, package: Package, order: [any]):
lookup = {}
for screenshot in package.screenshots.all():
lookup[screenshot.id] = screenshot
counter = 1
for ss_id in order:
2021-02-02 18:09:25 +01:00
try:
lookup[int(ss_id)].order = counter
2021-02-02 18:09:25 +01:00
counter += 1
2023-06-18 23:21:37 +02:00
except KeyError:
raise LogicError(400, "Unable to find screenshot with id={}".format(ss_id))
2023-06-18 23:21:37 +02:00
except (ValueError, TypeError):
raise LogicError(400, "Invalid id, not a number: {}".format(json.dumps(ss_id)))
2021-02-02 18:09:25 +01:00
db.session.commit()
2022-02-02 02:08:01 +01:00
def do_set_cover_image(_user: User, package: Package, cover_image):
try:
cover_image = int(cover_image)
2023-06-18 23:21:37 +02:00
except (ValueError, TypeError):
2022-02-02 02:08:01 +01:00
raise LogicError(400, "Invalid id, not a number: {}".format(json.dumps(cover_image)))
for screenshot in package.screenshots.all():
if screenshot.id == cover_image:
package.cover_image = screenshot
db.session.commit()
return
raise LogicError(400, "Unable to find screenshot")