summaryrefslogtreecommitdiff
path: root/server/szurubooru/search/configs/post_search_config.py
diff options
context:
space:
mode:
Diffstat (limited to 'server/szurubooru/search/configs/post_search_config.py')
-rw-r--r--server/szurubooru/search/configs/post_search_config.py498
1 files changed, 278 insertions, 220 deletions
diff --git a/server/szurubooru/search/configs/post_search_config.py b/server/szurubooru/search/configs/post_search_config.py
index 9869843..9065539 100644
--- a/server/szurubooru/search/configs/post_search_config.py
+++ b/server/szurubooru/search/configs/post_search_config.py
@@ -3,7 +3,7 @@ from typing import Any, Dict, Optional, Tuple
import sqlalchemy as sa
from szurubooru import db, errors, model
-from szurubooru.func import metrics, util
+from szurubooru.func import auth, metrics, util
from szurubooru.search import criteria, tokens
from szurubooru.search.configs import util as search_util
from szurubooru.search.configs.base_search_config import (
@@ -169,15 +169,17 @@ def _create_metric_num_filter(name: str):
pm = sa.orm.aliased(model.PostMetric)
expr = t.name == name
expr = expr & search_util.apply_num_criterion_to_column(
- pm.value, criterion, search_util.float_transformer)
+ pm.value, criterion, search_util.float_transformer
+ )
if negated:
expr = ~expr
ret = (
- query
- .join(pm, pm.post_id == model.Post.post_id)
+ query.join(pm, pm.post_id == model.Post.post_id)
.join(t, t.tag_id == pm.tag_id)
- .filter(expr))
+ .filter(expr)
+ )
return ret
+
return wrapper
@@ -189,13 +191,15 @@ def _metric_presence_filter(
assert criterion
t = sa.orm.aliased(model.TagName)
tag_name_filter = search_util.apply_str_criterion_to_column(
- t.name, criterion)
+ t.name, criterion
+ )
pm = sa.orm.aliased(model.PostMetric)
subquery = (
db.session.query(pm.post_id)
.join(t, t.tag_id == pm.tag_id)
.filter(tag_name_filter)
- .subquery())
+ .subquery()
+ )
post_filter = model.Post.post_id.in_(subquery)
if negated:
post_filter = ~post_filter
@@ -210,7 +214,8 @@ def _create_metric_sort_column(metric_name: str):
.filter(pm.post_id == model.Post.post_id)
.join(t, t.tag_id == pm.tag_id)
.filter(t.name == metric_name)
- .as_scalar())
+ .as_scalar()
+ )
return ret
@@ -242,6 +247,15 @@ def _category_filter(
return query.filter(expr)
+def _safety_filter(
+ query: SaQuery, criterion: Optional[criteria.BaseCriterion], negated: bool
+) -> SaQuery:
+ assert criterion
+ return search_util.create_str_filter(
+ model.Post.safety, _safety_transformer
+ )(query, criterion, negated)
+
+
class PostSearchConfig(BaseSearchConfig):
def __init__(self) -> None:
self.user = None # type: Optional[model.User]
@@ -306,6 +320,17 @@ class PostSearchConfig(BaseSearchConfig):
return db.session.query(model.Post)
def finalize_query(self, query: SaQuery) -> SaQuery:
+ if self.user and not auth.has_privilege(
+ self.user, "posts:list:unsafe"
+ ):
+ # exclude unsafe posts:
+ query = _safety_filter(
+ query,
+ criteria.PlainCriterion(
+ model.Post.SAFETY_UNSAFE, model.Post.SAFETY_UNSAFE
+ ),
+ negated=True,
+ )
return query.order_by(model.Post.post_id.desc())
@property
@@ -324,234 +349,267 @@ class PostSearchConfig(BaseSearchConfig):
@property
def named_filters(self) -> Dict[str, Filter]:
- filters = {"metric-" + name: _create_metric_num_filter(name)
- for name in self.all_metric_names}
- filters.update(util.unalias_dict(
- [
- (["id"], search_util.create_num_filter(model.Post.post_id)),
- (
- ["tag"],
- search_util.create_subquery_filter(
- model.Post.post_id,
- model.PostTag.post_id,
- model.TagName.name,
- search_util.create_str_filter,
- lambda subquery: subquery.join(model.Tag).join(
- model.TagName
+ filters = {
+ "metric-" + name: _create_metric_num_filter(name)
+ for name in self.all_metric_names
+ }
+ filters.update(
+ util.unalias_dict(
+ [
+ (
+ ["id"],
+ search_util.create_num_filter(model.Post.post_id),
+ ),
+ (
+ ["tag"],
+ search_util.create_subquery_filter(
+ model.Post.post_id,
+ model.PostTag.post_id,
+ model.TagName.name,
+ search_util.create_str_filter,
+ lambda subquery: subquery.join(model.Tag).join(
+ model.TagName
+ ),
),
),
- ),
- (["metric"], _metric_presence_filter),
- (["score"], search_util.create_num_filter(model.Post.score)),
- (["uploader", "upload", "submit"], _user_filter),
- (
- ["comment"],
- search_util.create_subquery_filter(
- model.Post.post_id,
- model.Comment.post_id,
- model.User.name,
- search_util.create_str_filter,
- lambda subquery: subquery.join(model.User),
+ (["metric"], _metric_presence_filter),
+ (
+ ["score"],
+ search_util.create_num_filter(model.Post.score),
),
- ),
- (
- ["fav"],
- search_util.create_subquery_filter(
- model.Post.post_id,
- model.PostFavorite.post_id,
- model.User.name,
- search_util.create_str_filter,
- lambda subquery: subquery.join(model.User),
+ (["uploader", "upload", "submit"], _user_filter),
+ (
+ ["comment"],
+ search_util.create_subquery_filter(
+ model.Post.post_id,
+ model.Comment.post_id,
+ model.User.name,
+ search_util.create_str_filter,
+ lambda subquery: subquery.join(model.User),
+ ),
),
- ),
- (["liked"], _create_score_filter(1)),
- (["disliked"], _create_score_filter(-1)),
- (
- ["source"],
- search_util.create_str_filter(
- model.Post.source, _source_transformer
+ (
+ ["fav"],
+ search_util.create_subquery_filter(
+ model.Post.post_id,
+ model.PostFavorite.post_id,
+ model.User.name,
+ search_util.create_str_filter,
+ lambda subquery: subquery.join(model.User),
+ ),
),
- ),
- (
- ["tag-count"],
- search_util.create_num_filter(model.Post.tag_count),
- ),
- (
- ["comment-count"],
- search_util.create_num_filter(model.Post.comment_count),
- ),
- (
- ["fav-count"],
- search_util.create_num_filter(model.Post.favorite_count),
- ),
- (
- ["note-count"],
- search_util.create_num_filter(model.Post.note_count),
- ),
- (
- ["relation-count"],
- search_util.create_num_filter(model.Post.relation_count),
- ),
- (
- ["feature-count"],
- search_util.create_num_filter(model.Post.feature_count),
- ),
- (
- ["type"],
- search_util.create_str_filter(
- model.Post.type, _type_transformer
+ (["liked"], _create_score_filter(1)),
+ (["disliked"], _create_score_filter(-1)),
+ (
+ ["source"],
+ search_util.create_str_filter(
+ model.Post.source, _source_transformer
+ ),
),
- ),
- (
- ["content-checksum", "sha1"],
- search_util.create_str_filter(model.Post.checksum),
- ),
- (
- ["md5"],
- search_util.create_str_filter(model.Post.checksum_md5),
- ),
- (
- ["file-size"],
- search_util.create_num_filter(model.Post.file_size),
- ),
- (
- ["image-width", "width"],
- search_util.create_num_filter(model.Post.canvas_width),
- ),
- (
- ["image-height", "height"],
- search_util.create_num_filter(model.Post.canvas_height),
- ),
- (
- ["image-area", "area"],
- search_util.create_num_filter(model.Post.canvas_area),
- ),
- (
- ["image-aspect-ratio", "image-ar", "aspect-ratio", "ar"],
- search_util.create_num_filter(
- model.Post.canvas_aspect_ratio,
- transformer=search_util.float_transformer,
+ (
+ ["tag-count"],
+ search_util.create_num_filter(model.Post.tag_count),
),
- ),
- (
- ["creation-date", "creation-time", "date", "time"],
- search_util.create_date_filter(model.Post.creation_time),
- ),
- (
- [
- "last-edit-date",
- "last-edit-time",
- "edit-date",
- "edit-time",
- ],
- search_util.create_date_filter(model.Post.last_edit_time),
- ),
- (
- ["comment-date", "comment-time"],
- search_util.create_date_filter(
- model.Post.last_comment_creation_time
+ (
+ ["comment-count"],
+ search_util.create_num_filter(
+ model.Post.comment_count
+ ),
),
- ),
- (
- ["fav-date", "fav-time"],
- search_util.create_date_filter(
- model.Post.last_favorite_time
+ (
+ ["fav-count"],
+ search_util.create_num_filter(
+ model.Post.favorite_count
+ ),
),
- ),
- (
- ["feature-date", "feature-time"],
- search_util.create_date_filter(
- model.Post.last_feature_time
+ (
+ ["note-count"],
+ search_util.create_num_filter(model.Post.note_count),
),
- ),
- (
- ["safety", "rating"],
- search_util.create_str_filter(
- model.Post.safety, _safety_transformer
+ (
+ ["relation-count"],
+ search_util.create_num_filter(
+ model.Post.relation_count
+ ),
),
- ),
- (["note-text"], _note_filter),
- (
- ["flag"],
- search_util.create_str_filter(
- model.Post.flags_string, _flag_transformer
+ (
+ ["feature-count"],
+ search_util.create_num_filter(
+ model.Post.feature_count
+ ),
),
- ),
- (["pool"], _pool_filter),
- (["similar"], _similar_filter),
- (["category"], _category_filter),
- ]
- ))
+ (
+ ["type"],
+ search_util.create_str_filter(
+ model.Post.type, _type_transformer
+ ),
+ ),
+ (
+ ["content-checksum", "sha1"],
+ search_util.create_str_filter(model.Post.checksum),
+ ),
+ (
+ ["md5"],
+ search_util.create_str_filter(model.Post.checksum_md5),
+ ),
+ (
+ ["file-size"],
+ search_util.create_num_filter(model.Post.file_size),
+ ),
+ (
+ ["image-width", "width"],
+ search_util.create_num_filter(model.Post.canvas_width),
+ ),
+ (
+ ["image-height", "height"],
+ search_util.create_num_filter(
+ model.Post.canvas_height
+ ),
+ ),
+ (
+ ["image-area", "area"],
+ search_util.create_num_filter(model.Post.canvas_area),
+ ),
+ (
+ [
+ "image-aspect-ratio",
+ "image-ar",
+ "aspect-ratio",
+ "ar",
+ ],
+ search_util.create_num_filter(
+ model.Post.canvas_aspect_ratio,
+ transformer=search_util.float_transformer,
+ ),
+ ),
+ (
+ ["creation-date", "creation-time", "date", "time"],
+ search_util.create_date_filter(
+ model.Post.creation_time
+ ),
+ ),
+ (
+ [
+ "last-edit-date",
+ "last-edit-time",
+ "edit-date",
+ "edit-time",
+ ],
+ search_util.create_date_filter(
+ model.Post.last_edit_time
+ ),
+ ),
+ (
+ ["comment-date", "comment-time"],
+ search_util.create_date_filter(
+ model.Post.last_comment_creation_time
+ ),
+ ),
+ (
+ ["fav-date", "fav-time"],
+ search_util.create_date_filter(
+ model.Post.last_favorite_time
+ ),
+ ),
+ (
+ ["feature-date", "feature-time"],
+ search_util.create_date_filter(
+ model.Post.last_feature_time
+ ),
+ ),
+ (["safety", "rating"], _safety_filter),
+ (["note-text"], _note_filter),
+ (
+ ["flag"],
+ search_util.create_str_filter(
+ model.Post.flags_string, _flag_transformer
+ ),
+ ),
+ (["pool"], _pool_filter),
+ (["similar"], _similar_filter),
+ (["category"], _category_filter),
+ ]
+ )
+ )
return filters
@property
def sort_columns(self) -> Dict[str, Tuple[SaColumn, str]]:
- filters = {"metric-" + name:
- (_create_metric_sort_column(name), self.SORT_ASC)
- for name in self.all_metric_names}
- filters.update(util.unalias_dict(
- [
- (
- ["random"],
- (sa.sql.expression.func.random(), self.SORT_NONE),
- ),
- (["id"], (model.Post.post_id, self.SORT_DESC)),
- (["score"], (model.Post.score, self.SORT_DESC)),
- (["tag-count"], (model.Post.tag_count, self.SORT_DESC)),
- (
- ["comment-count"],
- (model.Post.comment_count, self.SORT_DESC),
- ),
- (["fav-count"], (model.Post.favorite_count, self.SORT_DESC)),
- (["note-count"], (model.Post.note_count, self.SORT_DESC)),
- (
- ["relation-count"],
- (model.Post.relation_count, self.SORT_DESC),
- ),
- (
- ["feature-count"],
- (model.Post.feature_count, self.SORT_DESC),
- ),
- (["file-size"], (model.Post.file_size, self.SORT_DESC)),
- (
- ["image-width", "width"],
- (model.Post.canvas_width, self.SORT_DESC),
- ),
- (
- ["image-height", "height"],
- (model.Post.canvas_height, self.SORT_DESC),
- ),
- (
- ["image-area", "area"],
- (model.Post.canvas_area, self.SORT_DESC),
- ),
- (
- ["creation-date", "creation-time", "date", "time"],
- (model.Post.creation_time, self.SORT_DESC),
- ),
- (
- [
- "last-edit-date",
- "last-edit-time",
- "edit-date",
- "edit-time",
- ],
- (model.Post.last_edit_time, self.SORT_DESC),
- ),
- (
- ["comment-date", "comment-time"],
- (model.Post.last_comment_creation_time, self.SORT_DESC),
- ),
- (
- ["fav-date", "fav-time"],
- (model.Post.last_favorite_time, self.SORT_DESC),
- ),
- (
- ["feature-date", "feature-time"],
- (model.Post.last_feature_time, self.SORT_DESC),
- ),
- ]
- ))
+ filters = {
+ "metric-" + name: (_create_metric_sort_column(name), self.SORT_ASC)
+ for name in self.all_metric_names
+ }
+ filters.update(
+ util.unalias_dict(
+ [
+ (
+ ["random"],
+ (sa.sql.expression.func.random(), self.SORT_NONE),
+ ),
+ (["id"], (model.Post.post_id, self.SORT_DESC)),
+ (["score"], (model.Post.score, self.SORT_DESC)),
+ (["tag-count"], (model.Post.tag_count, self.SORT_DESC)),
+ (
+ ["comment-count"],
+ (model.Post.comment_count, self.SORT_DESC),
+ ),
+ (
+ ["fav-count"],
+ (model.Post.favorite_count, self.SORT_DESC),
+ ),
+ (["note-count"], (model.Post.note_count, self.SORT_DESC)),
+ (
+ ["relation-count"],
+ (model.Post.relation_count, self.SORT_DESC),
+ ),
+ (
+ ["feature-count"],
+ (model.Post.feature_count, self.SORT_DESC),
+ ),
+ (["file-size"], (model.Post.file_size, self.SORT_DESC)),
+ (
+ ["image-width", "width"],
+ (model.Post.canvas_width, self.SORT_DESC),
+ ),
+ (
+ ["image-height", "height"],
+ (model.Post.canvas_height, self.SORT_DESC),
+ ),
+ (
+ ["image-area", "area"],
+ (model.Post.canvas_area, self.SORT_DESC),
+ ),
+ (
+ ["creation-date", "creation-time", "date", "time"],
+ (model.Post.creation_time, self.SORT_DESC),
+ ),
+ (
+ [
+ "last-edit-date",
+ "last-edit-time",
+ "edit-date",
+ "edit-time",
+ ],
+ (model.Post.last_edit_time, self.SORT_DESC),
+ ),
+ (
+ ["comment-date", "comment-time"],
+ (
+ model.Post.last_comment_creation_time,
+ self.SORT_DESC,
+ ),
+ ),
+ (
+ ["fav-date", "fav-time"],
+ (model.Post.last_favorite_time, self.SORT_DESC),
+ ),
+ (
+ ["feature-date", "feature-time"],
+ (model.Post.last_feature_time, self.SORT_DESC),
+ ),
+ ]
+ )
+ )
return filters
@property