This commit is contained in:
parent
63eb952655
commit
fe4e37663e
3
main.py
3
main.py
|
@ -9,7 +9,8 @@ from sentry_sdk.integrations.sqlalchemy import SqlalchemyIntegration
|
|||
from sentry_sdk.integrations.starlette import StarletteIntegration
|
||||
from sentry_sdk.integrations.aiohttp import AioHttpIntegration
|
||||
from starlette.applications import Starlette
|
||||
from starlette.endpoints import HTTPEndpoint, Request
|
||||
from starlette.endpoints import HTTPEndpoint
|
||||
from starlette.requests import Request
|
||||
from starlette.responses import JSONResponse
|
||||
from starlette.routing import Route
|
||||
|
||||
|
|
|
@ -77,3 +77,25 @@ target-version = "py312"
|
|||
venvPath = "."
|
||||
venv = ".venv"
|
||||
include = ["."]
|
||||
useLibraryCodeForTypes = true
|
||||
disableLanguageServices = false
|
||||
disableOrganizeImports = false
|
||||
reportMissingImports = false
|
||||
reportMissingModuleSource = "warning"
|
||||
reportImportCycles = "warning"
|
||||
maxMemoryForLargeFile = 4096
|
||||
pythonVersion = "3.12"
|
||||
autoImportCompletions = true
|
||||
useVirtualEnv = true
|
||||
typeCheckingMode = "basic"
|
||||
disableJediCompletion = false
|
||||
disableCompletion = false
|
||||
disableSnippetCompletion = false
|
||||
disableGoToDefinition = false
|
||||
disableRenaming = false
|
||||
disableSignatureHelp = false
|
||||
diagnostics = true
|
||||
logLevel = "Information"
|
||||
pluginSearchPaths = []
|
||||
typings = {}
|
||||
mergeTypeStubPackages = false
|
||||
|
|
|
@ -140,6 +140,7 @@ async def get_authors_all(_, _info):
|
|||
|
||||
@query.field("get_author")
|
||||
async def get_author(_, _info, slug="", user=None, author_id=None):
|
||||
q = None
|
||||
if slug or user or author_id:
|
||||
if slug:
|
||||
q = select(Author).where(Author.slug == slug)
|
||||
|
|
|
@ -40,6 +40,7 @@ async def create_shout(_, info, inp):
|
|||
user_id = info.context["user_id"]
|
||||
with local_session() as session:
|
||||
author = session.query(Author).filter(Author.user == user_id).first()
|
||||
shout_dict = None
|
||||
if author:
|
||||
topics = session.query(Topic).filter(Topic.slug.in_(inp.get("topics", []))).all()
|
||||
authors = inp.get("authors", [])
|
||||
|
@ -55,7 +56,7 @@ async def create_shout(_, info, inp):
|
|||
"body": inp.get("body", ""),
|
||||
"layout": inp.get("layout"),
|
||||
"authors": authors,
|
||||
"slug": inp.get("slug"),
|
||||
"slug": inp.get("slug") or f"draft-{time.time()}",
|
||||
"topics": inp.get("topics"),
|
||||
"visibility": ShoutVisibility.AUTHORS,
|
||||
"created_at": current_time, # Set created_at as Unix timestamp
|
||||
|
@ -67,16 +68,13 @@ async def create_shout(_, info, inp):
|
|||
# NOTE: shout made by one first author
|
||||
sa = ShoutAuthor(shout=new_shout.id, author=author.id)
|
||||
session.add(sa)
|
||||
shout_dict = new_shout.dict()
|
||||
session.add(new_shout)
|
||||
reactions_follow(author.id, new_shout.id, True)
|
||||
session.commit()
|
||||
|
||||
if new_shout.slug is None:
|
||||
new_shout.slug = f"draft-{new_shout.id}"
|
||||
session.commit()
|
||||
else:
|
||||
await notify_shout(new_shout.dict(), "create")
|
||||
return {"shout": new_shout}
|
||||
await notify_shout(shout_dict, "create")
|
||||
return {"shout": shout_dict}
|
||||
|
||||
|
||||
@mutation.field("update_shout")
|
||||
|
@ -85,6 +83,8 @@ async def update_shout(_, info, shout_id, shout_input=None, publish=False):
|
|||
user_id = info.context["user_id"]
|
||||
with local_session() as session:
|
||||
author = session.query(Author).filter(Author.user == user_id).first()
|
||||
shout_dict = None
|
||||
current_time = int(time.time())
|
||||
if author:
|
||||
shout = (
|
||||
session.query(Shout)
|
||||
|
@ -99,7 +99,6 @@ async def update_shout(_, info, shout_id, shout_input=None, publish=False):
|
|||
return {"error": "shout not found"}
|
||||
if shout.created_by != author.id:
|
||||
return {"error": "access denied"}
|
||||
updated = False
|
||||
if shout_input is not None:
|
||||
topics_input = shout_input["topics"]
|
||||
del shout_input["topics"]
|
||||
|
@ -141,24 +140,22 @@ async def update_shout(_, info, shout_id, shout_input=None, publish=False):
|
|||
if shout_input["mainTopic"] == "":
|
||||
del shout_input["mainTopic"]
|
||||
# Replace datetime with Unix timestamp
|
||||
current_time = int(time.time())
|
||||
shout_input["updated_at"] = current_time # Set updated_at as Unix timestamp
|
||||
Shout.update(shout, shout_input)
|
||||
session.add(shout)
|
||||
updated = True
|
||||
# TODO: use visibility setting
|
||||
if publish and shout.visibility == ShoutVisibility.AUTHORS:
|
||||
shout.visibility = ShoutVisibility.COMMUNITY
|
||||
shout.published_at = current_time # Set published_at as Unix timestamp
|
||||
session.add(shout)
|
||||
updated = True
|
||||
# notify on publish
|
||||
await notify_shout(shout.dict(), "public")
|
||||
if updated:
|
||||
session.commit()
|
||||
if not publish:
|
||||
await notify_shout(shout.dict(), "update")
|
||||
return {"shout": shout}
|
||||
if publish:
|
||||
if shout.visibility is ShoutVisibility.AUTHORS:
|
||||
shout_dict = shout.dict()
|
||||
shout_dict['visibility'] = ShoutVisibility.COMMUNITY
|
||||
shout_dict['published_at'] = current_time # Set published_at as Unix timestamp
|
||||
Shout.update(shout, shout_dict)
|
||||
session.add(shout)
|
||||
await notify_shout(shout.dict(), "public")
|
||||
shout_dict = shout.dict()
|
||||
session.commit()
|
||||
if not publish:
|
||||
await notify_shout(shout_dict, "update")
|
||||
return {"shout": shout_dict}
|
||||
|
||||
|
||||
@mutation.field("delete_shout")
|
||||
|
@ -170,13 +167,17 @@ async def delete_shout(_, info, shout_id):
|
|||
shout = session.query(Shout).filter(Shout.id == shout_id).first()
|
||||
if not shout:
|
||||
return {"error": "invalid shout id"}
|
||||
if author.id not in shout.authors:
|
||||
return {"error": "access denied"}
|
||||
for author_id in shout.authors:
|
||||
reactions_unfollow(author_id, shout_id)
|
||||
# Replace datetime with Unix timestamp
|
||||
current_time = int(time.time())
|
||||
shout.deleted_at = current_time # Set deleted_at as Unix timestamp
|
||||
session.commit()
|
||||
await notify_shout(shout.dict(), "delete")
|
||||
if author:
|
||||
if author.id not in shout.authors:
|
||||
return {"error": "access denied"}
|
||||
for author_id in shout.authors:
|
||||
reactions_unfollow(author_id, shout_id)
|
||||
# Replace datetime with Unix timestamp
|
||||
current_time = int(time.time())
|
||||
shout_dict = shout.dict()
|
||||
shout_dict['deleted_at'] = current_time # Set deleted_at as Unix timestamp
|
||||
Shout.update(shout, shout_dict)
|
||||
session.add(shout)
|
||||
session.commit()
|
||||
await notify_shout(shout_dict, "delete")
|
||||
return {}
|
||||
|
|
|
@ -36,7 +36,7 @@ def add_reaction_stat_columns(q):
|
|||
return q
|
||||
|
||||
|
||||
def reactions_follow(author_id, shout_id: int, auto=False):
|
||||
def reactions_follow(author_id, shout_id, auto=False):
|
||||
try:
|
||||
with local_session() as session:
|
||||
shout = session.query(Shout).where(Shout.id == shout_id).one()
|
||||
|
@ -202,18 +202,22 @@ async def create_reaction(_, info, reaction):
|
|||
session.delete(opposite_reaction)
|
||||
|
||||
r = Reaction(**reaction)
|
||||
|
||||
rdict = r.dict()
|
||||
# Proposal accepting logix
|
||||
if r.reply_to is not None and r.kind == ReactionKind.ACCEPT and author.id in shout.dict()["authors"]:
|
||||
replied_reaction = session.query(Reaction).where(Reaction.id == r.reply_to).first()
|
||||
if replied_reaction and replied_reaction.kind == ReactionKind.PROPOSE:
|
||||
if replied_reaction.range:
|
||||
old_body = shout.body
|
||||
start, end = replied_reaction.range.split(":")
|
||||
start = int(start)
|
||||
end = int(end)
|
||||
new_body = old_body[:start] + replied_reaction.body + old_body[end:]
|
||||
shout.body = new_body
|
||||
if rdict.get("reply_to"):
|
||||
if r.kind is ReactionKind.ACCEPT and author.id in shout.authors:
|
||||
replied_reaction = session.query(Reaction).where(Reaction.id == r.reply_to).first()
|
||||
if replied_reaction:
|
||||
if replied_reaction.kind is ReactionKind.PROPOSE:
|
||||
if replied_reaction.range:
|
||||
old_body = shout.body
|
||||
start, end = replied_reaction.range.split(":")
|
||||
start = int(start)
|
||||
end = int(end)
|
||||
new_body = old_body[:start] + replied_reaction.body + old_body[end:]
|
||||
shout_dict = shout.dict()
|
||||
shout_dict['body'] = new_body
|
||||
Shout.update(shout, shout_dict)
|
||||
|
||||
session.add(r)
|
||||
session.commit()
|
||||
|
@ -294,13 +298,16 @@ async def delete_reaction(_, info, rid):
|
|||
return {"error": "invalid reaction id"}
|
||||
author = session.query(Author).filter(Author.user == user_id).first()
|
||||
if author:
|
||||
if r.created_by != author.id:
|
||||
if r.created_by is author.id:
|
||||
return {"error": "access denied"}
|
||||
|
||||
if r.kind in [ReactionKind.LIKE, ReactionKind.DISLIKE]:
|
||||
session.delete(r)
|
||||
else:
|
||||
r.deleted_at = int(time.time())
|
||||
rdict = r.dict()
|
||||
rdict["deleted_at"] = int(time.time())
|
||||
Reaction.update(r, rdict)
|
||||
session.add(r)
|
||||
session.commit()
|
||||
|
||||
await notify_reaction(r.dict(), "delete")
|
||||
|
@ -358,7 +365,7 @@ async def load_reactions_by(_, info, by, limit=50, offset=0):
|
|||
q = q.filter(Reaction.created_at > after)
|
||||
|
||||
order_way = asc if by.get("sort", "").startswith("-") else desc
|
||||
order_field = by.get("sort", "").replace("-", "") or Reaction.created_at
|
||||
order_field = by.get("sort", "").replace("-", "") or "created_at"
|
||||
q = q.group_by(Reaction.id, Author.id, Shout.id).order_by(order_way(order_field))
|
||||
q = add_reaction_stat_columns(q)
|
||||
q = q.where(Reaction.deleted_at.is_(None))
|
||||
|
@ -398,10 +405,11 @@ def reacted_shouts_updates(follower_id: int, limit=50, offset=0) -> List[Shout]:
|
|||
shouts = (
|
||||
session.query(Shout)
|
||||
.join(Reaction)
|
||||
.filter(Reaction.created_by == author.id)
|
||||
.filter(Reaction.created_by == follower_id)
|
||||
.filter(Reaction.created_at > author.last_seen)
|
||||
.limit(limit)
|
||||
.offset(offset)
|
||||
.all()
|
||||
)
|
||||
return shouts
|
||||
|
||||
|
@ -414,7 +422,8 @@ async def load_shouts_followed(_, info, limit=50, offset=0) -> List[Shout]:
|
|||
with local_session() as session:
|
||||
author = session.query(Author).filter(Author.user == user_id).first()
|
||||
if author:
|
||||
shouts = reacted_shouts_updates(author.id, limit, offset)
|
||||
author_id: int = author.dict()['id']
|
||||
shouts = reacted_shouts_updates(author_id, limit, offset)
|
||||
return shouts
|
||||
else:
|
||||
return []
|
||||
|
|
Loading…
Reference in New Issue
Block a user