Merge branch 'master' into better-links

This commit is contained in:
Neo 2024-04-26 22:16:37 +02:00 committed by GitHub
commit 4f9d46e1c2
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 105 additions and 18 deletions

View file

@ -8,7 +8,7 @@ scrubbing](https://sjp.pwn.pl/sjp/;2527372). It is pronounced as *shoorubooru*.
## Features ## 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
- Ability to retrieve web video content using [youtube-dl](https://github.com/ytdl-org/youtube-dl) - Ability to retrieve web video content using [yt-dlp](https://github.com/yt-dlp/yt-dlp)
- Post comments - Post comments
- Post notes / annotations, including arbitrary polygons - Post notes / annotations, including arbitrary polygons
- Rich JSON REST API ([see documentation](doc/API.md)) - Rich JSON REST API ([see documentation](doc/API.md))

View file

@ -127,6 +127,10 @@ $comment-border-color = #DDD
color: mix($main-color, $inactive-link-color-darktheme) color: mix($main-color, $inactive-link-color-darktheme)
.comment-content .comment-content
p
word-wrap: normal
word-break: break-all
ul, ol ul, ol
list-style-position: inside list-style-position: inside
margin: 1em 0 margin: 1em 0

View file

@ -300,10 +300,10 @@ a .access-key
background-size: 20px 20px background-size: 20px 20px
img img
opacity: 0 opacity: 0
width: inherit width: 100%
height: 100% height: 100%
video video
width: inherit width: 100%
height: 100% height: 100%
.flexbox-dummy .flexbox-dummy

View file

@ -43,6 +43,8 @@ class PoolListController {
this._headerView.addEventListener( this._headerView.addEventListener(
"submit", "submit",
(e) => this._evtSubmit(e), (e) => this._evtSubmit(e),
);
this._headerView.addEventListener(
"navigate", "navigate",
(e) => this._evtNavigate(e) (e) => this._evtNavigate(e)
); );

View file

@ -54,7 +54,7 @@
- [Deleting pool category](#deleting-pool-category) - [Deleting pool category](#deleting-pool-category)
- [Setting default pool category](#setting-default-pool-category) - [Setting default pool category](#setting-default-pool-category)
- Pools - Pools
- [Listing pools](#listing-pool) - [Listing pools](#listing-pools)
- [Creating pool](#creating-pool) - [Creating pool](#creating-pool)
- [Updating pool](#updating-pool) - [Updating pool](#updating-pool)
- [Getting pool](#getting-pool) - [Getting pool](#getting-pool)
@ -165,9 +165,9 @@ way. The files, however, should be passed as regular fields appended with a
accepts a file named `content`, the client should pass accepts a file named `content`, the client should pass
`{"contentUrl":"http://example.com/file.jpg"}` as a part of the JSON message `{"contentUrl":"http://example.com/file.jpg"}` as a part of the JSON message
body. When creating or updating post content using this method, the server can body. When creating or updating post content using this method, the server can
also be configured to employ [youtube-dl](https://github.com/ytdl-org/youtube-dl) also be configured to employ [yt-dlp](https://github.com/yt-dlp/yt-dlp) to
to download content from popular sites such as youtube, gfycat, etc. Access to download content from popular sites such as youtube, gfycat, etc. Access to
youtube-dl can be configured with the `'uploads:use_downloader'` permission yt-dlp can be configured with the `'uploads:use_downloader'` permission
Finally, in some cases the user might want to reuse one file between the Finally, in some cases the user might want to reuse one file between the
requests to save the bandwidth (for example, reverse search + consecutive requests to save the bandwidth (for example, reverse search + consecutive
@ -323,7 +323,7 @@ data.
{ {
"name": <name>, "name": <name>,
"color": <color>, "color": <color>,
"order": <order> // optional "order": <order>
} }
``` ```
@ -1389,7 +1389,7 @@ data.
## Creating pool ## Creating pool
- **Request** - **Request**
`POST /pools/create` `POST /pool`
- **Input** - **Input**
@ -2491,7 +2491,7 @@ One file together with its metadata posted to the site.
## Micro post ## Micro post
**Description** **Description**
A [post resource](#post) stripped down to `name` and `thumbnailUrl` fields. A [post resource](#post) stripped down to `id` and `thumbnailUrl` fields.
## Note ## Note
**Description** **Description**

View file

@ -23,15 +23,15 @@ RUN apk --no-cache add \
py3-pillow \ py3-pillow \
py3-pynacl \ py3-pynacl \
py3-tz \ py3-tz \
py3-pyrfc3339 \ py3-pyrfc3339
&& pip3 install --no-cache-dir --disable-pip-version-check \ RUN pip3 install --no-cache-dir --disable-pip-version-check \
"alembic>=0.8.5" \ "alembic>=0.8.5" \
"coloredlogs==5.0" \ "coloredlogs==5.0" \
"pyheif==0.6.1" \ "pyheif==0.6.1" \
"heif-image-plugin>=0.3.2" \ "heif-image-plugin>=0.3.2" \
youtube_dl \ yt-dlp \
"pillow-avif-plugin>=1.1.0" \ "pillow-avif-plugin~=1.1.0"
&& apk --no-cache del py3-pip RUN apk --no-cache del py3-pip
COPY ./ /opt/app/ COPY ./ /opt/app/
RUN rm -rf /opt/app/szurubooru/tests RUN rm -rf /opt/app/szurubooru/tests

View file

@ -3,7 +3,7 @@ certifi>=2017.11.5
coloredlogs==5.0 coloredlogs==5.0
heif-image-plugin==0.3.2 heif-image-plugin==0.3.2
numpy>=1.8.2 numpy>=1.8.2
pillow-avif-plugin>=1.1.0 pillow-avif-plugin~=1.1.0
pillow>=4.3.0 pillow>=4.3.0
psycopg2-binary>=2.6.1 psycopg2-binary>=2.6.1
pyheif==0.6.1 pyheif==0.6.1
@ -12,4 +12,4 @@ pyRFC3339>=1.0
pytz>=2018.3 pytz>=2018.3
pyyaml>=3.11 pyyaml>=3.11
SQLAlchemy>=1.0.12, <1.4 SQLAlchemy>=1.0.12, <1.4
youtube_dl yt-dlp

View file

@ -64,7 +64,7 @@ def download(url: str, use_video_downloader: bool = False) -> bytes:
def _get_youtube_dl_content_url(url: str) -> str: 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"]: if config.config["user_agent"]:
cmd.extend(["--user-agent", config.config["user_agent"]]) cmd.extend(["--user-agent", config.config["user_agent"]])
cmd.extend(["--get-url", url]) cmd.extend(["--get-url", url])

View file

@ -122,6 +122,34 @@ def _pool_filter(
)(query, criterion, negated) )(query, criterion, negated)
def _category_filter(
query: SaQuery, criterion: Optional[criteria.BaseCriterion], negated: bool
) -> SaQuery:
assert criterion
# Step 1. find the id for the category
q1 = db.session.query(model.TagCategory.tag_category_id).filter(
model.TagCategory.name == criterion.value
)
# Step 2. find the tags with that category
q2 = db.session.query(model.Tag.tag_id).filter(
model.Tag.category_id.in_(q1)
)
# Step 3. find all posts that have at least one of those tags
q3 = db.session.query(model.PostTag.post_id).filter(
model.PostTag.tag_id.in_(q2)
)
# Step 4. profit
expr = model.Post.post_id.in_(q3)
if negated:
expr = ~expr
return query.filter(expr)
class PostSearchConfig(BaseSearchConfig): class PostSearchConfig(BaseSearchConfig):
def __init__(self) -> None: def __init__(self) -> None:
self.user = None # type: Optional[model.User] self.user = None # type: Optional[model.User]
@ -349,6 +377,7 @@ class PostSearchConfig(BaseSearchConfig):
), ),
), ),
(["pool"], _pool_filter), (["pool"], _pool_filter),
(["category"], _category_filter),
] ]
) )

View file

@ -863,3 +863,55 @@ def test_tumbleweed(
db.session.flush() db.session.flush()
verify_unpaged("special:tumbleweed", [4]) verify_unpaged("special:tumbleweed", [4])
verify_unpaged("-special:tumbleweed", [1, 2, 3]) verify_unpaged("-special:tumbleweed", [1, 2, 3])
@pytest.mark.parametrize(
"input,expected_post_ids",
[
("category:cat1", [1, 2, 3]),
("category:cat2", [3, 4]),
],
)
def test_search_by_tag_category(
verify_unpaged,
post_factory,
tag_factory,
tag_category_factory,
input,
expected_post_ids,
):
cat1 = tag_category_factory(name="cat1")
cat2 = tag_category_factory(name="cat2")
tag1 = tag_factory(names=["t1"], category=cat1)
tag2 = tag_factory(names=["t2"], category=cat1)
tag3 = tag_factory(names=["t3"], category=cat2)
post1 = post_factory(id=1)
post1.tags.append(tag1)
post2 = post_factory(id=2)
post2.tags.append(tag2)
post3 = post_factory(id=3)
post3.tags.append(tag1)
post3.tags.append(tag3)
post4 = post_factory(id=4)
post4.tags.append(tag3)
post5 = post_factory(id=5)
db.session.add_all(
[
tag1,
tag2,
tag3,
post1,
post2,
post3,
post4,
post5,
]
)
db.session.flush()
verify_unpaged(input, expected_post_ids)