summaryrefslogtreecommitdiff
path: root/server/szurubooru/func
diff options
context:
space:
mode:
Diffstat (limited to 'server/szurubooru/func')
-rw-r--r--server/szurubooru/func/auth.py8
-rw-r--r--server/szurubooru/func/image_hash.py6
-rw-r--r--server/szurubooru/func/images.py9
-rw-r--r--server/szurubooru/func/mime.py14
-rw-r--r--server/szurubooru/func/net.py18
-rw-r--r--server/szurubooru/func/util.py6
6 files changed, 40 insertions, 21 deletions
diff --git a/server/szurubooru/func/auth.py b/server/szurubooru/func/auth.py
index d013775..17d25f7 100644
--- a/server/szurubooru/func/auth.py
+++ b/server/szurubooru/func/auth.py
@@ -25,7 +25,7 @@ RANK_MAP = OrderedDict(
def get_password_hash(salt: str, password: str) -> Tuple[str, int]:
- """ Retrieve argon2id password hash. """
+ """Retrieve argon2id password hash."""
return (
pwhash.argon2id.str(
(config.config["secret"] + salt + password).encode("utf8")
@@ -37,7 +37,7 @@ def get_password_hash(salt: str, password: str) -> Tuple[str, int]:
def get_sha256_legacy_password_hash(
salt: str, password: str
) -> Tuple[str, int]:
- """ Retrieve old-style sha256 password hash. """
+ """Retrieve old-style sha256 password hash."""
digest = hashlib.sha256()
digest.update(config.config["secret"].encode("utf8"))
digest.update(salt.encode("utf8"))
@@ -46,7 +46,7 @@ def get_sha256_legacy_password_hash(
def get_sha1_legacy_password_hash(salt: str, password: str) -> Tuple[str, int]:
- """ Retrieve old-style sha1 password hash. """
+ """Retrieve old-style sha1 password hash."""
digest = hashlib.sha1()
digest.update(b"1A2/$_4xVa")
digest.update(salt.encode("utf8"))
@@ -125,7 +125,7 @@ def verify_privilege(user: model.User, privilege_name: str) -> None:
def generate_authentication_token(user: model.User) -> str:
- """ Generate nonguessable challenge (e.g. links in password reminder). """
+ """Generate nonguessable challenge (e.g. links in password reminder)."""
assert user
digest = hashlib.md5()
digest.update(config.config["secret"].encode("utf8"))
diff --git a/server/szurubooru/func/image_hash.py b/server/szurubooru/func/image_hash.py
index a445e62..76d5a84 100644
--- a/server/szurubooru/func/image_hash.py
+++ b/server/szurubooru/func/image_hash.py
@@ -4,12 +4,10 @@ from datetime import datetime
from io import BytesIO
from typing import Any, Callable, List, Optional, Set, Tuple
+import HeifImagePlugin
import numpy as np
-from PIL import Image
import pillow_avif
-import pyheif
-from pyheif_pillow_opener import register_heif_opener
-register_heif_opener()
+from PIL import Image
from szurubooru import config, errors
diff --git a/server/szurubooru/func/images.py b/server/szurubooru/func/images.py
index 101bba8..e135d18 100644
--- a/server/szurubooru/func/images.py
+++ b/server/szurubooru/func/images.py
@@ -6,6 +6,9 @@ import shlex
import subprocess
from io import BytesIO
from typing import List
+
+import HeifImagePlugin
+import pillow_avif
from PIL import Image as PILImage
from szurubooru import errors
@@ -17,7 +20,7 @@ logger = logging.getLogger(__name__)
def convert_heif_to_png(content: bytes) -> bytes:
img = PILImage.open(BytesIO(content))
img_byte_arr = BytesIO()
- img.save(img_byte_arr, format='PNG')
+ img.save(img_byte_arr, format="PNG")
return img_byte_arr.getvalue()
@@ -276,10 +279,10 @@ class Image:
proc = subprocess.Popen(
cli,
stdout=subprocess.PIPE,
- stdin=subprocess.PIPE,
+ stdin=subprocess.DEVNULL,
stderr=subprocess.PIPE,
)
- out, err = proc.communicate(input=self.content)
+ out, err = proc.communicate()
if proc.returncode != 0:
logger.warning(
"Failed to execute ffmpeg command (cli=%r, err=%r)",
diff --git a/server/szurubooru/func/mime.py b/server/szurubooru/func/mime.py
index 93c096b..8fae567 100644
--- a/server/szurubooru/func/mime.py
+++ b/server/szurubooru/func/mime.py
@@ -36,9 +36,12 @@ def get_mime_type(content: bytes) -> str:
if content[0:4] == b"\x1A\x45\xDF\xA3":
return "video/webm"
- if content[4:12] in (b"ftypisom", b"ftypiso5", b"ftypmp42", b"ftypM4V "):
+ if content[4:12] in (b"ftypisom", b"ftypiso5", b"ftypiso6", b"ftypmp42", b"ftypM4V "):
return "video/mp4"
+ if content[4:12] == b"ftypqt ":
+ return "video/quicktime"
+
return "application/octet-stream"
@@ -54,6 +57,7 @@ def get_extension(mime_type: str) -> Optional[str]:
"image/heif": "heif",
"image/heic": "heic",
"video/mp4": "mp4",
+ "video/quicktime": "mov",
"video/webm": "webm",
"application/octet-stream": "dat",
}
@@ -65,7 +69,12 @@ def is_flash(mime_type: str) -> bool:
def is_video(mime_type: str) -> bool:
- return mime_type.lower() in ("application/ogg", "video/mp4", "video/webm")
+ return mime_type.lower() in (
+ "application/ogg",
+ "video/mp4",
+ "video/quicktime",
+ "video/webm",
+ )
def is_image(mime_type: str) -> bool:
@@ -88,6 +97,7 @@ def is_animated_gif(content: bytes) -> bool:
and len(re.findall(pattern, content)) > 1
)
+
def is_heif(mime_type: str) -> bool:
return mime_type.lower() in (
"image/heif",
diff --git a/server/szurubooru/func/net.py b/server/szurubooru/func/net.py
index 9dff3c4..d6aa95e 100644
--- a/server/szurubooru/func/net.py
+++ b/server/szurubooru/func/net.py
@@ -39,13 +39,20 @@ def download(url: str, use_video_downloader: bool = False) -> bytes:
length_tally = 0
try:
with urllib.request.urlopen(request) as handle:
- while (chunk := handle.read(_dl_chunk_size)) :
+ while chunk := handle.read(_dl_chunk_size):
length_tally += len(chunk)
if length_tally > config.config["max_dl_filesize"]:
- raise DownloadTooLargeError(url)
+ raise DownloadTooLargeError(
+ "Download target exceeds maximum. (%d)"
+ % (config.config["max_dl_filesize"]),
+ extra_fields={"URL": url},
+ )
content_buffer += chunk
except urllib.error.HTTPError as ex:
- raise DownloadError(url) from ex
+ raise DownloadError(
+ "Download target returned HTTP %d. (%s)" % (ex.code, ex.reason),
+ extra_fields={"URL": url},
+ ) from ex
if (
youtube_dl_error
@@ -57,7 +64,7 @@ def download(url: str, use_video_downloader: bool = False) -> bytes:
def _get_youtube_dl_content_url(url: str) -> str:
- cmd = ["youtube-dl", "--format", "best", "--no-playlist"]
+ cmd = ["yt-dlp", "--format", "best", "--no-playlist"]
if config.config["user_agent"]:
cmd.extend(["--user-agent", config.config["user_agent"]])
cmd.extend(["--get-url", url])
@@ -69,7 +76,8 @@ def _get_youtube_dl_content_url(url: str) -> str:
)
except subprocess.CalledProcessError:
raise errors.ThirdPartyError(
- "Could not extract content location from %s" % (url)
+ "Could not extract content location from URL.",
+ extra_fields={"URL": url},
) from None
diff --git a/server/szurubooru/func/util.py b/server/szurubooru/func/util.py
index eacdc2a..dc5ced0 100644
--- a/server/szurubooru/func/util.py
+++ b/server/szurubooru/func/util.py
@@ -87,12 +87,12 @@ def flip(source: Dict[Any, Any]) -> Dict[Any, Any]:
def is_valid_email(email: Optional[str]) -> bool:
- """ Return whether given email address is valid or empty. """
+ """Return whether given email address is valid or empty."""
return not email or re.match(r"^[^@]*@[^@]*\.[^@]*$", email) is not None
class dotdict(dict):
- """ dot.notation access to dictionary attributes. """
+ """dot.notation access to dictionary attributes."""
def __getattr__(self, attr: str) -> Any:
return self.get(attr)
@@ -102,7 +102,7 @@ class dotdict(dict):
def parse_time_range(value: str) -> Tuple[datetime, datetime]:
- """ Return tuple containing min/max time for given text representation. """
+ """Return tuple containing min/max time for given text representation."""
one_day = timedelta(days=1)
one_second = timedelta(seconds=1)
almost_one_day = one_day - one_second