mirror of
https://github.com/rr-/szurubooru.git
synced 2025-07-17 08:26:24 +00:00
Compare commits
2 Commits
c3cdf88c36
...
fb70171b17
Author | SHA1 | Date | |
---|---|---|---|
fb70171b17 | |||
0825866dce |
6
.gitignore
vendored
6
.gitignore
vendored
@ -13,3 +13,9 @@ server/**/lib/
|
||||
server/**/bin/
|
||||
server/**/pyvenv.cfg
|
||||
__pycache__/
|
||||
|
||||
# Developer Tools
|
||||
.vscode/
|
||||
.idea/
|
||||
*.sublime-project
|
||||
*.sublime-workspace
|
||||
|
@ -7,7 +7,7 @@ scrubbing](https://sjp.pwn.pl/sjp/;2527372). It is pronounced as *shoorubooru*.
|
||||
|
||||
## Features
|
||||
|
||||
- Post content: images (JPG, PNG, GIF, animated GIF), videos (MP4, WEBM), Flash animations
|
||||
- Post content: images (JPG, PNG, GIF, animated GIF), videos (MP4, WEBM), Flash animations, project files (PSD)
|
||||
- Ability to retrieve web video content using [yt-dlp](https://github.com/yt-dlp/yt-dlp)
|
||||
- Post comments
|
||||
- Post notes / annotations, including arbitrary polygons
|
||||
|
@ -1,7 +1,11 @@
|
||||
<div class='post-content post-type-<%- ctx.post.type %>'>
|
||||
<% if (['image', 'animation'].includes(ctx.post.type)) { %>
|
||||
|
||||
<img class='resize-listener' alt='' src='<%- ctx.post.contentUrl %>'/>
|
||||
<% if (ctx.post.mimeType === 'image/vnd.adobe.photoshop') { %>
|
||||
<img class='resize-listener' alt='' src='<%- ctx.post.thumbnailUrl %>'/>
|
||||
<% } else { %>
|
||||
<img class='resize-listener' alt='' src='<%- ctx.post.contentUrl %>'/>
|
||||
<% } %>
|
||||
|
||||
<% } else if (ctx.post.type === 'flash') { %>
|
||||
|
||||
|
@ -13,6 +13,7 @@
|
||||
'image/avif': 'AVIF',
|
||||
'image/heif': 'HEIF',
|
||||
'image/heic': 'HEIC',
|
||||
'image/vnd.adobe.photoshop': 'PSD',
|
||||
'video/webm': 'WEBM',
|
||||
'video/mp4': 'MPEG-4',
|
||||
'video/quicktime': 'MOV',
|
||||
|
@ -20,6 +20,7 @@ function _mimeTypeToPostType(mimeType) {
|
||||
"image/avif": "image",
|
||||
"image/heif": "image",
|
||||
"image/heic": "image",
|
||||
"image/vnd.adobe.photoshop": "image",
|
||||
"video/mp4": "video",
|
||||
"video/webm": "video",
|
||||
"video/quicktime": "video",
|
||||
@ -165,7 +166,7 @@ class PostUploadView extends events.EventTarget {
|
||||
this._contentInputNode,
|
||||
{
|
||||
extraText:
|
||||
"Allowed extensions: .jpg, .png, .gif, .webm, .mp4, .swf, .avif, .heif, .heic",
|
||||
"Allowed extensions: .jpg, .png, .gif, .webm, .mp4, .swf, .avif, .heif, .heic, .psd",
|
||||
allowUrls: true,
|
||||
allowMultiple: true,
|
||||
lock: false,
|
||||
|
@ -1,9 +1,12 @@
|
||||
ARG ALPINE_VERSION=3.13
|
||||
ARG ALPINE_VERSION=3.16
|
||||
|
||||
|
||||
FROM alpine:$ALPINE_VERSION as prereqs
|
||||
#######################################
|
||||
# Base Stage (prereqs)
|
||||
#######################################
|
||||
FROM alpine:$ALPINE_VERSION AS prereqs
|
||||
WORKDIR /opt/app
|
||||
|
||||
# Install system dependencies (Python, development packages, and runtime libraries)
|
||||
RUN apk --no-cache add \
|
||||
python3 \
|
||||
python3-dev \
|
||||
@ -13,31 +16,47 @@ RUN apk --no-cache add \
|
||||
libheif-dev \
|
||||
libavif \
|
||||
libavif-dev \
|
||||
freetype-dev \
|
||||
ffmpeg \
|
||||
lapack \
|
||||
lapack-dev \
|
||||
# from requirements.txt:
|
||||
py3-yaml \
|
||||
py3-psycopg2 \
|
||||
py3-sqlalchemy \
|
||||
py3-certifi \
|
||||
py3-numpy \
|
||||
py3-pillow \
|
||||
py3-pynacl \
|
||||
py3-tz \
|
||||
py3-pyrfc3339
|
||||
|
||||
# Install pip-only packages, using a wheel to avoid building scikit-image
|
||||
RUN pip3 install --no-cache-dir wheel
|
||||
|
||||
RUN pip3 install --no-cache-dir --disable-pip-version-check \
|
||||
--extra-index-url https://alpine-wheels.github.io/index \
|
||||
"aggdraw==1.3.12" \
|
||||
"alembic>=0.8.5" \
|
||||
"attrs==25.1.0" \
|
||||
"coloredlogs==5.0" \
|
||||
"pyheif==0.6.1" \
|
||||
"heif-image-plugin>=0.3.2" \
|
||||
yt-dlp \
|
||||
"pillow-avif-plugin~=1.1.0"
|
||||
"pillow>=6.1.0" \
|
||||
"pillow-avif-plugin~=1.1.0" \
|
||||
"psd-tools==1.10.4" \
|
||||
"numpy==1.21.6" \
|
||||
"scikit-image==0.19.3" \
|
||||
"scipy==1.8.0" \
|
||||
"sqlalchemy==1.3.21"
|
||||
|
||||
RUN apk --no-cache del py3-pip
|
||||
|
||||
COPY ./ /opt/app/
|
||||
RUN rm -rf /opt/app/szurubooru/tests
|
||||
|
||||
|
||||
FROM --platform=$BUILDPLATFORM prereqs as testing
|
||||
#######################################
|
||||
# Testing Stage
|
||||
#######################################
|
||||
FROM --platform=$BUILDPLATFORM prereqs AS testing
|
||||
WORKDIR /opt/app
|
||||
|
||||
RUN apk --no-cache add \
|
||||
@ -60,8 +79,10 @@ USER app
|
||||
ENTRYPOINT ["pytest", "--tb=short"]
|
||||
CMD ["szurubooru/"]
|
||||
|
||||
|
||||
FROM prereqs as release
|
||||
#######################################
|
||||
# Release Stage
|
||||
#######################################
|
||||
FROM prereqs AS release
|
||||
WORKDIR /opt/app
|
||||
|
||||
ARG PUID=1000
|
||||
|
@ -1,15 +1,20 @@
|
||||
aggdraw==1.3.12
|
||||
alembic>=0.8.5
|
||||
attrs==25.1.0
|
||||
certifi>=2017.11.5
|
||||
coloredlogs==5.0
|
||||
heif-image-plugin==0.3.2
|
||||
numpy>=1.8.2
|
||||
heif-image-plugin>=0.3.2
|
||||
numpy>=1.21.6
|
||||
pillow-avif-plugin~=1.1.0
|
||||
pillow>=4.3.0
|
||||
pillow>=6.1.0
|
||||
psd-tools==1.10.4
|
||||
psycopg2-binary>=2.6.1
|
||||
pyheif==0.6.1
|
||||
pynacl>=1.2.1
|
||||
pyRFC3339>=1.0
|
||||
pytz>=2018.3
|
||||
pyyaml>=3.11
|
||||
SQLAlchemy>=1.0.12, <1.4
|
||||
scikit-image==0.19.3
|
||||
scipy==1.8.0
|
||||
SQLAlchemy==1.3.21
|
||||
yt-dlp
|
||||
|
@ -7,13 +7,14 @@ import subprocess
|
||||
from io import BytesIO
|
||||
from typing import List
|
||||
|
||||
import HeifImagePlugin
|
||||
import pillow_avif
|
||||
from PIL import Image as PILImage
|
||||
|
||||
from psd_tools import PSDImage
|
||||
|
||||
from szurubooru import errors
|
||||
from szurubooru.func import mime, util
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@ -24,6 +25,15 @@ def convert_heif_to_png(content: bytes) -> bytes:
|
||||
return img_byte_arr.getvalue()
|
||||
|
||||
|
||||
|
||||
def convert_psd_to_png(content: bytes) -> bytes:
|
||||
psd_object = PSDImage.open(BytesIO(content))
|
||||
img = psd_object.composite()
|
||||
img_byte_arr = BytesIO()
|
||||
img.save(img_byte_arr, format="PNG")
|
||||
return img_byte_arr.getvalue()
|
||||
|
||||
|
||||
class Image:
|
||||
def __init__(self, content: bytes) -> None:
|
||||
self.content = content
|
||||
@ -265,10 +275,13 @@ class Image:
|
||||
get_logs: bool = False,
|
||||
) -> bytes:
|
||||
mime_type = mime.get_mime_type(self.content)
|
||||
# FFmpeg does not support HEIF or PSD.
|
||||
# https://trac.ffmpeg.org/ticket/6521
|
||||
# https://ffmpeg.org/pipermail/ffmpeg-devel/2016-July/196477.html
|
||||
if mime.is_heif(mime_type):
|
||||
# FFmpeg does not support HEIF.
|
||||
# https://trac.ffmpeg.org/ticket/6521
|
||||
self.content = convert_heif_to_png(self.content)
|
||||
elif mime_type == "image/vnd.adobe.photoshop":
|
||||
self.content = convert_psd_to_png(self.content)
|
||||
extension = mime.get_extension(mime_type)
|
||||
assert extension
|
||||
with util.create_temp_file(suffix="." + extension) as handle:
|
||||
|
@ -33,6 +33,9 @@ def get_mime_type(content: bytes) -> str:
|
||||
if content[4:12] in (b"ftypheic", b"ftypheix"):
|
||||
return "image/heic"
|
||||
|
||||
if content[0:4] == b"8BPS":
|
||||
return "image/vnd.adobe.photoshop"
|
||||
|
||||
if content[0:4] == b"\x1A\x45\xDF\xA3":
|
||||
return "video/webm"
|
||||
|
||||
@ -56,6 +59,7 @@ def get_extension(mime_type: str) -> Optional[str]:
|
||||
"image/avif": "avif",
|
||||
"image/heif": "heif",
|
||||
"image/heic": "heic",
|
||||
"image/vnd.adobe.photoshop": "psd",
|
||||
"video/mp4": "mp4",
|
||||
"video/quicktime": "mov",
|
||||
"video/webm": "webm",
|
||||
@ -87,6 +91,7 @@ def is_image(mime_type: str) -> bool:
|
||||
"image/avif",
|
||||
"image/heif",
|
||||
"image/heic",
|
||||
"image/vnd.adobe.photoshop",
|
||||
)
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user