norandomtopic-onserver-fix
All checks were successful
Deploy on push / deploy (push) Successful in 1m17s

This commit is contained in:
Untone 2024-11-01 11:09:16 +03:00
parent 54e26fb863
commit a105372b15
7 changed files with 76 additions and 97 deletions

View File

@ -2,7 +2,13 @@
- `docs` added - `docs` added
- optimized and unified `load_shouts_*` resolvers with `LoadShoutsOptions` - optimized and unified `load_shouts_*` resolvers with `LoadShoutsOptions`
- `load_shouts_bookmarked` resolver fixed - `load_shouts_bookmarked` resolver fixed
- refactored with `resolvers/feed` - resolvers updates:
- new resolvers group `feed`
- `load_shouts_authored_by` resolver added
- `load_shouts_with_topic` resolver added
- `load_shouts_followed` removed
- `load_shouts_random_topic` removed
- `get_topics_random` removed
- model updates: - model updates:
- `ShoutsOrderBy` enum added - `ShoutsOrderBy` enum added
- `Shout.main_topic` from `ShoutTopic.main` as `Topic` type output - `Shout.main_topic` from `ShoutTopic.main` as `Topic` type output

View File

@ -12,6 +12,12 @@ from resolvers.author import ( # search_authors,
) )
from resolvers.community import get_communities_all, get_community from resolvers.community import get_communities_all, get_community
from resolvers.editor import create_shout, delete_shout, update_shout from resolvers.editor import create_shout, delete_shout, update_shout
from resolvers.feed import (
load_shouts_coauthored,
load_shouts_discussed,
load_shouts_feed,
load_shouts_followed_by,
)
from resolvers.follower import follow, get_shout_followers, unfollow from resolvers.follower import follow, get_shout_followers, unfollow
from resolvers.notifier import ( from resolvers.notifier import (
load_notifications, load_notifications,
@ -33,17 +39,9 @@ from resolvers.reader import (
get_shout, get_shout,
load_shouts_by, load_shouts_by,
load_shouts_random_top, load_shouts_random_top,
load_shouts_random_topic,
load_shouts_search, load_shouts_search,
load_shouts_unrated, load_shouts_unrated,
) )
from resolvers.feed import (
load_shouts_coauthored,
load_shouts_discussed,
load_shouts_feed,
load_shouts_followed,
load_shouts_followed_by,
)
from resolvers.topic import ( from resolvers.topic import (
get_topic, get_topic,
get_topic_authors, get_topic_authors,
@ -81,15 +79,16 @@ __all__ = [
# reader # reader
"get_shout", "get_shout",
"load_shouts_by", "load_shouts_by",
"load_shouts_random_top",
# feed
"load_shouts_feed", "load_shouts_feed",
"load_shouts_search", "load_shouts_search",
"load_shouts_followed",
"load_shouts_followed_by", "load_shouts_followed_by",
"load_shouts_unrated", "load_shouts_unrated",
"load_shouts_coauthored", "load_shouts_coauthored",
"load_shouts_discussed", "load_shouts_discussed",
"load_shouts_random_top", "load_shouts_with_topic",
"load_shouts_random_topic", "load_shouts_authored_by",
# follower # follower
"follow", "follow",
"unfollow", "unfollow",

View File

@ -1,4 +1,5 @@
from operator import and_ from operator import and_
from graphql import GraphQLError from graphql import GraphQLError
from sqlalchemy import delete, insert, select from sqlalchemy import delete, insert, select
@ -30,7 +31,11 @@ def load_shouts_bookmarked(_, info, options):
if not author_id: if not author_id:
raise GraphQLError("User not authenticated") raise GraphQLError("User not authenticated")
q = query_with_stat() if has_field(info, "stat") else select(Shout).filter(and_(Shout.published_at.is_not(None), Shout.deleted_at.is_(None))) q = (
query_with_stat()
if has_field(info, "stat")
else select(Shout).filter(and_(Shout.published_at.is_not(None), Shout.deleted_at.is_(None)))
)
q = q.join(AuthorBookmark) q = q.join(AuthorBookmark)
q = q.filter( q = q.filter(
and_( and_(

View File

@ -6,7 +6,7 @@ from sqlalchemy.orm import joinedload
from orm.author import Author, AuthorFollower from orm.author import Author, AuthorFollower
from orm.reaction import Reaction from orm.reaction import Reaction
from orm.shout import Shout, ShoutAuthor, ShoutReactionsFollower, ShoutTopic from orm.shout import Shout, ShoutAuthor, ShoutReactionsFollower, ShoutTopic
from orm.topic import TopicFollower from orm.topic import Topic, TopicFollower
from resolvers.reader import apply_filters, apply_sorting, get_shouts_with_links, has_field, query_with_stat from resolvers.reader import apply_filters, apply_sorting, get_shouts_with_links, has_field, query_with_stat
from services.auth import login_required from services.auth import login_required
from services.db import local_session from services.db import local_session
@ -70,29 +70,6 @@ def filter_followed(info, q):
return q, reader_id return q, reader_id
@query.field("load_shouts_feed")
@login_required
async def load_shouts_feed(_, info, options):
"""
Загрузка ленты публикаций для авторизованного пользователя.
:param info: Информация о контексте GraphQL.
:param options: Опции фильтрации и сортировки.
:return: Список публикаций для ленты.
"""
author_id = info.context.get("author_id")
if not author_id:
return []
q = (
query_with_stat()
if has_field(info, "stat")
else select(Shout).filter(and_(Shout.published_at.is_not(None), Shout.deleted_at.is_(None)))
)
q, limit, offset = apply_options(q, options, author_id)
return get_shouts_with_links(info, q, limit, offset)
@query.field("load_shouts_coauthored") @query.field("load_shouts_coauthored")
@login_required @login_required
async def load_shouts_coauthored(_, info, options): async def load_shouts_coauthored(_, info, options):
@ -200,9 +177,9 @@ async def reacted_shouts_updates(info, follower_id: int, options) -> List[Shout]
return shouts return shouts
@query.field("load_shouts_followed") @query.field("load_shouts_feed")
@login_required @login_required
async def load_shouts_followed(_, info, options) -> List[Shout]: async def load_shouts_feed(_, info, options) -> List[Shout]:
""" """
Загружает публикации, на которые подписан пользователь. Загружает публикации, на которые подписан пользователь.
@ -243,3 +220,41 @@ async def load_shouts_followed_by(_, info, slug: str, options) -> List[Shout]:
except Exception as error: except Exception as error:
logger.debug(error) logger.debug(error)
return [] return []
@query.field("load_shouts_authored_by")
async def load_shouts_authored_by(_, info, slug: str, options) -> List[Shout]:
"""
Загружает публикации, написанные автором по slug.
"""
with local_session() as session:
author = session.query(Author).filter(Author.slug == slug).first()
if author:
try:
author_id: int = author.dict()["id"]
q = query_with_stat() if has_field(info, "stat") else select(Shout)
q = q.filter(and_(Shout.published_at.is_not(None), Shout.deleted_at.is_(None)))
q = q.filter(Shout.authors.any(id=author_id))
q, limit, offset = apply_options(q, options, author_id)
shouts = get_shouts_with_links(info, q, limit, offset=offset)
return shouts
except Exception as error:
logger.debug(error)
return []
@query.field("load_shouts_with_topic")
async def load_shouts_with_topic(_, info, slug: str, options) -> List[Shout]:
"""
Загружает публикации, связанные с темой по slug.
"""
with local_session() as session:
topic = session.query(Topic).filter(Topic.slug == slug).first()
if topic:
try:
topic_id: int = topic.dict()["id"]
shouts = await reacted_shouts_updates(info, topic_id, options)
return shouts
except Exception as error:
logger.debug(error)
return []

View File

@ -7,7 +7,6 @@ from orm.author import Author
from orm.reaction import Reaction, ReactionKind from orm.reaction import Reaction, ReactionKind
from orm.shout import Shout, ShoutAuthor, ShoutTopic from orm.shout import Shout, ShoutAuthor, ShoutTopic
from orm.topic import Topic from orm.topic import Topic
from resolvers.topic import get_topics_random
from services.db import local_session from services.db import local_session
from services.schema import query from services.schema import query
from services.search import search_text from services.search import search_text
@ -457,31 +456,3 @@ async def load_shouts_random_top(_, info, options):
q = q.order_by(func.random()) q = q.order_by(func.random())
limit = options.get("limit", 10) limit = options.get("limit", 10)
return get_shouts_with_links(info, q, limit) return get_shouts_with_links(info, q, limit)
@query.field("load_shouts_random_topic")
async def load_shouts_random_topic(_, info, options):
"""
Загрузка случайной темы и связанных с ней публикаций.
:param info: Информация о контексте GraphQL.
:param options: Опции фильтрации и сортировки.
:return: Тема и связанные публикации.
"""
[topic] = get_topics_random(None, None, 1)
if topic:
q = (
query_with_stat()
if has_field(info, "stat")
else select(Shout).filter(and_(Shout.published_at.is_not(None), Shout.deleted_at.is_(None)))
)
q = q.filter(Shout.topics.any(slug=topic.slug))
q = apply_filters(q, options)
q = apply_sorting(q, options)
limit = options.get("limit", 10)
offset = options.get("offset", 0)
shouts = get_shouts_with_links(info, q, limit, offset)
if shouts:
return {"topic": topic, "shouts": shouts}
return {"error": "failed to get random topic"}

View File

@ -1,4 +1,4 @@
from sqlalchemy import distinct, func, select from sqlalchemy import select
from cache.cache import ( from cache.cache import (
get_cached_topic_authors, get_cached_topic_authors,
@ -7,7 +7,6 @@ from cache.cache import (
) )
from cache.memorycache import cache_region from cache.memorycache import cache_region
from orm.author import Author from orm.author import Author
from orm.shout import ShoutTopic
from orm.topic import Topic from orm.topic import Topic
from resolvers.stat import get_with_stat from resolvers.stat import get_with_stat
from services.auth import login_required from services.auth import login_required
@ -116,23 +115,6 @@ async def delete_topic(_, info, slug: str):
return {"error": "access denied"} return {"error": "access denied"}
# Запрос на получение случайных тем
@query.field("get_topics_random")
def get_topics_random(_, _info, amount=12):
q = select(Topic)
q = q.join(ShoutTopic)
q = q.group_by(Topic.id)
q = q.having(func.count(distinct(ShoutTopic.shout)) > 2)
q = q.order_by(func.random()).limit(amount)
topics = []
with local_session() as session:
for [topic] in session.execute(q):
topics.append(topic)
return topics
# Запрос на получение подписчиков темы # Запрос на получение подписчиков темы
@query.field("get_topic_followers") @query.field("get_topic_followers")
async def get_topic_followers(_, _info, slug: str): async def get_topic_followers(_, _info, slug: str):

View File

@ -19,8 +19,6 @@ type Query {
get_author_follows(slug: String, user: String, author_id: Int): CommonResult! get_author_follows(slug: String, user: String, author_id: Int): CommonResult!
get_author_follows_topics(slug: String, user: String, author_id: Int): [Topic] get_author_follows_topics(slug: String, user: String, author_id: Int): [Topic]
get_author_follows_authors(slug: String, user: String, author_id: Int): [Author] get_author_follows_authors(slug: String, user: String, author_id: Int): [Author]
load_shouts_followed(limit: Int, offset: Int): [Shout]
load_shouts_followed_by(slug: String, limit: Int, offset: Int): [Shout]
# reaction # reaction
load_reactions_by(by: ReactionBy!, limit: Int, offset: Int): [Reaction] load_reactions_by(by: ReactionBy!, limit: Int, offset: Int): [Reaction]
@ -33,14 +31,18 @@ type Query {
load_shouts_by(options: LoadShoutsOptions): [Shout] load_shouts_by(options: LoadShoutsOptions): [Shout]
load_shouts_search(text: String!, options: LoadShoutsOptions): [SearchResult] load_shouts_search(text: String!, options: LoadShoutsOptions): [SearchResult]
load_shouts_bookmarked(options: LoadShoutsOptions): [Shout] load_shouts_bookmarked(options: LoadShoutsOptions): [Shout]
load_shouts_random_topic(options: LoadShoutsOptions): CommonResult! # { topic shouts }
# feed # public feeds
load_shouts_with_topic(slug: String, options: LoadShoutsOptions): [Shout] # topic feed
load_shouts_random_top(options: LoadShoutsOptions): [Shout] # random order, fixed filter, limit offset can be used
load_shouts_authored_by(slug: String, options: LoadShoutsOptions): [Shout] # author feed
load_shouts_followed_by(slug: String, options: LoadShoutsOptions): [Shout] # another author feed
# my feeds
load_shouts_feed(options: LoadShoutsOptions): [Shout] load_shouts_feed(options: LoadShoutsOptions): [Shout]
load_shouts_unrated(options: LoadShoutsOptions): [Shout] load_shouts_unrated(options: LoadShoutsOptions): [Shout]
load_shouts_coauthored(options: LoadShoutsOptions): [Shout] load_shouts_coauthored(options: LoadShoutsOptions): [Shout]
load_shouts_discussed(options: LoadShoutsOptions): [Shout] load_shouts_discussed(options: LoadShoutsOptions): [Shout]
load_shouts_random_top(options: LoadShoutsOptions): [Shout] # random order, fixed filter, limit offset can be used
# editor # editor
get_my_shout(shout_id: Int!): CommonResult! get_my_shout(shout_id: Int!): CommonResult!
@ -49,7 +51,6 @@ type Query {
# topic # topic
get_topic(slug: String!): Topic get_topic(slug: String!): Topic
get_topics_all: [Topic] get_topics_all: [Topic]
get_topics_random(amount: Int): [Topic]
get_topics_by_author(slug: String, user: String, author_id: Int): [Topic] get_topics_by_author(slug: String, user: String, author_id: Int): [Topic]
get_topics_by_community(slug: String, community_id: Int): [Topic] get_topics_by_community(slug: String, community_id: Int): [Topic]