This commit is contained in:
parent
2c6b872acb
commit
a6c5243c06
5
main.py
5
main.py
|
@ -1,20 +1,21 @@
|
||||||
import os
|
import os
|
||||||
from importlib import import_module
|
from importlib import import_module
|
||||||
from os.path import exists
|
from os.path import exists
|
||||||
|
|
||||||
from ariadne import load_schema_from_path, make_executable_schema
|
from ariadne import load_schema_from_path, make_executable_schema
|
||||||
from ariadne.asgi import GraphQL
|
from ariadne.asgi import GraphQL
|
||||||
|
from sentry_sdk.integrations.aiohttp import AioHttpIntegration
|
||||||
from sentry_sdk.integrations.ariadne import AriadneIntegration
|
from sentry_sdk.integrations.ariadne import AriadneIntegration
|
||||||
from sentry_sdk.integrations.redis import RedisIntegration
|
from sentry_sdk.integrations.redis import RedisIntegration
|
||||||
from sentry_sdk.integrations.sqlalchemy import SqlalchemyIntegration
|
from sentry_sdk.integrations.sqlalchemy import SqlalchemyIntegration
|
||||||
from sentry_sdk.integrations.starlette import StarletteIntegration
|
from sentry_sdk.integrations.starlette import StarletteIntegration
|
||||||
from sentry_sdk.integrations.aiohttp import AioHttpIntegration
|
|
||||||
from starlette.applications import Starlette
|
from starlette.applications import Starlette
|
||||||
from starlette.routing import Route
|
from starlette.routing import Route
|
||||||
|
|
||||||
from resolvers.webhook import WebhookEndpoint
|
from resolvers.webhook import WebhookEndpoint
|
||||||
from services.rediscache import redis
|
from services.rediscache import redis
|
||||||
from services.schema import resolvers
|
from services.schema import resolvers
|
||||||
from settings import DEV_SERVER_PID_FILE_NAME, SENTRY_DSN, MODE
|
from settings import DEV_SERVER_PID_FILE_NAME, MODE, SENTRY_DSN
|
||||||
|
|
||||||
import_module("resolvers")
|
import_module("resolvers")
|
||||||
schema = make_executable_schema(load_schema_from_path("schemas/core.graphql"), resolvers) # type: ignore
|
schema = make_executable_schema(load_schema_from_path("schemas/core.graphql"), resolvers) # type: ignore
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
from sqlalchemy import Column, ForeignKey, Enum, String
|
from enum import Enum as Enumeration
|
||||||
|
|
||||||
|
from sqlalchemy import Column, ForeignKey, String
|
||||||
from sqlalchemy.orm import relationship
|
from sqlalchemy.orm import relationship
|
||||||
from services.db import Base
|
|
||||||
from orm.author import Author
|
from orm.author import Author
|
||||||
from orm.shout import Shout
|
from orm.shout import Shout
|
||||||
from enum import Enum as Enumeration
|
from services.db import Base
|
||||||
|
|
||||||
|
|
||||||
class InviteStatus(Enumeration):
|
class InviteStatus(Enumeration):
|
||||||
|
|
|
@ -12,25 +12,24 @@ SQLAlchemy = "^2.0.22"
|
||||||
psycopg2-binary = "^2.9.9"
|
psycopg2-binary = "^2.9.9"
|
||||||
redis = {extras = ["hiredis"], version = "^5.0.1"}
|
redis = {extras = ["hiredis"], version = "^5.0.1"}
|
||||||
uvicorn = "^0.24"
|
uvicorn = "^0.24"
|
||||||
sentry-sdk = "^1.38.0"
|
sentry-sdk = "^1.39.1"
|
||||||
starlette = "^0.32.0.post1"
|
starlette = "^0.34.0"
|
||||||
gql = "^3.4.1"
|
gql = "^3.4.1"
|
||||||
ariadne = "^0.21"
|
ariadne = "^0.21"
|
||||||
aiohttp = "^3.9.1"
|
aiohttp = "^3.9.1"
|
||||||
requests = "^2.31.0"
|
|
||||||
|
|
||||||
[tool.poetry.group.dev.dependencies]
|
[tool.poetry.group.dev.dependencies]
|
||||||
setuptools = "^69.0.2"
|
setuptools = "^69.0.2"
|
||||||
|
pyright = "^1.1.341"
|
||||||
|
pytest = "^7.4.2"
|
||||||
|
black = { version = "^23.12.0", python = ">=3.12" }
|
||||||
|
ruff = { version = "^0.1.8", python = ">=3.12" }
|
||||||
|
isort = "^5.13.2"
|
||||||
|
|
||||||
[build-system]
|
[build-system]
|
||||||
requires = ["poetry-core"]
|
requires = ["poetry-core"]
|
||||||
build-backend = "poetry.core.masonry.api"
|
build-backend = "poetry.core.masonry.api"
|
||||||
|
|
||||||
[tool.poetry.dev-dependencies]
|
|
||||||
pytest = "^7.4.2"
|
|
||||||
black = { version = "^23.12.0", python = ">=3.12" }
|
|
||||||
ruff = { version = "^0.1.8", python = ">=3.12" }
|
|
||||||
|
|
||||||
[tool.black]
|
[tool.black]
|
||||||
line-length = 120
|
line-length = 120
|
||||||
target-version = ['py312']
|
target-version = ['py312']
|
||||||
|
|
|
@ -1,40 +1,32 @@
|
||||||
from resolvers.editor import create_shout, delete_shout, update_shout
|
|
||||||
|
|
||||||
from resolvers.author import (
|
from resolvers.author import (
|
||||||
get_author,
|
get_author,
|
||||||
|
get_author_followed,
|
||||||
|
get_author_followers,
|
||||||
get_author_id,
|
get_author_id,
|
||||||
load_authors_all,
|
load_authors_all,
|
||||||
get_author_followers,
|
|
||||||
get_author_followed,
|
|
||||||
load_authors_by,
|
load_authors_by,
|
||||||
update_profile,
|
|
||||||
rate_author,
|
rate_author,
|
||||||
|
update_profile,
|
||||||
)
|
)
|
||||||
|
from resolvers.community import get_communities_all, get_community
|
||||||
|
from resolvers.editor import create_shout, delete_shout, update_shout
|
||||||
|
from resolvers.follower import follow, get_my_followed, unfollow
|
||||||
from resolvers.reaction import (
|
from resolvers.reaction import (
|
||||||
create_reaction,
|
create_reaction,
|
||||||
update_reaction,
|
|
||||||
delete_reaction,
|
delete_reaction,
|
||||||
load_reactions_by,
|
load_reactions_by,
|
||||||
load_shouts_followed,
|
load_shouts_followed,
|
||||||
|
update_reaction,
|
||||||
)
|
)
|
||||||
from resolvers.topic import (
|
|
||||||
get_topics_by_author,
|
|
||||||
get_topics_by_community,
|
|
||||||
get_topics_all,
|
|
||||||
get_topic,
|
|
||||||
)
|
|
||||||
|
|
||||||
from resolvers.follower import follow, unfollow, get_my_followed
|
|
||||||
from resolvers.reader import (
|
from resolvers.reader import (
|
||||||
get_shout,
|
get_shout,
|
||||||
load_shouts_by,
|
load_shouts_by,
|
||||||
load_shouts_feed,
|
load_shouts_feed,
|
||||||
|
load_shouts_random_top,
|
||||||
load_shouts_search,
|
load_shouts_search,
|
||||||
load_shouts_unrated,
|
load_shouts_unrated,
|
||||||
load_shouts_random_top,
|
|
||||||
)
|
)
|
||||||
from resolvers.community import get_community, get_communities_all
|
from resolvers.topic import get_topic, get_topics_all, get_topics_by_author, get_topics_by_community
|
||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
# author
|
# author
|
||||||
|
|
|
@ -1,20 +1,21 @@
|
||||||
import time
|
import time
|
||||||
from typing import List
|
from typing import List
|
||||||
from sqlalchemy import and_, func, distinct, select, literal, case
|
|
||||||
|
from sqlalchemy import and_, case, distinct, func, literal, select
|
||||||
from sqlalchemy.orm import aliased
|
from sqlalchemy.orm import aliased
|
||||||
|
|
||||||
from orm.reaction import Reaction, ReactionKind
|
from orm.author import Author, AuthorFollower, AuthorRating
|
||||||
from services.auth import login_required
|
|
||||||
from services.db import local_session
|
|
||||||
from services.unread import get_total_unread_counter
|
|
||||||
from services.schema import mutation, query
|
|
||||||
from orm.community import Community
|
from orm.community import Community
|
||||||
|
from orm.reaction import Reaction, ReactionKind
|
||||||
from orm.shout import ShoutAuthor, ShoutTopic
|
from orm.shout import ShoutAuthor, ShoutTopic
|
||||||
from orm.topic import Topic
|
from orm.topic import Topic
|
||||||
from orm.author import AuthorFollower, Author, AuthorRating
|
|
||||||
from resolvers.community import followed_communities
|
from resolvers.community import followed_communities
|
||||||
from resolvers.topic import followed_topics
|
|
||||||
from resolvers.reaction import reacted_shouts_updates as followed_reactions
|
from resolvers.reaction import reacted_shouts_updates as followed_reactions
|
||||||
|
from resolvers.topic import followed_topics
|
||||||
|
from services.auth import login_required
|
||||||
|
from services.db import local_session
|
||||||
|
from services.schema import mutation, query
|
||||||
|
from services.unread import get_total_unread_counter
|
||||||
|
|
||||||
|
|
||||||
def add_author_stat_columns(q):
|
def add_author_stat_columns(q):
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
|
from orm.author import Author
|
||||||
|
from orm.invite import Invite, InviteStatus
|
||||||
|
from orm.shout import Shout
|
||||||
from services.auth import login_required
|
from services.auth import login_required
|
||||||
from services.db import local_session
|
from services.db import local_session
|
||||||
from services.schema import mutation
|
from services.schema import mutation
|
||||||
from orm.invite import Invite, InviteStatus
|
|
||||||
from orm.author import Author
|
|
||||||
from orm.shout import Shout
|
|
||||||
|
|
||||||
|
|
||||||
@mutation.field("accept_invite")
|
@mutation.field("accept_invite")
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
from services.db import local_session
|
from sqlalchemy import and_, distinct, func, literal, select
|
||||||
from services.schema import query
|
from sqlalchemy.orm import aliased
|
||||||
|
|
||||||
from orm.author import Author
|
from orm.author import Author
|
||||||
from orm.community import Community, CommunityAuthor
|
from orm.community import Community, CommunityAuthor
|
||||||
from orm.shout import ShoutCommunity
|
from orm.shout import ShoutCommunity
|
||||||
from sqlalchemy import select, distinct, func, literal, and_
|
from services.db import local_session
|
||||||
from sqlalchemy.orm import aliased
|
from services.schema import query
|
||||||
|
|
||||||
|
|
||||||
def add_community_stat_columns(q):
|
def add_community_stat_columns(q):
|
||||||
|
|
|
@ -1,15 +1,16 @@
|
||||||
import time # For Unix timestamps
|
import time # For Unix timestamps
|
||||||
|
|
||||||
from sqlalchemy import and_, select
|
from sqlalchemy import and_, select
|
||||||
from sqlalchemy.orm import joinedload
|
from sqlalchemy.orm import joinedload
|
||||||
|
|
||||||
from orm.author import Author
|
from orm.author import Author
|
||||||
from services.auth import login_required
|
|
||||||
from services.db import local_session
|
|
||||||
from services.schema import mutation, query
|
|
||||||
from orm.shout import Shout, ShoutAuthor, ShoutTopic, ShoutVisibility
|
from orm.shout import Shout, ShoutAuthor, ShoutTopic, ShoutVisibility
|
||||||
from orm.topic import Topic
|
from orm.topic import Topic
|
||||||
from resolvers.reaction import reactions_follow, reactions_unfollow
|
from resolvers.reaction import reactions_follow, reactions_unfollow
|
||||||
|
from services.auth import login_required
|
||||||
|
from services.db import local_session
|
||||||
from services.notify import notify_shout
|
from services.notify import notify_shout
|
||||||
|
from services.schema import mutation, query
|
||||||
|
|
||||||
|
|
||||||
@query.field("get_shouts_drafts")
|
@query.field("get_shouts_drafts")
|
||||||
|
|
|
@ -2,18 +2,18 @@ from typing import List
|
||||||
|
|
||||||
from sqlalchemy import select
|
from sqlalchemy import select
|
||||||
|
|
||||||
from orm.community import Community, CommunityAuthor
|
from orm.author import Author, AuthorFollower
|
||||||
|
from orm.community import Community
|
||||||
from orm.reaction import Reaction
|
from orm.reaction import Reaction
|
||||||
from orm.shout import Shout
|
from orm.shout import Shout
|
||||||
from orm.topic import Topic, TopicFollower
|
from orm.topic import Topic, TopicFollower
|
||||||
from services.auth import login_required
|
|
||||||
from resolvers.author import author_follow, author_unfollow
|
from resolvers.author import author_follow, author_unfollow
|
||||||
|
from resolvers.community import community_follow, community_unfollow
|
||||||
from resolvers.reaction import reactions_follow, reactions_unfollow
|
from resolvers.reaction import reactions_follow, reactions_unfollow
|
||||||
from resolvers.topic import topic_follow, topic_unfollow
|
from resolvers.topic import topic_follow, topic_unfollow
|
||||||
from resolvers.community import community_follow, community_unfollow
|
from services.auth import login_required
|
||||||
from services.following import FollowingManager, FollowingResult
|
|
||||||
from services.db import local_session
|
from services.db import local_session
|
||||||
from orm.author import Author, AuthorFollower
|
from services.following import FollowingManager, FollowingResult
|
||||||
from services.notify import notify_follower
|
from services.notify import notify_follower
|
||||||
from services.schema import mutation, query
|
from services.schema import mutation, query
|
||||||
|
|
||||||
|
|
|
@ -1,15 +1,16 @@
|
||||||
import time
|
import time
|
||||||
from typing import List
|
from typing import List
|
||||||
|
|
||||||
from sqlalchemy import and_, asc, desc, select, text, func, case
|
from sqlalchemy import and_, asc, case, desc, func, select, text
|
||||||
from sqlalchemy.orm import aliased, joinedload
|
from sqlalchemy.orm import aliased, joinedload
|
||||||
from services.notify import notify_reaction
|
|
||||||
from services.auth import login_required
|
from orm.author import Author
|
||||||
from services.db import local_session
|
|
||||||
from services.schema import mutation, query
|
|
||||||
from orm.reaction import Reaction, ReactionKind
|
from orm.reaction import Reaction, ReactionKind
|
||||||
from orm.shout import Shout, ShoutReactionsFollower
|
from orm.shout import Shout, ShoutReactionsFollower
|
||||||
from orm.author import Author
|
from services.auth import login_required
|
||||||
|
from services.db import local_session
|
||||||
|
from services.notify import notify_reaction
|
||||||
|
from services.schema import mutation, query
|
||||||
|
|
||||||
|
|
||||||
def add_reaction_stat_columns(q):
|
def add_reaction_stat_columns(q):
|
||||||
|
|
|
@ -1,15 +1,15 @@
|
||||||
from sqlalchemy import distinct, bindparam, or_
|
from sqlalchemy import bindparam, distinct, or_
|
||||||
from sqlalchemy.orm import aliased, joinedload
|
from sqlalchemy.orm import aliased, joinedload
|
||||||
from sqlalchemy.sql.expression import and_, asc, case, desc, func, nulls_last, select
|
from sqlalchemy.sql.expression import and_, asc, case, desc, func, nulls_last, select
|
||||||
from starlette.exceptions import HTTPException
|
from starlette.exceptions import HTTPException
|
||||||
|
|
||||||
|
from orm.author import Author, AuthorFollower
|
||||||
|
from orm.reaction import Reaction, ReactionKind
|
||||||
|
from orm.shout import Shout, ShoutAuthor, ShoutTopic, ShoutVisibility
|
||||||
|
from orm.topic import Topic, TopicFollower
|
||||||
from services.auth import login_required
|
from services.auth import login_required
|
||||||
from services.db import local_session
|
from services.db import local_session
|
||||||
from services.schema import query
|
from services.schema import query
|
||||||
from orm.topic import TopicFollower, Topic
|
|
||||||
from orm.reaction import Reaction, ReactionKind
|
|
||||||
from orm.shout import Shout, ShoutAuthor, ShoutTopic, ShoutVisibility
|
|
||||||
from orm.author import AuthorFollower, Author
|
|
||||||
from services.search import SearchService
|
from services.search import SearchService
|
||||||
from services.viewed import ViewedStorage
|
from services.viewed import ViewedStorage
|
||||||
|
|
||||||
|
@ -161,7 +161,9 @@ async def load_shouts_by(_, _info, options):
|
||||||
session.query(Topic.slug)
|
session.query(Topic.slug)
|
||||||
.join(
|
.join(
|
||||||
ShoutTopic,
|
ShoutTopic,
|
||||||
and_(ShoutTopic.topic == Topic.id, ShoutTopic.shout == shout.id, ShoutTopic.main == True),
|
and_(
|
||||||
|
ShoutTopic.topic == Topic.id, ShoutTopic.shout == shout.id, ShoutTopic.main == True
|
||||||
|
), # noqa: E712
|
||||||
)
|
)
|
||||||
.first()
|
.first()
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
from sqlalchemy import and_, select, distinct, func
|
from sqlalchemy import and_, distinct, func, select
|
||||||
from sqlalchemy.orm import aliased
|
from sqlalchemy.orm import aliased
|
||||||
|
|
||||||
|
from orm.author import Author
|
||||||
|
from orm.shout import ShoutAuthor, ShoutTopic
|
||||||
|
from orm.topic import Topic, TopicFollower
|
||||||
from services.auth import login_required
|
from services.auth import login_required
|
||||||
from services.db import local_session
|
from services.db import local_session
|
||||||
from services.schema import mutation, query
|
from services.schema import mutation, query
|
||||||
from orm.shout import ShoutTopic, ShoutAuthor
|
|
||||||
from orm.topic import Topic, TopicFollower
|
|
||||||
from orm.author import Author
|
|
||||||
|
|
||||||
|
|
||||||
async def followed_topics(follower_id):
|
async def followed_topics(follower_id):
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
import uvicorn
|
import uvicorn
|
||||||
from uvicorn.main import logger
|
from uvicorn.main import logger
|
||||||
|
|
||||||
|
@ -58,5 +59,5 @@ if __name__ == "__main__":
|
||||||
if "dev" in sys.argv:
|
if "dev" in sys.argv:
|
||||||
import os
|
import os
|
||||||
|
|
||||||
os.environ.set("MODE", "development")
|
os.environ["MODE"] = "development"
|
||||||
uvicorn.run("main:app", host="0.0.0.0", port=PORT, proxy_headers=True, server_header=True)
|
uvicorn.run("main:app", host="0.0.0.0", port=PORT, proxy_headers=True, server_header=True)
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
from functools import wraps
|
from functools import wraps
|
||||||
|
|
||||||
import aiohttp
|
import aiohttp
|
||||||
from aiohttp.web import HTTPUnauthorized
|
from aiohttp.web import HTTPUnauthorized
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import json
|
import json
|
||||||
|
|
||||||
from services.rediscache import redis
|
from services.rediscache import redis
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import redis.asyncio as aredis
|
import redis.asyncio as aredis
|
||||||
|
|
||||||
from settings import REDIS_URL
|
from settings import REDIS_URL
|
||||||
|
|
||||||
|
|
||||||
|
@ -45,16 +46,6 @@ class RedisCache:
|
||||||
return
|
return
|
||||||
await self._client.publish(channel, data)
|
await self._client.publish(channel, data)
|
||||||
|
|
||||||
async def lrange(self, key, start, stop):
|
|
||||||
if self._client:
|
|
||||||
print(f"[redis] LRANGE {key} {start} {stop}")
|
|
||||||
return await self._client.lrange(key, start, stop)
|
|
||||||
|
|
||||||
async def mget(self, key, *keys):
|
|
||||||
if self._client:
|
|
||||||
print(f"[redis] MGET {key} {keys}")
|
|
||||||
return await self._client.mget(key, *keys)
|
|
||||||
|
|
||||||
|
|
||||||
redis = RedisCache()
|
redis = RedisCache()
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
from ariadne import QueryType, MutationType # , ScalarType
|
from ariadne import MutationType, QueryType # , ScalarType
|
||||||
|
|
||||||
|
|
||||||
# datetime_scalar = ScalarType("DateTime")
|
# datetime_scalar = ScalarType("DateTime")
|
||||||
query = QueryType()
|
query = QueryType()
|
||||||
|
|
|
@ -1,8 +1,11 @@
|
||||||
import asyncio
|
import asyncio
|
||||||
import json
|
import json
|
||||||
|
from typing import List
|
||||||
|
|
||||||
import aiohttp
|
import aiohttp
|
||||||
from services.rediscache import redis
|
|
||||||
from orm.shout import Shout
|
from orm.shout import Shout
|
||||||
|
from services.rediscache import redis
|
||||||
|
|
||||||
|
|
||||||
class SearchService:
|
class SearchService:
|
||||||
|
@ -16,11 +19,12 @@ class SearchService:
|
||||||
SearchService.cache = {}
|
SearchService.cache = {}
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
async def search(text, limit, offset) -> [Shout]:
|
async def search(text, limit: int = 50, offset: int = 0) -> List[Shout]:
|
||||||
cached = await redis.execute("GET", text)
|
cached = await redis.execute("GET", text)
|
||||||
if not cached:
|
if not cached:
|
||||||
async with SearchService.lock:
|
async with SearchService.lock:
|
||||||
# Use aiohttp to send a request to ElasticSearch
|
# Use aiohttp to send a request to ElasticSearch
|
||||||
|
# TODO: add limit offset usage
|
||||||
async with aiohttp.ClientSession() as session:
|
async with aiohttp.ClientSession() as session:
|
||||||
search_url = f"https://search.discours.io/search?q={text}"
|
search_url = f"https://search.discours.io/search?q={text}"
|
||||||
async with session.get(search_url) as response:
|
async with session.get(search_url) as response:
|
||||||
|
|
|
@ -2,13 +2,14 @@ from services.rediscache import redis
|
||||||
|
|
||||||
|
|
||||||
async def get_unread_counter(chat_id: str, author_id: int) -> int:
|
async def get_unread_counter(chat_id: str, author_id: int) -> int:
|
||||||
unread = await redis.execute("LLEN", f"chats/{chat_id}/unread/{author_id}")
|
unread: int = await redis.execute("LLEN", f"chats/{chat_id}/unread/{author_id}") or 0
|
||||||
return unread or 0
|
return unread
|
||||||
|
|
||||||
|
|
||||||
async def get_total_unread_counter(author_id: int) -> int:
|
async def get_total_unread_counter(author_id: int) -> int:
|
||||||
chats_set = await redis.execute("SMEMBERS", f"chats_by_author/{author_id}")
|
chats_set = await redis.execute("SMEMBERS", f"chats_by_author/{author_id}")
|
||||||
unread = 0
|
unread = 0
|
||||||
|
if chats_set:
|
||||||
for chat_id in list(chats_set):
|
for chat_id in list(chats_set):
|
||||||
n = await get_unread_counter(chat_id, author_id)
|
n = await get_unread_counter(chat_id, author_id)
|
||||||
unread += n
|
unread += n
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
import asyncio
|
import asyncio
|
||||||
import time
|
import time
|
||||||
from datetime import timedelta, timezone, datetime
|
from datetime import datetime, timedelta, timezone
|
||||||
from os import environ
|
from os import environ
|
||||||
|
|
||||||
from gql import Client, gql
|
from gql import Client, gql
|
||||||
from gql.transport.aiohttp import AIOHTTPTransport
|
from gql.transport.aiohttp import AIOHTTPTransport
|
||||||
|
|
||||||
from services.db import local_session
|
from orm.shout import Shout, ShoutTopic
|
||||||
from orm.topic import Topic
|
from orm.topic import Topic
|
||||||
from orm.shout import ShoutTopic, Shout
|
from services.db import local_session
|
||||||
|
|
||||||
load_facts = gql(
|
load_facts = gql(
|
||||||
""" query getDomains {
|
""" query getDomains {
|
||||||
|
@ -60,7 +60,7 @@ class ViewedStorage:
|
||||||
pages = None
|
pages = None
|
||||||
domains = None
|
domains = None
|
||||||
period = 60 * 60 # every hour
|
period = 60 * 60 # every hour
|
||||||
client = None
|
client: Client | None = None
|
||||||
auth_result = None
|
auth_result = None
|
||||||
disabled = False
|
disabled = False
|
||||||
|
|
||||||
|
@ -70,7 +70,7 @@ class ViewedStorage:
|
||||||
self = ViewedStorage
|
self = ViewedStorage
|
||||||
async with self.lock:
|
async with self.lock:
|
||||||
if token:
|
if token:
|
||||||
self.client = create_client({"Authorization": "Bearer %s" % str(token)}, schema=schema_str)
|
self.client = create_client({"Authorization": f"Bearer {token}"}, schema=schema_str)
|
||||||
print("[services.viewed] * authorized permanently by ackee.discours.io: %s" % token)
|
print("[services.viewed] * authorized permanently by ackee.discours.io: %s" % token)
|
||||||
else:
|
else:
|
||||||
print("[services.viewed] * please set ACKEE_TOKEN")
|
print("[services.viewed] * please set ACKEE_TOKEN")
|
||||||
|
@ -83,22 +83,19 @@ class ViewedStorage:
|
||||||
start = time.time()
|
start = time.time()
|
||||||
self = ViewedStorage
|
self = ViewedStorage
|
||||||
try:
|
try:
|
||||||
async with self.client as session:
|
if self.client:
|
||||||
self.pages = await session.execute(load_pages)
|
self.pages = self.client.execute(load_pages)
|
||||||
self.pages = self.pages["domains"][0]["statistics"]["pages"]
|
self.pages = self.pages["domains"][0]["statistics"]["pages"]
|
||||||
shouts = {}
|
shouts = {}
|
||||||
try:
|
|
||||||
for page in self.pages:
|
for page in self.pages:
|
||||||
p = page["value"].split("?")[0]
|
p = page["value"].split("?")[0]
|
||||||
slug = p.split("discours.io/")[-1]
|
slug = p.split("discours.io/")[-1]
|
||||||
shouts[slug] = page["count"]
|
shouts[slug] = page["count"]
|
||||||
for slug in shouts.keys():
|
for slug in shouts.keys():
|
||||||
await ViewedStorage.increment(slug, shouts[slug])
|
await ViewedStorage.increment(slug, shouts[slug])
|
||||||
except Exception:
|
|
||||||
pass
|
|
||||||
print("[services.viewed] ⎪ %d pages collected " % len(shouts.keys()))
|
print("[services.viewed] ⎪ %d pages collected " % len(shouts.keys()))
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
raise e
|
raise Exception(e)
|
||||||
|
|
||||||
end = time.time()
|
end = time.time()
|
||||||
print("[services.viewed] ⎪ update_pages took %fs " % (end - start))
|
print("[services.viewed] ⎪ update_pages took %fs " % (end - start))
|
||||||
|
@ -106,8 +103,14 @@ class ViewedStorage:
|
||||||
@staticmethod
|
@staticmethod
|
||||||
async def get_facts():
|
async def get_facts():
|
||||||
self = ViewedStorage
|
self = ViewedStorage
|
||||||
|
facts = []
|
||||||
|
try:
|
||||||
|
if self.client:
|
||||||
async with self.lock:
|
async with self.lock:
|
||||||
return await self.client.execute(load_facts)
|
facts = self.client.execute(load_facts)
|
||||||
|
except Exception as er:
|
||||||
|
print(f"[services.viewed] get_facts error: {er}")
|
||||||
|
return facts or []
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
async def get_shout(shout_slug):
|
async def get_shout(shout_slug):
|
||||||
|
@ -138,7 +141,7 @@ class ViewedStorage:
|
||||||
"""updates topics counters by shout slug"""
|
"""updates topics counters by shout slug"""
|
||||||
self = ViewedStorage
|
self = ViewedStorage
|
||||||
with local_session() as session:
|
with local_session() as session:
|
||||||
for [shout_topic, topic] in (
|
for [_shout_topic, topic] in (
|
||||||
session.query(ShoutTopic, Topic).join(Topic).join(Shout).where(Shout.slug == shout_slug).all()
|
session.query(ShoutTopic, Topic).join(Topic).join(Shout).where(Shout.slug == shout_slug).all()
|
||||||
):
|
):
|
||||||
if not self.by_topics.get(topic.slug):
|
if not self.by_topics.get(topic.slug):
|
||||||
|
|
Loading…
Reference in New Issue
Block a user