Skip to content

Commit 6a843ce

Browse files
committed
增加/status状态页,tag参数请求增加or,总请求数持久化,增加瀑布流页面/wtf
1 parent 638a285 commit 6a843ce

File tree

11 files changed

+1271
-41
lines changed

11 files changed

+1271
-41
lines changed

backend/app/api/public/docs_page.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ def u(path: str) -> str:
4949
<head>
5050
<meta charset="utf-8" />
5151
<meta name="viewport" content="width=device-width, initial-scale=1" />
52+
<meta name="color-scheme" content="light" />
5253
<title>Random Mage Docs</title>
5354
<style>
5455
:root {{
@@ -70,6 +71,7 @@ def u(path: str) -> str:
7071
}}
7172
7273
* {{ box-sizing: border-box; }}
74+
html, body {{ height: 100%; }}
7375
body {{
7476
margin: 0;
7577
font-family: var(--sans);
@@ -336,8 +338,8 @@ def u(path: str) -> str:
336338
<tr>
337339
<td><code>included_tags</code></td>
338340
<td>
339-
必须包含的标签(AND)。可重复传参:<code>included_tags=a&amp;included_tags=b</code>。<br/>
340-
也支持用 <code>|</code> 分隔:<code>included_tags=a|b</code> 等价于同时包含 a 与 b。<br/>
341+
必须包含的标签:参数之间是 <strong>AND</strong>,单个参数内用 <code>|</code> 表示 <strong>OR</strong>。<br/>
342+
:<code>included_tags=girl|boy&amp;included_tags=white|black</code> 表示 (girl OR boy) AND (white OR black)。<br/>
341343
示例:<a href="{examples["tag_loli"]}">{examples["tag_loli"]}</a>
342344
</td>
343345
</tr>

backend/app/api/public/random.py

Lines changed: 38 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@
3030
router = APIRouter()
3131

3232
_MAX_TAG_FILTERS = 50
33+
_MAX_TAG_OR_TERMS = 20
34+
_MAX_TAG_TOTAL_TERMS = 200
3335

3436

3537
def _as_nonneg_int(value: Any) -> int:
@@ -241,22 +243,49 @@ async def random_image(
241243
if not min_explicit and min_width_i == 0 and min_height_i == 0 and min_pixels_i == 0:
242244
min_pixels_i = 1_000_000 if is_mobile else 2_000_000
243245

244-
def _parse_tags(values: list[str] | None) -> list[str]:
246+
def _parse_tag_filters(values: list[str] | None) -> list[str]:
247+
"""
248+
Tag filters support "AND of groups" where each query param is one group.
249+
250+
Examples:
251+
- included_tags=girl&included_tags=boy -> girl AND boy
252+
- included_tags=girl|boy -> girl OR boy
253+
- included_tags=girl|boy&included_tags=white|black -> (girl OR boy) AND (white OR black)
254+
"""
245255
out: list[str] = []
246256
seen: set[str] = set()
247257
for raw in values or []:
248-
for part in str(raw).split("|"):
249-
name = part.strip()
250-
if not name or name in seen:
251-
continue
252-
seen.add(name)
253-
out.append(name)
258+
expr = str(raw or "").strip()
259+
if not expr or expr in seen:
260+
continue
261+
seen.add(expr)
262+
out.append(expr)
254263
return out
255264

256-
included = _parse_tags(included_tags)
257-
excluded = _parse_tags(excluded_tags)
265+
included = _parse_tag_filters(included_tags)
266+
excluded = _parse_tag_filters(excluded_tags)
267+
268+
def _validate_tag_filters(values: list[str]) -> None:
269+
total_terms = 0
270+
for expr in values:
271+
parts: list[str] = []
272+
seen_terms: set[str] = set()
273+
for part in str(expr).split("|"):
274+
term = part.strip()
275+
if not term or term in seen_terms:
276+
continue
277+
seen_terms.add(term)
278+
parts.append(term)
279+
if len(parts) > _MAX_TAG_OR_TERMS:
280+
raise ApiError(code=ErrorCode.BAD_REQUEST, message="Too many tag terms in a group", status_code=400)
281+
total_terms += len(parts)
282+
if total_terms > _MAX_TAG_TOTAL_TERMS:
283+
raise ApiError(code=ErrorCode.BAD_REQUEST, message="Too many tag terms", status_code=400)
284+
258285
if len(included) > _MAX_TAG_FILTERS or len(excluded) > _MAX_TAG_FILTERS:
259286
raise ApiError(code=ErrorCode.BAD_REQUEST, message="Too many tag filters", status_code=400)
287+
_validate_tag_filters(included)
288+
_validate_tag_filters(excluded)
260289
if user_id is not None and int(user_id) <= 0:
261290
raise ApiError(code=ErrorCode.BAD_REQUEST, message="Unsupported user_id", status_code=400)
262291
if illust_id is not None and int(illust_id) <= 0:

0 commit comments

Comments
 (0)