Merge branch 'master' into better-links
This commit is contained in:
commit
4f9d46e1c2
10 changed files with 105 additions and 18 deletions
|
@ -8,7 +8,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
|
||||
- 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 notes / annotations, including arbitrary polygons
|
||||
- Rich JSON REST API ([see documentation](doc/API.md))
|
||||
|
|
|
@ -127,6 +127,10 @@ $comment-border-color = #DDD
|
|||
color: mix($main-color, $inactive-link-color-darktheme)
|
||||
|
||||
.comment-content
|
||||
p
|
||||
word-wrap: normal
|
||||
word-break: break-all
|
||||
|
||||
ul, ol
|
||||
list-style-position: inside
|
||||
margin: 1em 0
|
||||
|
|
|
@ -300,10 +300,10 @@ a .access-key
|
|||
background-size: 20px 20px
|
||||
img
|
||||
opacity: 0
|
||||
width: inherit
|
||||
width: 100%
|
||||
height: 100%
|
||||
video
|
||||
width: inherit
|
||||
width: 100%
|
||||
height: 100%
|
||||
|
||||
.flexbox-dummy
|
||||
|
|
|
@ -43,6 +43,8 @@ class PoolListController {
|
|||
this._headerView.addEventListener(
|
||||
"submit",
|
||||
(e) => this._evtSubmit(e),
|
||||
);
|
||||
this._headerView.addEventListener(
|
||||
"navigate",
|
||||
(e) => this._evtNavigate(e)
|
||||
);
|
||||
|
|
14
doc/API.md
14
doc/API.md
|
@ -54,7 +54,7 @@
|
|||
- [Deleting pool category](#deleting-pool-category)
|
||||
- [Setting default pool category](#setting-default-pool-category)
|
||||
- Pools
|
||||
- [Listing pools](#listing-pool)
|
||||
- [Listing pools](#listing-pools)
|
||||
- [Creating pool](#creating-pool)
|
||||
- [Updating pool](#updating-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
|
||||
`{"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
|
||||
also be configured to employ [youtube-dl](https://github.com/ytdl-org/youtube-dl)
|
||||
to download content from popular sites such as youtube, gfycat, etc. Access to
|
||||
youtube-dl can be configured with the `'uploads:use_downloader'` permission
|
||||
also be configured to employ [yt-dlp](https://github.com/yt-dlp/yt-dlp) to
|
||||
download content from popular sites such as youtube, gfycat, etc. Access to
|
||||
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
|
||||
requests to save the bandwidth (for example, reverse search + consecutive
|
||||
|
@ -323,7 +323,7 @@ data.
|
|||
{
|
||||
"name": <name>,
|
||||
"color": <color>,
|
||||
"order": <order> // optional
|
||||
"order": <order>
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -1389,7 +1389,7 @@ data.
|
|||
## Creating pool
|
||||
- **Request**
|
||||
|
||||
`POST /pools/create`
|
||||
`POST /pool`
|
||||
|
||||
- **Input**
|
||||
|
||||
|
@ -2491,7 +2491,7 @@ One file together with its metadata posted to the site.
|
|||
## Micro post
|
||||
**Description**
|
||||
|
||||
A [post resource](#post) stripped down to `name` and `thumbnailUrl` fields.
|
||||
A [post resource](#post) stripped down to `id` and `thumbnailUrl` fields.
|
||||
|
||||
## Note
|
||||
**Description**
|
||||
|
|
|
@ -23,15 +23,15 @@ RUN apk --no-cache add \
|
|||
py3-pillow \
|
||||
py3-pynacl \
|
||||
py3-tz \
|
||||
py3-pyrfc3339 \
|
||||
&& pip3 install --no-cache-dir --disable-pip-version-check \
|
||||
py3-pyrfc3339
|
||||
RUN pip3 install --no-cache-dir --disable-pip-version-check \
|
||||
"alembic>=0.8.5" \
|
||||
"coloredlogs==5.0" \
|
||||
"pyheif==0.6.1" \
|
||||
"heif-image-plugin>=0.3.2" \
|
||||
youtube_dl \
|
||||
"pillow-avif-plugin>=1.1.0" \
|
||||
&& apk --no-cache del py3-pip
|
||||
yt-dlp \
|
||||
"pillow-avif-plugin~=1.1.0"
|
||||
RUN apk --no-cache del py3-pip
|
||||
|
||||
COPY ./ /opt/app/
|
||||
RUN rm -rf /opt/app/szurubooru/tests
|
||||
|
|
|
@ -3,7 +3,7 @@ certifi>=2017.11.5
|
|||
coloredlogs==5.0
|
||||
heif-image-plugin==0.3.2
|
||||
numpy>=1.8.2
|
||||
pillow-avif-plugin>=1.1.0
|
||||
pillow-avif-plugin~=1.1.0
|
||||
pillow>=4.3.0
|
||||
psycopg2-binary>=2.6.1
|
||||
pyheif==0.6.1
|
||||
|
@ -12,4 +12,4 @@ pyRFC3339>=1.0
|
|||
pytz>=2018.3
|
||||
pyyaml>=3.11
|
||||
SQLAlchemy>=1.0.12, <1.4
|
||||
youtube_dl
|
||||
yt-dlp
|
||||
|
|
|
@ -64,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])
|
||||
|
|
|
@ -122,6 +122,34 @@ def _pool_filter(
|
|||
)(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):
|
||||
def __init__(self) -> None:
|
||||
self.user = None # type: Optional[model.User]
|
||||
|
@ -349,6 +377,7 @@ class PostSearchConfig(BaseSearchConfig):
|
|||
),
|
||||
),
|
||||
(["pool"], _pool_filter),
|
||||
(["category"], _category_filter),
|
||||
]
|
||||
)
|
||||
|
||||
|
|
|
@ -863,3 +863,55 @@ def test_tumbleweed(
|
|||
db.session.flush()
|
||||
verify_unpaged("special:tumbleweed", [4])
|
||||
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)
|
||||
|
|
Loading…
Reference in a new issue