fmt
All checks were successful
Deploy on push / deploy (push) Successful in 22s

This commit is contained in:
2024-03-28 15:56:32 +03:00
parent 7f913050ee
commit 9bda7cef95
12 changed files with 273 additions and 177 deletions

View File

@@ -14,21 +14,21 @@ from services.logger import root_logger as logger
DEFAULT_FOLLOWS = {
"topics": [],
"authors": [],
"communities": [{"id": 1, "name": "Дискурс", "slug": "discours", "pic": ""}],
'topics': [],
'authors': [],
'communities': [{'id': 1, 'name': 'Дискурс', 'slug': 'discours', 'pic': ''}],
}
async def set_author_cache(author: dict):
payload = json.dumps(author, cls=CustomJSONEncoder)
await redis.execute("SET", f'user:{author.get("user")}', payload)
await redis.execute("SET", f'author:{author.get("id")}', payload)
await redis.execute('SET', f'user:{author.get("user")}', payload)
await redis.execute('SET', f'author:{author.get("id")}', payload)
async def set_topic_cache(topic: dict):
payload = json.dumps(topic, cls=CustomJSONEncoder)
await redis.execute("SET", f'topic:{topic.get("id")}', payload)
await redis.execute('SET', f'topic:{topic.get("id")}', payload)
async def update_author_followers_cache(author_id: int, followers):
@@ -36,7 +36,7 @@ async def update_author_followers_cache(author_id: int, followers):
[f.dict() if isinstance(f, Author) else f for f in followers],
cls=CustomJSONEncoder,
)
await redis.execute("SET", f"author:{author_id}:followers", payload)
await redis.execute('SET', f'author:{author_id}:followers', payload)
async def set_follows_topics_cache(follows, author_id: int):
@@ -45,7 +45,7 @@ async def set_follows_topics_cache(follows, author_id: int):
[a.dict() if isinstance(a, Author) else a for a in follows],
cls=CustomJSONEncoder,
)
await redis.execute("SET", f"author:{author_id}:follows-topics", payload)
await redis.execute('SET', f'author:{author_id}:follows-topics', payload)
except Exception as exc:
logger.error(exc)
import traceback
@@ -60,7 +60,7 @@ async def set_follows_authors_cache(follows, author_id: int):
[a.dict() if isinstance(a, Author) else a for a in follows],
cls=CustomJSONEncoder,
)
await redis.execute("SET", f"author:{author_id}:follows-authors", payload)
await redis.execute('SET', f'author:{author_id}:follows-authors', payload)
except Exception as exc:
import traceback
@@ -73,31 +73,31 @@ async def update_follows_for_author(
follower: Author, entity_type: str, entity: dict, is_insert: bool
):
follows = []
redis_key = f"author:{follower.id}:follows-{entity_type}s"
follows_str = await redis.execute("GET", redis_key)
redis_key = f'author:{follower.id}:follows-{entity_type}s'
follows_str = await redis.execute('GET', redis_key)
if isinstance(follows_str, str):
follows = json.loads(follows_str)
if is_insert:
follows.append(entity)
else:
entity_id = entity.get("id")
entity_id = entity.get('id')
if not entity_id:
raise Exception("wrong entity")
raise Exception('wrong entity')
# Remove the entity from follows
follows = [e for e in follows if e["id"] != entity_id]
follows = [e for e in follows if e['id'] != entity_id]
logger.debug(f'{entity['slug']} removed from what @{follower.slug} follows')
if entity_type == "topic":
await set_follows_topics_cache(follows, follower.id.scalar())
if entity_type == "author":
await set_follows_authors_cache(follows, follower.id.scalar())
if entity_type == 'topic':
await set_follows_topics_cache(follows, follower.id)
if entity_type == 'author':
await set_follows_authors_cache(follows, follower.id)
return follows
async def update_followers_for_author(
follower: Author, author: Author, is_insert: bool
):
redis_key = f"author:{author.id}:followers"
followers_str = await redis.execute("GET", redis_key)
redis_key = f'author:{author.id}:followers'
followers_str = await redis.execute('GET', redis_key)
followers = []
if isinstance(followers_str, str):
followers = json.loads(followers_str)
@@ -105,8 +105,8 @@ async def update_followers_for_author(
followers.append(follower)
else:
# Remove the entity from followers
followers = [e for e in followers if e["id"] != author.id]
await update_author_followers_cache(author.id.scalar(), followers)
followers = [e for e in followers if e['id'] != author.id]
await update_author_followers_cache(author.id, followers)
return followers
@@ -136,8 +136,9 @@ def after_reaction_update(mapper, connection, reaction: Reaction):
select(author_subquery.subquery())
.select_from(author_subquery.subquery())
.union(
select(replied_author_subquery.subquery())
.select_from(replied_author_subquery.subquery())
select(replied_author_subquery.subquery()).select_from(
replied_author_subquery.subquery()
)
)
)
@@ -166,25 +167,25 @@ def after_author_update(_mapper, _connection, author: Author):
def after_topic_follower_insert(_mapper, _connection, target: TopicFollower):
asyncio.create_task(
handle_topic_follower_change(target.topic.scalar(), target.follower.scalar(), True)
handle_topic_follower_change(target.topic, target.follower, True)
)
def after_topic_follower_delete(_mapper, _connection, target: TopicFollower):
asyncio.create_task(
handle_topic_follower_change(target.topic.scalar(), target.follower.scalar(), False)
handle_topic_follower_change(target.topic, target.follower, False)
)
def after_author_follower_insert(_mapper, _connection, target: AuthorFollower):
asyncio.create_task(
handle_author_follower_change(target.author.scalar(), target.follower.scalar(), True)
handle_author_follower_change(target.author, target.follower, True)
)
def after_author_follower_delete(_mapper, _connection, target: AuthorFollower):
asyncio.create_task(
handle_author_follower_change(target.author.scalar(), target.follower.scalar(), False)
handle_author_follower_change(target.author, target.follower, False)
)
@@ -198,24 +199,24 @@ async def handle_author_follower_change(
if follower and author:
_ = asyncio.create_task(set_author_cache(author.dict()))
follows_authors = await redis.execute(
"GET", f"author:{follower_id}:follows-authors"
'GET', f'author:{follower_id}:follows-authors'
)
if isinstance(follows_authors, str):
follows_authors = json.loads(follows_authors)
if not any(x.get("id") == author.id for x in follows_authors):
if not any(x.get('id') == author.id for x in follows_authors):
follows_authors.append(author.dict())
_ = asyncio.create_task(set_follows_authors_cache(follows_authors, follower_id))
_ = asyncio.create_task(set_author_cache(follower.dict()))
await update_follows_for_author(
follower,
"author",
'author',
{
"id": author.id,
"name": author.name,
"slug": author.slug,
"pic": author.pic,
"bio": author.bio,
"stat": author.stat,
'id': author.id,
'name': author.name,
'slug': author.slug,
'pic': author.pic,
'bio': author.bio,
'stat': author.stat,
},
is_insert,
)
@@ -231,41 +232,41 @@ async def handle_topic_follower_change(
if follower and topic:
_ = asyncio.create_task(set_author_cache(follower.dict()))
follows_topics = await redis.execute(
"GET", f"author:{follower_id}:follows-topics"
'GET', f'author:{follower_id}:follows-topics'
)
if isinstance(follows_topics, str):
follows_topics = json.loads(follows_topics)
if not any(x.get("id") == topic.id for x in follows_topics):
if not any(x.get('id') == topic.id for x in follows_topics):
follows_topics.append(topic)
_ = asyncio.create_task(set_follows_topics_cache(follows_topics, follower_id))
await update_follows_for_author(
follower,
"topic",
'topic',
{
"id": topic.id,
"title": topic.title,
"slug": topic.slug,
"body": topic.body,
"stat": topic.stat,
'id': topic.id,
'title': topic.title,
'slug': topic.slug,
'body': topic.body,
'stat': topic.stat,
},
is_insert,
)
def events_register():
event.listen(Shout, "after_insert", after_shout_update)
event.listen(Shout, "after_update", after_shout_update)
event.listen(Shout, 'after_insert', after_shout_update)
event.listen(Shout, 'after_update', after_shout_update)
event.listen(Reaction, "after_insert", after_reaction_update)
event.listen(Reaction, "after_update", after_reaction_update)
event.listen(Reaction, 'after_insert', after_reaction_update)
event.listen(Reaction, 'after_update', after_reaction_update)
event.listen(Author, "after_insert", after_author_update)
event.listen(Author, "after_update", after_author_update)
event.listen(Author, 'after_insert', after_author_update)
event.listen(Author, 'after_update', after_author_update)
event.listen(AuthorFollower, "after_insert", after_author_follower_insert)
event.listen(AuthorFollower, "after_delete", after_author_follower_delete)
event.listen(AuthorFollower, 'after_insert', after_author_follower_insert)
event.listen(AuthorFollower, 'after_delete', after_author_follower_delete)
event.listen(TopicFollower, "after_insert", after_topic_follower_insert)
event.listen(TopicFollower, "after_delete", after_topic_follower_delete)
event.listen(TopicFollower, 'after_insert', after_topic_follower_insert)
event.listen(TopicFollower, 'after_delete', after_topic_follower_delete)
logger.info('cache events were registered!')

View File

@@ -101,7 +101,11 @@ def after_cursor_execute(conn, cursor, statement, parameters, context, executema
if hasattr(conn, 'query_start_time'):
elapsed = time.time() - conn.query_start_time
conn.query_start_time = None
query = f'{statement} % {parameters}' if parameters else f'{statement}'.replace('\n', ' ')
query = (
f'{statement} % {parameters}'
if parameters
else f'{statement}'.replace('\n', ' ')
)
if elapsed > 1 and conn.executed_statement != conn.statement:
conn.executed_statement = conn.statement
logger.debug(f"\n{query}\n{'*' * math.floor(elapsed)} {elapsed:.3f} s\n")

View File

@@ -122,7 +122,9 @@ class SearchService:
async def recreate_index(self):
if self.client:
async with self.lock:
self.client.indices.delete(index=self.index_name, ignore_unavailable=True)
self.client.indices.delete(
index=self.index_name, ignore_unavailable=True
)
await self.check_index()
def index(self, shout):
@@ -146,7 +148,12 @@ class SearchService:
# Use Redis as cache with TTL
redis_key = f'search:{text}'
await redis.execute('SETEX', redis_key, REDIS_TTL, json.dumps(results, cls=CustomJSONEncoder))
await redis.execute(
'SETEX',
redis_key,
REDIS_TTL,
json.dumps(results, cls=CustomJSONEncoder),
)
return []

View File

@@ -42,7 +42,6 @@ class ViewedStorage:
"""Подключение к клиенту Google Analytics с использованием аутентификации"""
self = ViewedStorage
async with self.lock:
# Загрузка предварительно подсчитанных просмотров из файла JSON
self.load_precounted_views()
@@ -66,7 +65,9 @@ class ViewedStorage:
try:
if os.path.exists(VIEWS_FILEPATH):
self.file_modification_timestamp = os.path.getmtime(VIEWS_FILEPATH)
self.start_date = datetime.fromtimestamp(self.file_modification_timestamp).strftime('%Y-%m-%d')
self.start_date = datetime.fromtimestamp(
self.file_modification_timestamp
).strftime('%Y-%m-%d')
now_date = datetime.now().strftime('%Y-%m-%d')
if now_date == self.start_date:
@@ -83,7 +84,7 @@ class ViewedStorage:
f' * {len(precounted_views)} публикаций с просмотрами успешно загружены.'
)
else:
logger.info(" * Файл просмотров не найден.")
logger.info(' * Файл просмотров не найден.')
except Exception as e:
logger.error(f'Ошибка загрузки предварительно подсчитанных просмотров: {e}')