This commit is contained in:
tonyrewin 2023-01-13 14:04:45 +03:00
parent 92b1eae932
commit 2017be82ee
5 changed files with 122 additions and 80 deletions

View File

@ -1,27 +0,0 @@
from datetime import datetime
from sqlalchemy import Column, ForeignKey, DateTime, String
from sqlalchemy.orm import relationship
from base.orm import Base
from orm.user import User
class CollabAuthor(Base):
__tablename__ = "collab_author"
id = None # type: ignore
collab = Column(ForeignKey("collab.id"), primary_key=True)
author = Column(ForeignKey("user.id"), primary_key=True)
# accepted = Column(Boolean, default=False)
class Collab(Base):
__tablename__ = "collab"
title = Column(String, nullable=True, comment="Title")
body = Column(String, nullable=True, comment="Body")
pic = Column(String, nullable=True, comment="Picture")
authors = relationship(lambda: User, secondary=CollabAuthor.__tablename__)
# invites = relationship(lambda: User, secondary=CollabInvited.__tablename__)
createdAt = Column(DateTime, default=datetime.now, comment="Created At")
chat = Column(String, unique=True, nullable=False)

32
orm/draft.py Normal file
View File

@ -0,0 +1,32 @@
from datetime import datetime
from sqlalchemy import Column, ForeignKey, DateTime, String
from sqlalchemy.orm import relationship
from base.orm import Base
from orm.user import User
class DraftAuthor(Base):
__tablename__ = "collab_author"
id = None # type: ignore
collab = Column(ForeignKey("collab.id"), primary_key=True)
author = Column(ForeignKey("user.id"), primary_key=True)
# accepted = Column(Boolean, default=False)
class DraftCollab(Base):
__tablename__ = "draftcollab"
slug = Column(String, nullable=True, comment="Slug")
title = Column(String, nullable=True, comment="Title")
subtitle = Column(String, nullable=True, comment="Subtitle")
layout = Column(String, nullable=True, comment="Layout format")
body = Column(String, nullable=True, comment="Body")
cover = Column(String, nullable=True, comment="Cover")
authors = relationship(lambda: User, secondary=DraftAuthor.__tablename__)
topics = relationship(lambda: Topic, secondary=ShoutTopic.__tablename__)
invites = relationship(lambda: User, secondary=CollabInvited.__tablename__)
createdAt = Column(DateTime, default=datetime.now, comment="Created At")
updatedAt = Column(DateTime, default=datetime.now, comment="Updated At")
chat = Column(String, unique=True, nullable=True)

View File

@ -50,7 +50,7 @@ class Shout(Base):
subtitle = Column(String, nullable=True) subtitle = Column(String, nullable=True)
layout = Column(String, nullable=True) layout = Column(String, nullable=True)
mainTopic = Column(ForeignKey("topic.slug"), nullable=True) mainTopic = Column(ForeignKey("topic.slug"), nullable=True)
cover = Column(String, nullable=True) cover = Column(String, nullable=True, comment="Cover")
authors = relationship(lambda: User, secondary=ShoutAuthor.__tablename__) authors = relationship(lambda: User, secondary=ShoutAuthor.__tablename__)
topics = relationship(lambda: Topic, secondary=ShoutTopic.__tablename__) topics = relationship(lambda: Topic, secondary=ShoutTopic.__tablename__)
reactions = relationship(lambda: Reaction) reactions = relationship(lambda: Reaction)

View File

