drafts-orm-struct

This commit is contained in:
tonyrewin 2023-01-16 11:32:36 +03:00
parent 2017be82ee
commit 261b22716b
6 changed files with 88 additions and 43 deletions

View File

@ -1,22 +1,31 @@
from datetime import datetime
from sqlalchemy import Column, ForeignKey, DateTime, String
from sqlalchemy import Boolean, Column, ForeignKey, DateTime, String
from sqlalchemy.orm import relationship
from base.orm import Base
from orm.user import User
from orm.topic import Topic
class DraftTopic(Base):
__tablename__ = "draft_topic"
id = None # type: ignore
collab = Column(ForeignKey("draft_collab.id"), primary_key=True)
topic = Column(ForeignKey("topic.id"), primary_key=True)
class DraftAuthor(Base):
__tablename__ = "collab_author"
__tablename__ = "draft_author"
id = None # type: ignore
collab = Column(ForeignKey("collab.id"), primary_key=True)
collab = Column(ForeignKey("draft_collab.id"), primary_key=True)
author = Column(ForeignKey("user.id"), primary_key=True)
# accepted = Column(Boolean, default=False)
accepted = Column(Boolean, default=False)
class DraftCollab(Base):
__tablename__ = "draftcollab"
__tablename__ = "draft_collab"
slug = Column(String, nullable=True, comment="Slug")
title = Column(String, nullable=True, comment="Title")
@ -25,8 +34,7 @@ class DraftCollab(Base):
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__)
topics = relationship(lambda: Topic, secondary=DraftTopic.__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

@ -8,7 +8,8 @@ from resolvers.auth import (
get_current_user,
)
from resolvers.create.collab import remove_coauthor, invite_coauthor
from resolvers.create.collab import load_drafts, create_draft, update_draft, delete_draft,\
accept_coauthor, invite_coauthor
from resolvers.create.migrate import markdown_body
from resolvers.create.editor import create_shout, delete_shout, update_shout
@ -93,8 +94,12 @@ __all__ = [
# create.migrate
"markdown_body",
# create.collab
"load_drafts",
"create_draft",
"update_draft",
"delete_draft",
"invite_coauthor",
"remove_coauthor",
"accept_coauthor",
# zine.topics
"topics_all",
"topics_by_community",

View File

@ -3,33 +3,33 @@ from auth.credentials import AuthCredentials
from base.orm import local_session
from base.resolvers import query, mutation
from base.exceptions import ObjectNotExist, BaseHttpException
from orm.draft import DraftCollab, CollabAuthor
from orm.draft import DraftCollab, DraftAuthor, DraftTopic
from orm.shout import Shout
from orm.user import User
# TODO: use updatedAt
@query.field("loadDrafts")
@login_required
async def get_drafts(_, info):
async def load_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
}
return drafts
@mutation.field("createDraft") # TODO
@login_required
async def create_draft(_, info):
async def create_draft(_, info, draft_input):
auth: AuthCredentials = info.context["request"].auth
with local_session() as session:
pass
collab = DraftCollab.create(**draft_input)
session.add(collab)
session.commit()
# TODO: email notify to all authors
return {}
@mutation.field("deleteDraft") # TODO
@ -38,15 +38,29 @@ async def delete_draft(_, info, draft: int = 0):
auth: AuthCredentials = info.context["request"].auth
with local_session() as session:
pass
collab = session.query(DraftCollab).where(DraftCollab.id == draft_input.id).one()
if auth.user_id not in s.authors:
# raise BaseHttpException("only owner can remove coauthors")
return {
"error": "Only authors can update a draft"
}
elif not collab:
return {
"error": "There is no draft with this id"
}
else:
session.delete(collab)
session.commit()
return {}
@mutation.field("updateDraft") # TODO
@mutation.field("updateDraft") # TODO: draft input type
@login_required
async def update_draft(_, info, author: int = 0, draft: int = 0):
async def update_draft(_, info, draft_input):
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
collab = session.query(DraftCollab).where(DraftCollab.id == draft_input.id).one() # raises Error when not found
if auth.user_id not in s.authors:
# raise BaseHttpException("only owner can remove coauthors")
return {
@ -57,12 +71,8 @@ async def update_draft(_, info, author: int = 0, draft: int = 0):
"error": "There is no draft with this id"
}
else:
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)
draft_input["updatedAt"] = datetime.now(tz=timezone.utc)
collab.update(**draft_input)
session.commit()
# TODO: email notify
@ -80,11 +90,19 @@ async def invite_coauthor(_, info, author: int = 0, draft: int = 0):
return {
"error": "You are not in authors list"
}
else:
elif c.id:
invited_user = session.query(User).where(User.id == author).one()
c.invites.append(invited_user)
session.add(c)
da = DraftAuthor.create({
"accepted": False,
"collab": c.id,
"author": invited_user.id
})
session.add(da)
session.commit()
else:
return {
"error": "Draft is not found"
}
# TODO: email notify
return {}
@ -96,13 +114,17 @@ async def accept_coauthor(_, info, draft: int):
auth: AuthCredentials = info.context["request"].auth
with local_session() as session:
c = session.query(DraftCollab).where(DraftCollab.id == draft).one()
accepted = filter(lambda x: x.id == auth.user_id, c.invites).pop()
if accepted:
c.authors.append(accepted)
session.add(c)
# c = session.query(DraftCollab).where(DraftCollab.id == draft).one()
a = session.query(DraftAuthor).where(DraftAuthor.collab == draft).filter(DraftAuthor.author == auth.user_id).one()
if not a.accepted:
a.accepted = True
session.commit()
# TODO: email notify
return {}
elif a.accepted == True:
return {
"error": "You have accepted invite before"
}
else:
# raise BaseHttpException("only invited can accept")
return {

View File

@ -14,7 +14,7 @@ from resolvers.zine.reactions import reactions_follow, reactions_unfollow
from services.zine.gittask import GitTask
from resolvers.inbox.chats import create_chat
from services.inbox.storage import MessagesStorage
from orm.collab import Collab
from orm.draft import DraftCollab
@mutation.field("createShout")

View File

@ -219,10 +219,13 @@ def author_unfollow(user_id, slug):
).first()
)
if not flw:
raise Exception("[resolvers.profile] follower not exist, cant unfollow")
return {
"error": "Follower is not exist, cant unfollow"
}
else:
session.delete(flw)
session.commit()
return {}
@query.field("authorsAll")

View File

@ -69,6 +69,7 @@ type Result {
members: [ChatMember]
shout: Shout
shouts: [Shout]
drafts: [DraftCollab]
author: Author
authors: [Author]
reaction: Reaction
@ -538,10 +539,16 @@ type Chat {
private: Boolean
}
type Collab {
authors: [String]!
invites: [String]
shout: Shout
type DraftCollab {
slug: String
title: String
subtitle: String
body: String
cover: String
layout: String
authors: [Int]!
topics: [String]
chat: Chat
createdAt: Int!
updatedAt: Int
}