@ -3,34 +3,83 @@ from auth.credentials import AuthCredentials
from base.orm import local_session from base.orm import local_session
from base.resolvers import query, mutation from base.resolvers import query, mutation
from base.exceptions import ObjectNotExist, BaseHttpException from base.exceptions import ObjectNotExist, BaseHttpException
from orm.collab import Collab, CollabAuthor from orm.draft import DraftCollab, CollabAuthor
from orm.shout import Shout from orm.shout import Shout
from orm.user import User from orm.user import User
@query.field("getCollabs") # TODO: use updatedAt
@query.field("loadDrafts")
@login_required @login_required
async def get_collabs(_, info): async def get_drafts(_, info):
auth: AuthCredentials = info.context["request"].auth
drafts = []
with local_session() as session:
drafts = session.query(DraftCollab).filter(auth.user_id in DraftCollab.authors)
return {
"drafts": drafts
}
@mutation.field("createDraft") # TODO
@login_required
async def create_draft(_, info):
auth: AuthCredentials = info.context["request"].auth auth: AuthCredentials = info.context["request"].auth
with local_session() as session: with local_session() as session:
collabs = session.query(Collab).filter(auth.user_id in Collab.authors) pass
return collabs
@mutation.field("inviteCoauthor") @mutation.field("deleteDraft") # TODO
@login_required @login_required
async def invite_coauthor(_, info, author: int = 0, shout: int = 0): async def delete_draft(_, info, draft: int = 0):
auth: AuthCredentials = info.context["request"].auth auth: AuthCredentials = info.context["request"].auth
with local_session() as session: with local_session() as session:
s = session.query(Shout).where(Shout.id == shout).one() pass
if not s:
raise ObjectNotExist("invalid shout id") @mutation.field("updateDraft") # TODO
@login_required
async def update_draft(_, info, author: int = 0, draft: int = 0):
auth: AuthCredentials = info.context["request"].auth
with local_session() as session:
s = session.query(DraftCollab).where(DraftCollab.id == draft).one() # raises Error when not found
if auth.user_id not in s.authors:
# raise BaseHttpException("only owner can remove coauthors")
return {
"error": "Only authors can update draft"
}
elif not s:
return {
"error": "There is no draft with this id"
}
else: else:
c = session.query(Collab).where(Collab.shout == shout).one() c = session.query(DraftCollab).where(DraftCollab.id == draft).one()
ca = session.query(CollabAuthor).join(User).where(c.id == draft).filter(User.id == author).one()
session.remve(ca)
c.invites = filter(lambda x: x.id == author, c.invites)
c.authors = filter(lambda x: x.id == author, c.authors)
session.add(c)
session.commit()
# TODO: email notify
return {}
@mutation.field("inviteAuthor")
@login_required
async def invite_coauthor(_, info, author: int = 0, draft: int = 0):
auth: AuthCredentials = info.context["request"].auth
with local_session() as session:
c = session.query(DraftCollab).where(DraftCollab.id == draft).one()
if auth.user_id not in c.authors: if auth.user_id not in c.authors:
raise BaseHttpException("you are not in authors list") # raise BaseHttpException("you are not in authors list")
return {
"error": "You are not in authors list"
}
else: else:
invited_user = session.query(User).where(User.id == author).one() invited_user = session.query(User).where(User.id == author).one()
c.invites.append(invited_user) c.invites.append(invited_user)
@ -41,46 +90,21 @@ async def invite_coauthor(_, info, author: int = 0, shout: int = 0):
return {} return {}
@mutation.field("removeCoauthor") @mutation.field("inviteAccept")
@login_required @login_required
async def remove_coauthor(_, info, author: int = 0, shout: int = 0): async def accept_coauthor(_, info, draft: int):
auth: AuthCredentials = info.context["request"].auth auth: AuthCredentials = info.context["request"].auth
with local_session() as session: with local_session() as session:
s = session.query(Shout).where(Shout.id == shout).one() # raises Error when not found c = session.query(DraftCollab).where(DraftCollab.id == draft).one()
if auth.user_id not in s.authors:
raise BaseHttpException("only owner can remove coauthors")
else:
c = session.query(Collab).where(Collab.shout == shout).one()
ca = session.query(CollabAuthor).join(User).where(c.shout == shout, User.id == author).one()
session.remve(ca)
c.invites = filter(lambda x: x.id == author, c.invites)
c.authors = filter(lambda x: x.id == author, c.authors)
session.add(c)
session.commit()
# TODO: email notify
return {}
@mutation.field("acceptCoauthor")
@login_required
async def accept_coauthor(_, info, shout: int):
auth: AuthCredentials = info.context["request"].auth
with local_session() as session:
s = session.query(Shout).where(Shout.id == shout).one()
if not s:
raise ObjectNotExist("invalid shout id")
else:
c = session.query(Collab).where(Collab.shout == shout).one()
accepted = filter(lambda x: x.id == auth.user_id, c.invites).pop() accepted = filter(lambda x: x.id == auth.user_id, c.invites).pop()
if accepted: if accepted:
c.authors.append(accepted) c.authors.append(accepted)
s.authors.append(accepted)
session.add(s)
session.add(c) session.add(c)
session.commit() session.commit()
return {} return {}
else: else:
raise BaseHttpException("only invited can accept") # raise BaseHttpException("only invited can accept")
return {
"error": "You don't have an invitation yet"
}

View File

@ -128,6 +128,17 @@ input TopicInput {
# parents: [String] # parents: [String]
} }
input DraftInput {
slug: String
topics: [Int]
authors: [Int]
title: String
subtitle: String
body: String
cover: String
}
input ReactionInput { input ReactionInput {
kind: ReactionKind! kind: ReactionKind!
shout: Int! shout: Int!
@ -189,10 +200,12 @@ type Mutation {
updateReaction(reaction: ReactionInput!): Result! updateReaction(reaction: ReactionInput!): Result!
deleteReaction(reaction: Int!): Result! deleteReaction(reaction: Int!): Result!
# collab # draft / collab
inviteCoauthor(author: String!, shout: Int!): Result! createDraft(draft: DraftInput!): Result!
removeCoauthor(author: String!, shout: Int!): Result! updateDraft(draft: DraftInput!): Result!
acceptCoauthor(shout: Int!): Result! deleteDraft(draft: Int!): Result!
inviteAccept(draft: Int!): Result!
inviteAuthor(draft: Int!, author: Int!): Result!
# following # following
follow(what: FollowingEntity!, slug: String!): Result! follow(what: FollowingEntity!, slug: String!): Result!
@ -289,8 +302,8 @@ type Query {
authorsAll: [Author]! authorsAll: [Author]!
getAuthor(slug: String!): User getAuthor(slug: String!): User
# collab # draft/collab
getCollabs: [Collab]! loadDrafts: [DraftCollab]!
# migrate # migrate
markdownBody(body: String!): String! markdownBody(body: String!): String!