proposals and refactoring
This commit is contained in:
parent
30c51ecac1
commit
11f81d46ce
|
@ -6,9 +6,13 @@ from orm.notification import Notification
|
||||||
from orm.shout import Shout, ShoutAuthor, ShoutTopic, ShoutRating, ShoutViewByDay,\
|
from orm.shout import Shout, ShoutAuthor, ShoutTopic, ShoutRating, ShoutViewByDay,\
|
||||||
ShoutRatingStorage, ShoutViewStorage
|
ShoutRatingStorage, ShoutViewStorage
|
||||||
from orm.base import Base, engine, local_session
|
from orm.base import Base, engine, local_session
|
||||||
from orm.comment import Comment, CommentRating
|
from orm.comment import Comment, CommentRating #, CommentRatingStorage
|
||||||
|
from orm.proposal import Proposal, ProposalRating #, ProposalRatingStorage
|
||||||
|
|
||||||
__all__ = ["User", "Role", "Community", "Operation", "Permission", "Shout", "Topic", "TopicSubscription", "Notification", "ShoutRating", "Comment", "CommentRating", "UserRating"]
|
__all__ = ["User", "Role", "Community", "Operation", \
|
||||||
|
"Permission", "Shout", "Topic", "TopicSubscription", \
|
||||||
|
"Notification", "ShoutRating", "Comment", "CommentRating", \
|
||||||
|
"UserRating", "Proposal", "ProposalRating"]
|
||||||
|
|
||||||
Base.metadata.create_all(engine)
|
Base.metadata.create_all(engine)
|
||||||
Operation.init_table()
|
Operation.init_table()
|
||||||
|
@ -19,6 +23,8 @@ Role.init_table()
|
||||||
|
|
||||||
with local_session() as session:
|
with local_session() as session:
|
||||||
ShoutRatingStorage.init(session)
|
ShoutRatingStorage.init(session)
|
||||||
|
# CommentRatingStorage.init(session)
|
||||||
|
# ProposalRatingStorage.init(session)
|
||||||
ShoutViewStorage.init(session)
|
ShoutViewStorage.init(session)
|
||||||
RoleStorage.init(session)
|
RoleStorage.init(session)
|
||||||
UserStorage.init(session)
|
UserStorage.init(session)
|
||||||
|
|
|
@ -1,23 +1,33 @@
|
||||||
from typing import List
|
from typing import List
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from sqlalchemy import Column, Integer, String, ForeignKey, Datetime
|
from sqlalchemy import Column, Integer, String, ForeignKey, DateTime
|
||||||
|
from sqlalchemy.orm import relationship
|
||||||
from orm import Permission
|
from orm import Permission
|
||||||
from orm.base import Base
|
from orm.base import Base
|
||||||
|
|
||||||
|
|
||||||
class Proposal(Base):
|
class ProposalRating(Base):
|
||||||
__tablename__ = 'proposal'
|
__tablename__ = "comment_rating"
|
||||||
|
|
||||||
shout: int = Column(Integer, ForeignKey("shout.id"), nullable=False, comment="Shout")
|
id = None
|
||||||
range: str = Column(String, nullable=True, comment="Range in format <start index>:<end>")
|
proposal_id = Column(ForeignKey('proposal.id'), primary_key = True)
|
||||||
body: str = Column(String, nullable=False, comment="Body")
|
createdBy = Column(ForeignKey('user.slug'), primary_key = True)
|
||||||
createdBy: int = Column(Integer, ForeignKey("user.id"), nullable=False, comment="Author")
|
createdAt: str = Column(DateTime, nullable=False, default = datetime.now, comment="Timestamp")
|
||||||
createdAt: str = Column(datetime, nullable=False, comment="Created at")
|
value = Column(Integer)
|
||||||
updatedAt: str = Column(datetime, nullable=True, comment="Updated at")
|
|
||||||
acceptedAt: str = Column(datetime, nullable=True, comment="Accepted at")
|
class Proposal(Base):
|
||||||
acceptedBy: str = Column(datetime, nullable=True, comment="Accepted by")
|
__tablename__ = 'proposal'
|
||||||
deletedAt: str = Column(datetime, nullable=True, comment="Deleted at")
|
|
||||||
declinedAt: str = Column(datetime, nullable=True, comment="Declined at)
|
shout: str = Column(String, ForeignKey("shout.slug"), nullable=False, comment="Shout")
|
||||||
declinedBy: str = Column(datetime, nullable=True, comment="Declined by")
|
range: str = Column(String, nullable=True, comment="Range in format <start index>:<end>")
|
||||||
# TODO: debug, logix
|
body: str = Column(String, nullable=False, comment="Body")
|
||||||
|
createdBy: int = Column(Integer, ForeignKey("user.id"), nullable=False, comment="Author")
|
||||||
|
createdAt: str = Column(DateTime, nullable=False, comment="Created at")
|
||||||
|
updatedAt: str = Column(DateTime, nullable=True, comment="Updated at")
|
||||||
|
acceptedAt: str = Column(DateTime, nullable=True, comment="Accepted at")
|
||||||
|
acceptedBy: str = Column(Integer, ForeignKey("user.id"), nullable=True, comment="Accepted by")
|
||||||
|
declinedAt: str = Column(DateTime, nullable=True, comment="Declined at")
|
||||||
|
declinedBy: str = Column(Integer, ForeignKey("user.id"), nullable=True, comment="Declined by")
|
||||||
|
ratings = relationship(ProposalRating, foreign_keys=ProposalRating.proposal_id)
|
||||||
|
deletedAt: str = Column(DateTime, nullable=True, comment="Deleted at")
|
||||||
|
# TODO: debug, logix
|
|
@ -1,42 +1,74 @@
|
||||||
from resolvers.auth import login, sign_out, is_email_used, register, confirm
|
from resolvers.auth import login, sign_out, is_email_used, register, confirm, auth_forget, auth_reset
|
||||||
from resolvers.zine import create_shout, get_shout_by_slug, \
|
from resolvers.zine import get_shout_by_slug, subscribe, unsubscribe, view_shout, rate_shout, \
|
||||||
top_month, top_overall, recent_published, recent_all, top_viewed, \
|
top_month, top_overall, recent_published, recent_all, top_viewed, \
|
||||||
shouts_by_authors, shouts_by_topics, shouts_by_communities, \
|
shouts_by_authors, shouts_by_topics, shouts_by_communities
|
||||||
shouts_reviewed, shouts_subscribed
|
from resolvers.profile import get_users_by_slugs, get_current_user, shouts_reviewed, shouts_subscribed
|
||||||
from resolvers.profile import get_users_by_slugs, get_current_user
|
|
||||||
from resolvers.topics import topic_subscribe, topic_unsubscribe, topics_by_author, \
|
from resolvers.topics import topic_subscribe, topic_unsubscribe, topics_by_author, \
|
||||||
topics_by_community, topics_by_slugs
|
topics_by_community, topics_by_slugs
|
||||||
from resolvers.comments import create_comment
|
from resolvers.comments import create_comment, delete_comment, update_comment, rate_comment
|
||||||
|
from resolvers.collab import get_shout_proposals, create_proposal, delete_proposal, \
|
||||||
|
update_proposal, rate_proposal, decline_proposal, disable_proposal, accept_proposal
|
||||||
|
from resolvers.editor import create_shout, delete_shout, update_shout
|
||||||
from resolvers.community import create_community, delete_community, get_community, get_communities
|
from resolvers.community import create_community, delete_community, get_community, get_communities
|
||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
"login",
|
# auth
|
||||||
"register",
|
"login",
|
||||||
"is_email_used",
|
"register",
|
||||||
"confirm",
|
"is_email_used",
|
||||||
# TODO: "reset_password_code",
|
"confirm",
|
||||||
# TODO: "reset_password_confirm",
|
"auth_forget",
|
||||||
"create_shout",
|
"auth_reset"
|
||||||
"get_current_user",
|
|
||||||
"get_users_by_slugs",
|
# profile
|
||||||
"get_shout_by_slug",
|
"get_current_user",
|
||||||
"recent_published",
|
"get_users_by_slugs",
|
||||||
"recent_all",
|
|
||||||
"shouts_by_topics",
|
# zine
|
||||||
"shouts_by_authors",
|
"recent_published",
|
||||||
"shouts_by_communities",
|
"recent_all",
|
||||||
"shouts_subscribed",
|
"shouts_by_topics",
|
||||||
"shouts_reviewed",
|
"shouts_by_authors",
|
||||||
"top_month",
|
"shouts_by_communities",
|
||||||
"top_overall",
|
"shouts_subscribed",
|
||||||
"top_viewed",
|
"shouts_reviewed",
|
||||||
"topics_by_slugs",
|
"top_month",
|
||||||
"topics_by_community",
|
"top_overall",
|
||||||
"topics_by_author",
|
"top_viewed",
|
||||||
"topic_subscribe",
|
"rate_shout",
|
||||||
"topic_unsubscribe",
|
"view_shout",
|
||||||
"create_community",
|
"get_shout_by_slug",
|
||||||
"delete_community",
|
|
||||||
"get_community",
|
# editor
|
||||||
"get_communities"
|
"create_shout",
|
||||||
]
|
"update_shout",
|
||||||
|
"delete_shout",
|
||||||
|
|
||||||
|
# topics
|
||||||
|
"topics_by_slugs",
|
||||||
|
"topics_by_community",
|
||||||
|
"topics_by_author",
|
||||||
|
"topic_subscribe",
|
||||||
|
"topic_unsubscribe",
|
||||||
|
|
||||||
|
# communities
|
||||||
|
"get_community",
|
||||||
|
"get_communities",
|
||||||
|
"create_community",
|
||||||
|
"delete_community",
|
||||||
|
|
||||||
|
# comments
|
||||||
|
"get_shout_comments",
|
||||||
|
"create_comment",
|
||||||
|
"update_comment",
|
||||||
|
"delete_comment",
|
||||||
|
|
||||||
|
# collab
|
||||||
|
"get_shout_proposals",
|
||||||
|
"create_proposal",
|
||||||
|
"update_proposal",
|
||||||
|
"disable_proposal",
|
||||||
|
"accept_proposal",
|
||||||
|
"decline_proposal",
|
||||||
|
"delete_proposal"
|
||||||
|
]
|
||||||
|
|
|
@ -18,6 +18,7 @@ from settings import JWT_AUTH_HEADER
|
||||||
|
|
||||||
@mutation.field("confirmEmail")
|
@mutation.field("confirmEmail")
|
||||||
async def confirm(*_, confirm_token):
|
async def confirm(*_, confirm_token):
|
||||||
|
''' confirm owning email address '''
|
||||||
auth_token, user = await Authorize.confirm(confirm_token)
|
auth_token, user = await Authorize.confirm(confirm_token)
|
||||||
if auth_token:
|
if auth_token:
|
||||||
user.emailConfirmed = True
|
user.emailConfirmed = True
|
||||||
|
@ -29,6 +30,7 @@ async def confirm(*_, confirm_token):
|
||||||
|
|
||||||
@mutation.field("registerUser")
|
@mutation.field("registerUser")
|
||||||
async def register(*_, email: str, password: str = ""):
|
async def register(*_, email: str, password: str = ""):
|
||||||
|
''' creates new user account '''
|
||||||
with local_session() as session:
|
with local_session() as session:
|
||||||
user = session.query(User).filter(User.email == email).first()
|
user = session.query(User).filter(User.email == email).first()
|
||||||
if user:
|
if user:
|
||||||
|
@ -51,7 +53,8 @@ async def register(*_, email: str, password: str = ""):
|
||||||
return { "user": user }
|
return { "user": user }
|
||||||
|
|
||||||
@mutation.field("requestPasswordUpdate")
|
@mutation.field("requestPasswordUpdate")
|
||||||
async def request_password_update(_, info, email):
|
async def auth_forget(_, info, email):
|
||||||
|
''' send email to recover account '''
|
||||||
with local_session() as session:
|
with local_session() as session:
|
||||||
user = session.query(User).filter(User.email == email).first()
|
user = session.query(User).filter(User.email == email).first()
|
||||||
if not user:
|
if not user:
|
||||||
|
@ -62,9 +65,10 @@ async def request_password_update(_, info, email):
|
||||||
return {}
|
return {}
|
||||||
|
|
||||||
@mutation.field("updatePassword")
|
@mutation.field("updatePassword")
|
||||||
async def update_password(_, info, password, token):
|
async def auth_reset(_, info, password, resetToken):
|
||||||
|
''' set the new password '''
|
||||||
try:
|
try:
|
||||||
user_id = await ResetPassword.verify(token)
|
user_id = await ResetPassword.verify(resetToken)
|
||||||
except InvalidToken as e:
|
except InvalidToken as e:
|
||||||
return {"error" : e.message}
|
return {"error" : e.message}
|
||||||
|
|
||||||
|
@ -79,6 +83,7 @@ async def update_password(_, info, password, token):
|
||||||
|
|
||||||
@query.field("signIn")
|
@query.field("signIn")
|
||||||
async def login(_, info: GraphQLResolveInfo, email: str, password: str = ""):
|
async def login(_, info: GraphQLResolveInfo, email: str, password: str = ""):
|
||||||
|
|
||||||
with local_session() as session:
|
with local_session() as session:
|
||||||
orm_user = session.query(User).filter(User.email == email).first()
|
orm_user = session.query(User).filter(User.email == email).first()
|
||||||
if orm_user is None:
|
if orm_user is None:
|
||||||
|
@ -126,4 +131,4 @@ async def sign_out(_, info: GraphQLResolveInfo):
|
||||||
async def is_email_used(_, info, email):
|
async def is_email_used(_, info, email):
|
||||||
with local_session() as session:
|
with local_session() as session:
|
||||||
user = session.query(User).filter(User.email == email).first()
|
user = session.query(User).filter(User.email == email).first()
|
||||||
return not user is None
|
return not user is None
|
191
resolvers/collab.py
Normal file
191
resolvers/collab.py
Normal file
|
@ -0,0 +1,191 @@
|
||||||
|
from orm import Proposal, ProposalRating, UserStorage
|
||||||
|
from orm.base import local_session
|
||||||
|
from resolvers.base import mutation, query, subscription
|
||||||
|
from auth.authenticate import login_required
|
||||||
|
import asyncio
|
||||||
|
from datetime import datetime
|
||||||
|
|
||||||
|
|
||||||
|
class ProposalResult:
|
||||||
|
def __init__(self, status, proposal):
|
||||||
|
self.status = status
|
||||||
|
self.proposal = proposal
|
||||||
|
|
||||||
|
@query.field("getShoutProposals")
|
||||||
|
@login_required
|
||||||
|
async def get_shout_proposals(_, info, slug):
|
||||||
|
auth = info.context["request"].auth
|
||||||
|
user_id = auth.user_id
|
||||||
|
with local_session() as session:
|
||||||
|
proposals = session.query(Proposal).\
|
||||||
|
options(selectinload(Proposal.ratings)).\
|
||||||
|
filter(Proposal.shout == slug).\
|
||||||
|
group_by(Proposal.id).all()
|
||||||
|
shout = session.query(Shout).filter(Shout.slug == slug).first()
|
||||||
|
authors = [author.id for author in shout.authors]
|
||||||
|
if user_id not in authors:
|
||||||
|
return {"error": "access denied"}
|
||||||
|
for proposal in proposals:
|
||||||
|
proposal.createdBy = await UserStorage.get_user(proposal.createdBy)
|
||||||
|
return proposals
|
||||||
|
|
||||||
|
|
||||||
|
@mutation.field("createProposal")
|
||||||
|
@login_required
|
||||||
|
async def create_proposal(_, info, body, shout, range = None):
|
||||||
|
auth = info.context["request"].auth
|
||||||
|
user_id = auth.user_id
|
||||||
|
|
||||||
|
proposal = Proposal.create(
|
||||||
|
createdBy = user_id,
|
||||||
|
body = body,
|
||||||
|
shout = shout,
|
||||||
|
range = range
|
||||||
|
)
|
||||||
|
|
||||||
|
result = ProposalResult("NEW", proposal)
|
||||||
|
await ProposalSubscriptions.put(result)
|
||||||
|
|
||||||
|
return {"proposal": proposal}
|
||||||
|
|
||||||
|
@mutation.field("updateProposal")
|
||||||
|
@login_required
|
||||||
|
async def update_proposal(_, info, id, body):
|
||||||
|
auth = info.context["request"].auth
|
||||||
|
user_id = auth.user_id
|
||||||
|
|
||||||
|
with local_session() as session:
|
||||||
|
proposal = session.query(Proposal).filter(Proposal.id == id).first()
|
||||||
|
shout = session.query(Shout).filter(Shout.sllug == proposal.shout).first()
|
||||||
|
authors = [author.id for author in shout.authors]
|
||||||
|
if not proposal:
|
||||||
|
return {"error": "invalid proposal id"}
|
||||||
|
if proposal.author in authors:
|
||||||
|
return {"error": "access denied"}
|
||||||
|
proposal.body = body
|
||||||
|
proposal.updatedAt = datetime.now()
|
||||||
|
session.commit()
|
||||||
|
|
||||||
|
result = ProposalResult("UPDATED", proposal)
|
||||||
|
await ProposalSubscriptions.put(result)
|
||||||
|
|
||||||
|
return {"proposal": proposal}
|
||||||
|
|
||||||
|
@mutation.field("deleteProposal")
|
||||||
|
@login_required
|
||||||
|
async def delete_proposal(_, info, id):
|
||||||
|
auth = info.context["request"].auth
|
||||||
|
user_id = auth.user_id
|
||||||
|
|
||||||
|
with local_session() as session:
|
||||||
|
proposal = session.query(Proposal).filter(Proposal.id == id).first()
|
||||||
|
if not proposal:
|
||||||
|
return {"error": "invalid proposal id"}
|
||||||
|
if proposal.createdBy != user_id:
|
||||||
|
return {"error": "access denied"}
|
||||||
|
|
||||||
|
proposal.deletedAt = datetime.now()
|
||||||
|
session.commit()
|
||||||
|
|
||||||
|
result = ProposalResult("DELETED", proposal)
|
||||||
|
await ProposalSubscriptions.put(result)
|
||||||
|
|
||||||
|
return {}
|
||||||
|
|
||||||
|
@mutation.field("disableProposal")
|
||||||
|
@login_required
|
||||||
|
async def disable_proposal(_, info, id):
|
||||||
|
auth = info.context["request"].auth
|
||||||
|
user_id = auth.user_id
|
||||||
|
|
||||||
|
with local_session() as session:
|
||||||
|
proposal = session.query(Proposal).filter(Proposal.id == id).first()
|
||||||
|
if not proposal:
|
||||||
|
return {"error": "invalid proposal id"}
|
||||||
|
if proposal.createdBy != user_id:
|
||||||
|
return {"error": "access denied"}
|
||||||
|
|
||||||
|
proposal.deletedAt = datetime.now()
|
||||||
|
session.commit()
|
||||||
|
|
||||||
|
result = ProposalResult("DISABLED", proposal)
|
||||||
|
await ProposalSubscriptions.put(result)
|
||||||
|
|
||||||
|
return {}
|
||||||
|
|
||||||
|
@mutation.field("rateProposal")
|
||||||
|
@login_required
|
||||||
|
async def rate_proposal(_, info, id, value):
|
||||||
|
auth = info.context["request"].auth
|
||||||
|
user_id = auth.user_id
|
||||||
|
|
||||||
|
with local_session() as session:
|
||||||
|
proposal = session.query(Proposal).filter(Proposal.id == id).first()
|
||||||
|
if not proposal:
|
||||||
|
return {"error": "invalid proposal id"}
|
||||||
|
|
||||||
|
rating = session.query(ProposalRating).\
|
||||||
|
filter(ProposalRating.proposal_id == id and ProposalRating.createdBy == user_id).first()
|
||||||
|
if rating:
|
||||||
|
rating.value = value
|
||||||
|
session.commit()
|
||||||
|
|
||||||
|
if not rating:
|
||||||
|
ProposalRating.create(
|
||||||
|
proposal_id = id,
|
||||||
|
createdBy = user_id,
|
||||||
|
value = value)
|
||||||
|
|
||||||
|
result = ProposalResult("UPDATED_RATING", proposal)
|
||||||
|
await ProposalSubscriptions.put(result)
|
||||||
|
|
||||||
|
return {}
|
||||||
|
|
||||||
|
|
||||||
|
@mutation.field("acceptProposal")
|
||||||
|
@login_required
|
||||||
|
async def accept_proposal(_, info, id):
|
||||||
|
auth = info.context["request"].auth
|
||||||
|
user_id = auth.user_id
|
||||||
|
|
||||||
|
with local_session() as session:
|
||||||
|
proposal = session.query(Proposal).filter(Proposal.id == id).first()
|
||||||
|
shout = session.query(Shout).filter(Shout.slug == proposal.shout).first()
|
||||||
|
authors = [author.id for author in shout.authors]
|
||||||
|
if not proposal:
|
||||||
|
return {"error": "invalid proposal id"}
|
||||||
|
if user_id not in authors:
|
||||||
|
return {"error": "access denied"}
|
||||||
|
|
||||||
|
proposal.acceptedAt = datetime.now()
|
||||||
|
proposal.acceptedBy = user_id
|
||||||
|
session.commit()
|
||||||
|
|
||||||
|
result = ProposalResult("ACCEPTED", proposal)
|
||||||
|
await ProposalSubscriptions.put(result)
|
||||||
|
|
||||||
|
return {}
|
||||||
|
|
||||||
|
@mutation.field("declineProposal")
|
||||||
|
@login_required
|
||||||
|
async def decline_proposal(_, info, id):
|
||||||
|
auth = info.context["request"].auth
|
||||||
|
user_id = auth.user_id
|
||||||
|
|
||||||
|
with local_session() as session:
|
||||||
|
proposal = session.query(Proposal).filter(Proposal.id == id).first()
|
||||||
|
shout = session.query(Shout).filter(Shout.slug == proposal.shout).first()
|
||||||
|
authors = [author.id for author in shout.authors]
|
||||||
|
if not proposal:
|
||||||
|
return {"error": "invalid proposal id"}
|
||||||
|
if user_id not in authors:
|
||||||
|
return {"error": "access denied"}
|
||||||
|
|
||||||
|
proposal.acceptedAt = datetime.now()
|
||||||
|
proposal.acceptedBy = user_id
|
||||||
|
session.commit()
|
||||||
|
|
||||||
|
result = ProposalResult("DECLINED", proposal)
|
||||||
|
await ProposalSubscriptions.put(result)
|
||||||
|
|
||||||
|
return {}
|
|
@ -1,123 +1,109 @@
|
||||||
from orm import Proposal, ProposalRating
|
from orm import Shout, ShoutRating, ShoutRatingStorage
|
||||||
from orm.base import local_session
|
from orm.base import local_session
|
||||||
from resolvers.base import mutation, query, subscription
|
from resolvers.base import mutation, query, subscription
|
||||||
from auth.authenticate import login_required
|
from auth.authenticate import login_required
|
||||||
import asyncio
|
import asyncio
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
class ProposalResult:
|
|
||||||
def __init__(self, status, proposal):
|
|
||||||
self.status = status
|
|
||||||
self.proposal = proposal
|
|
||||||
|
|
||||||
@mutation.field("createProposal")
|
@mutation.field("createShout")
|
||||||
@login_required
|
@login_required
|
||||||
async def create_proposal(_, info, body, shout, range = None):
|
async def create_shout(_, info, input):
|
||||||
|
user = info.context["request"].user
|
||||||
|
|
||||||
|
topic_slugs = input.get("topic_slugs", [])
|
||||||
|
if topic_slugs:
|
||||||
|
del input["topic_slugs"]
|
||||||
|
|
||||||
|
new_shout = Shout.create(**input)
|
||||||
|
ShoutAuthor.create(
|
||||||
|
shout = new_shout.slug,
|
||||||
|
user = user.slug)
|
||||||
|
|
||||||
|
if "mainTopic" in input:
|
||||||
|
topic_slugs.append(input["mainTopic"])
|
||||||
|
|
||||||
|
for slug in topic_slugs:
|
||||||
|
topic = ShoutTopic.create(
|
||||||
|
shout = new_shout.slug,
|
||||||
|
topic = slug)
|
||||||
|
new_shout.topic_slugs = topic_slugs
|
||||||
|
|
||||||
|
task = GitTask(
|
||||||
|
input,
|
||||||
|
user.username,
|
||||||
|
user.email,
|
||||||
|
"new shout %s" % (new_shout.slug)
|
||||||
|
)
|
||||||
|
|
||||||
|
await ShoutSubscriptions.send_shout(new_shout)
|
||||||
|
|
||||||
|
return {
|
||||||
|
"shout" : new_shout
|
||||||
|
}
|
||||||
|
|
||||||
|
@mutation.field("updateShout")
|
||||||
|
@login_required
|
||||||
|
async def update_shout(_, info, input):
|
||||||
auth = info.context["request"].auth
|
auth = info.context["request"].auth
|
||||||
user_id = auth.user_id
|
user_id = auth.user_id
|
||||||
|
|
||||||
proposal = Proposal.create(
|
slug = input["slug"]
|
||||||
createdBy = user_id,
|
|
||||||
body = body,
|
session = local_session()
|
||||||
shout = shout,
|
user = session.query(User).filter(User.id == user_id).first()
|
||||||
range = range
|
shout = session.query(Shout).filter(Shout.slug == slug).first()
|
||||||
|
|
||||||
|
if not shout:
|
||||||
|
return {
|
||||||
|
"error" : "shout not found"
|
||||||
|
}
|
||||||
|
|
||||||
|
authors = [author.id for author in shout.authors]
|
||||||
|
if not user_id in authors:
|
||||||
|
scopes = auth.scopes
|
||||||
|
print(scopes)
|
||||||
|
if not Resource.shout_id in scopes:
|
||||||
|
return {
|
||||||
|
"error" : "access denied"
|
||||||
|
}
|
||||||
|
|
||||||
|
shout.update(input)
|
||||||
|
shout.updatedAt = datetime.now()
|
||||||
|
session.commit()
|
||||||
|
session.close()
|
||||||
|
|
||||||
|
for topic in input.get("topic_slugs", []):
|
||||||
|
ShoutTopic.create(
|
||||||
|
shout = slug,
|
||||||
|
topic = topic)
|
||||||
|
|
||||||
|
task = GitTask(
|
||||||
|
input,
|
||||||
|
user.username,
|
||||||
|
user.email,
|
||||||
|
"update shout %s" % (slug)
|
||||||
)
|
)
|
||||||
|
|
||||||
result = ProposalResult("NEW", proposal)
|
return {
|
||||||
await ProposalSubscriptions.put(result)
|
"shout" : shout
|
||||||
|
}
|
||||||
|
|
||||||
return {"proposal": proposal}
|
@mutation.field("deleteShout")
|
||||||
|
|
||||||
@mutation.field("updateProposal")
|
|
||||||
@login_required
|
@login_required
|
||||||
async def update_proposal(_, info, id, body):
|
async def delete_shout(_, info, slug):
|
||||||
auth = info.context["request"].auth
|
auth = info.context["request"].auth
|
||||||
user_id = auth.user_id
|
user_id = auth.user_id
|
||||||
|
|
||||||
with local_session() as session:
|
with local_session() as session:
|
||||||
proposal = session.query(Proposal).filter(Proposal.id == id).first()
|
shout = session.query(Shout).filter(Shout.slug == slug).first()
|
||||||
shout = session.query(Shout.slug === proposal.shout)
|
authors = [author.id for author in shout.authors]
|
||||||
if not proposal:
|
if not comment:
|
||||||
return {"error": "invalid proposal id"}
|
return {"error": "invalid shout slug"}
|
||||||
if proposal.author != user_id:
|
if user_id not in authors:
|
||||||
return {"error": "access denied"}
|
|
||||||
proposal.body = body
|
|
||||||
proposal.updatedAt = datetime.now()
|
|
||||||
session.commit()
|
|
||||||
|
|
||||||
result = ProposalResult("UPDATED", proposal)
|
|
||||||
await ProposalSubscriptions.put(result)
|
|
||||||
|
|
||||||
return {"proposal": proposal}
|
|
||||||
|
|
||||||
@mutation.field("deleteProposal")
|
|
||||||
@login_required
|
|
||||||
async def delete_proposal(_, info, id):
|
|
||||||
auth = info.context["request"].auth
|
|
||||||
user_id = auth.user_id
|
|
||||||
|
|
||||||
with local_session() as session:
|
|
||||||
proposal = session.query(Proposal).filter(Proposal.id == id).first()
|
|
||||||
if not proposal:
|
|
||||||
return {"error": "invalid proposal id"}
|
|
||||||
if proposal.createdBy != user_id:
|
|
||||||
return {"error": "access denied"}
|
return {"error": "access denied"}
|
||||||
|
|
||||||
proposal.deletedAt = datetime.now()
|
shout.deletedAt = datetime.now()
|
||||||
session.commit()
|
session.commit()
|
||||||
|
|
||||||
result = ProposalResult("DELETED", proposal)
|
return {}
|
||||||
await ProposalSubscriptions.put(result)
|
|
||||||
|
|
||||||
return {}
|
|
||||||
|
|
||||||
@mutation.field("rateProposal")
|
|
||||||
@login_required
|
|
||||||
async def rate_proposal(_, info, id, value):
|
|
||||||
auth = info.context["request"].auth
|
|
||||||
user_id = auth.user_id
|
|
||||||
|
|
||||||
with local_session() as session:
|
|
||||||
proposal = session.query(Proposal).filter(Proposal.id == id).first()
|
|
||||||
if not proposal:
|
|
||||||
return {"error": "invalid proposal id"}
|
|
||||||
|
|
||||||
rating = session.query(ProposalRating).\
|
|
||||||
filter(ProposalRating.proposal_id == id and ProposalRating.createdBy == user_id).first()
|
|
||||||
if rating:
|
|
||||||
rating.value = value
|
|
||||||
session.commit()
|
|
||||||
|
|
||||||
if not rating:
|
|
||||||
ProposalRating.create(
|
|
||||||
proposal_id = id,
|
|
||||||
createdBy = user_id,
|
|
||||||
value = value)
|
|
||||||
|
|
||||||
result = ProposalResult("UPDATED_RATING", proposal)
|
|
||||||
await ProposalSubscriptions.put(result)
|
|
||||||
|
|
||||||
return {}
|
|
||||||
|
|
||||||
|
|
||||||
@mutation.field("acceptProposal")
|
|
||||||
@login_required
|
|
||||||
async def accept_proposal(_, info, id):
|
|
||||||
auth = info.context["request"].auth
|
|
||||||
user_id = auth.user_id
|
|
||||||
|
|
||||||
with local_session() as session:
|
|
||||||
proposal = session.query(Proposal).filter(Proposal.id == id).first()
|
|
||||||
if not proposal:
|
|
||||||
return {"error": "invalid proposal id"}
|
|
||||||
if proposal.acceptedBy == user_id: # TODO: manage ACL here to give access all editors
|
|
||||||
return {"error": "access denied"}
|
|
||||||
|
|
||||||
proposal.acceptedAt = datetime.now()
|
|
||||||
proposal.acceptedBy = user_id
|
|
||||||
session.commit()
|
|
||||||
|
|
||||||
result = ProposalResult("ACCEPTED", proposal)
|
|
||||||
await ProposalSubscriptions.put(result)
|
|
||||||
|
|
||||||
return {}
|
|
|
@ -153,36 +153,95 @@ def author_unsubscribe(user, slug):
|
||||||
session.delete(sub)
|
session.delete(sub)
|
||||||
session.commit()
|
session.commit()
|
||||||
|
|
||||||
@mutation.field("subscribe")
|
@query.field("shoutsRatedByUser")
|
||||||
@login_required
|
@login_required
|
||||||
async def subscribe(_, info, subscription, slug):
|
async def shouts_rated_by_user(_, info, page, size):
|
||||||
user = info.context["request"].user
|
user = info.context["request"].user
|
||||||
|
|
||||||
try:
|
with local_session() as session:
|
||||||
if subscription == "AUTHOR":
|
shouts = session.query(Shout).\
|
||||||
author_subscribe(user, slug)
|
join(ShoutRating).\
|
||||||
elif subscription == "TOPIC":
|
where(ShoutRating.rater == user.slug).\
|
||||||
topic_subscribe(user, slug)
|
order_by(desc(ShoutRating.ts)).\
|
||||||
elif subscription == "COMMUNITY":
|
limit(size).\
|
||||||
community_subscribe(user, slug)
|
offset( (page - 1) * size)
|
||||||
except Exception as e:
|
|
||||||
return {"error" : e}
|
|
||||||
|
|
||||||
return {}
|
return {
|
||||||
|
"shouts" : shouts
|
||||||
|
}
|
||||||
|
|
||||||
@mutation.field("unsubscribe")
|
@query.field("userUnpublishedShouts")
|
||||||
@login_required
|
@login_required
|
||||||
async def unsubscribe(_, info, subscription, slug):
|
async def user_unpublished_shouts(_, info, page, size):
|
||||||
user = info.context["request"].user
|
user = info.context["request"].user
|
||||||
|
|
||||||
try:
|
with local_session() as session:
|
||||||
if subscription == "AUTHOR":
|
shouts = session.query(Shout).\
|
||||||
author_unsubscribe(user, slug)
|
join(ShoutAuthor).\
|
||||||
elif subscription == "TOPIC":
|
where(and_(Shout.publishedAt == None, ShoutAuthor.user == user.slug)).\
|
||||||
topic_unsubscribe(user, slug)
|
order_by(desc(Shout.createdAt)).\
|
||||||
elif subscription == "COMMUNITY":
|
limit(size).\
|
||||||
community_unsubscribe(user, slug)
|
offset( (page - 1) * size)
|
||||||
except Exception as e:
|
|
||||||
return {"error" : e}
|
return {
|
||||||
|
"shouts" : shouts
|
||||||
|
}
|
||||||
|
|
||||||
|
@query.field("shoutsReviewed")
|
||||||
|
@login_required
|
||||||
|
async def shouts_reviewed(_, info, page, size):
|
||||||
|
user = info.context["request"].user
|
||||||
|
with local_session() as session:
|
||||||
|
shouts_by_rating = session.query(Shout).\
|
||||||
|
join(ShoutRating).\
|
||||||
|
where(and_(Shout.publishedAt != None, ShoutRating.rater == user.slug))
|
||||||
|
shouts_by_comment = session.query(Shout).\
|
||||||
|
join(Comment).\
|
||||||
|
where(and_(Shout.publishedAt != None, Comment.author == user.id))
|
||||||
|
shouts = shouts_by_rating.union(shouts_by_comment).\
|
||||||
|
order_by(desc(Shout.publishedAt)).\
|
||||||
|
limit(size).\
|
||||||
|
offset( (page - 1) * size)
|
||||||
|
|
||||||
|
return shouts
|
||||||
|
|
||||||
|
@query.field("shoutsSubscribed")
|
||||||
|
@login_required
|
||||||
|
async def shouts_subscribed(_, info, page, size):
|
||||||
|
user = info.context["request"].user
|
||||||
|
with local_session() as session:
|
||||||
|
shouts_by_topic = session.query(Shout).\
|
||||||
|
join(ShoutTopic).\
|
||||||
|
join(TopicSubscription, ShoutTopic.topic == TopicSubscription.topic).\
|
||||||
|
where(TopicSubscription.subscriber == user.slug)
|
||||||
|
shouts_by_author = session.query(Shout).\
|
||||||
|
join(ShoutAuthor).\
|
||||||
|
join(AuthorSubscription, ShoutAuthor.user == AuthorSubscription.author).\
|
||||||
|
where(AuthorSubscription.subscriber == user.slug)
|
||||||
|
shouts_by_community = session.query(Shout).\
|
||||||
|
join(Community).\
|
||||||
|
join(CommunitySubscription).\
|
||||||
|
where(CommunitySubscription.subscriber == user.slug)
|
||||||
|
shouts = shouts_by_topic.union(shouts_by_author).\
|
||||||
|
union(shouts_by_community).\
|
||||||
|
order_by(desc(Shout.createdAt)).\
|
||||||
|
limit(size).\
|
||||||
|
offset( (page - 1) * size)
|
||||||
|
|
||||||
|
return shouts
|
||||||
|
|
||||||
|
@query.field("shoutsCommentedByUser")
|
||||||
|
async def shouts_commented_by_user(_, info, slug, page, size):
|
||||||
|
user = await UserStorage.get_user_by_slug(slug)
|
||||||
|
if not user:
|
||||||
|
return {}
|
||||||
|
|
||||||
|
with local_session() as session:
|
||||||
|
shouts = session.query(Shout).\
|
||||||
|
join(Comment).\
|
||||||
|
where(Comment.author == user.id).\
|
||||||
|
order_by(desc(Comment.createdAt)).\
|
||||||
|
limit(size).\
|
||||||
|
offset( (page - 1) * size)
|
||||||
|
return shouts
|
||||||
|
|
||||||
return {}
|
|
||||||
|
|
|
@ -257,113 +257,6 @@ async def recent_commented(_, info, page, size):
|
||||||
async with ShoutsCache.lock:
|
async with ShoutsCache.lock:
|
||||||
return ShoutsCache.recent_commented[(page - 1) * size : page * size]
|
return ShoutsCache.recent_commented[(page - 1) * size : page * size]
|
||||||
|
|
||||||
@mutation.field("createShout")
|
|
||||||
@login_required
|
|
||||||
async def create_shout(_, info, input):
|
|
||||||
user = info.context["request"].user
|
|
||||||
|
|
||||||
topic_slugs = input.get("topic_slugs", [])
|
|
||||||
if topic_slugs:
|
|
||||||
del input["topic_slugs"]
|
|
||||||
|
|
||||||
new_shout = Shout.create(**input)
|
|
||||||
ShoutAuthor.create(
|
|
||||||
shout = new_shout.slug,
|
|
||||||
user = user.slug)
|
|
||||||
|
|
||||||
if "mainTopic" in input:
|
|
||||||
topic_slugs.append(input["mainTopic"])
|
|
||||||
|
|
||||||
for slug in topic_slugs:
|
|
||||||
topic = ShoutTopic.create(
|
|
||||||
shout = new_shout.slug,
|
|
||||||
topic = slug)
|
|
||||||
new_shout.topic_slugs = topic_slugs
|
|
||||||
|
|
||||||
task = GitTask(
|
|
||||||
input,
|
|
||||||
user.username,
|
|
||||||
user.email,
|
|
||||||
"new shout %s" % (new_shout.slug)
|
|
||||||
)
|
|
||||||
|
|
||||||
await ShoutSubscriptions.send_shout(new_shout)
|
|
||||||
|
|
||||||
return {
|
|
||||||
"shout" : new_shout
|
|
||||||
}
|
|
||||||
|
|
||||||
@mutation.field("updateShout")
|
|
||||||
@login_required
|
|
||||||
async def update_shout(_, info, input):
|
|
||||||
auth = info.context["request"].auth
|
|
||||||
user_id = auth.user_id
|
|
||||||
|
|
||||||
slug = input["slug"]
|
|
||||||
|
|
||||||
session = local_session()
|
|
||||||
user = session.query(User).filter(User.id == user_id).first()
|
|
||||||
shout = session.query(Shout).filter(Shout.slug == slug).first()
|
|
||||||
|
|
||||||
if not shout:
|
|
||||||
return {
|
|
||||||
"error" : "shout not found"
|
|
||||||
}
|
|
||||||
|
|
||||||
authors = [author.id for author in shout.authors]
|
|
||||||
if not user_id in authors:
|
|
||||||
scopes = auth.scopes
|
|
||||||
print(scopes)
|
|
||||||
if not Resource.shout_id in scopes:
|
|
||||||
return {
|
|
||||||
"error" : "access denied"
|
|
||||||
}
|
|
||||||
|
|
||||||
shout.update(input)
|
|
||||||
shout.updatedAt = datetime.now()
|
|
||||||
session.commit()
|
|
||||||
session.close()
|
|
||||||
|
|
||||||
for topic in input.get("topic_slugs", []):
|
|
||||||
ShoutTopic.create(
|
|
||||||
shout = slug,
|
|
||||||
topic = topic)
|
|
||||||
|
|
||||||
task = GitTask(
|
|
||||||
input,
|
|
||||||
user.username,
|
|
||||||
user.email,
|
|
||||||
"update shout %s" % (slug)
|
|
||||||
)
|
|
||||||
|
|
||||||
return {
|
|
||||||
"shout" : shout
|
|
||||||
}
|
|
||||||
|
|
||||||
@mutation.field("rateShout")
|
|
||||||
@login_required
|
|
||||||
async def rate_shout(_, info, slug, value):
|
|
||||||
auth = info.context["request"].auth
|
|
||||||
user = info.context["request"].user
|
|
||||||
|
|
||||||
with local_session() as session:
|
|
||||||
rating = session.query(ShoutRating).\
|
|
||||||
filter(and_(ShoutRating.rater == user.slug, ShoutRating.shout == slug)).first()
|
|
||||||
if rating:
|
|
||||||
rating.value = value;
|
|
||||||
rating.ts = datetime.now()
|
|
||||||
session.commit()
|
|
||||||
else:
|
|
||||||
rating = ShoutRating.create(
|
|
||||||
rater = user.slug,
|
|
||||||
shout = slug,
|
|
||||||
value = value
|
|
||||||
)
|
|
||||||
|
|
||||||
await ShoutRatingStorage.update_rating(rating)
|
|
||||||
|
|
||||||
return {"error" : ""}
|
|
||||||
|
|
||||||
@mutation.field("viewShout")
|
@mutation.field("viewShout")
|
||||||
async def view_shout(_, info, slug):
|
async def view_shout(_, info, slug):
|
||||||
await ShoutViewStorage.inc_view(slug)
|
await ShoutViewStorage.inc_view(slug)
|
||||||
|
@ -439,94 +332,61 @@ async def shouts_by_communities(_, info, slugs, page, size):
|
||||||
offset(page * size)
|
offset(page * size)
|
||||||
return shouts
|
return shouts
|
||||||
|
|
||||||
@query.field("shoutsSubscribed")
|
@mutation.field("subscribe")
|
||||||
@login_required
|
@login_required
|
||||||
async def shouts_subscribed(_, info, page, size):
|
async def subscribe(_, info, subscription, slug):
|
||||||
user = info.context["request"].user
|
user = info.context["request"].user
|
||||||
with local_session() as session:
|
|
||||||
shouts_by_topic = session.query(Shout).\
|
|
||||||
join(ShoutTopic).\
|
|
||||||
join(TopicSubscription, ShoutTopic.topic == TopicSubscription.topic).\
|
|
||||||
where(TopicSubscription.subscriber == user.slug)
|
|
||||||
shouts_by_author = session.query(Shout).\
|
|
||||||
join(ShoutAuthor).\
|
|
||||||
join(AuthorSubscription, ShoutAuthor.user == AuthorSubscription.author).\
|
|
||||||
where(AuthorSubscription.subscriber == user.slug)
|
|
||||||
shouts_by_community = session.query(Shout).\
|
|
||||||
join(Community).\
|
|
||||||
join(CommunitySubscription).\
|
|
||||||
where(CommunitySubscription.subscriber == user.slug)
|
|
||||||
shouts = shouts_by_topic.union(shouts_by_author).\
|
|
||||||
union(shouts_by_community).\
|
|
||||||
order_by(desc(Shout.createdAt)).\
|
|
||||||
limit(size).\
|
|
||||||
offset( (page - 1) * size)
|
|
||||||
|
|
||||||
return shouts
|
try:
|
||||||
|
if subscription == "AUTHOR":
|
||||||
|
author_subscribe(user, slug)
|
||||||
|
elif subscription == "TOPIC":
|
||||||
|
topic_subscribe(user, slug)
|
||||||
|
elif subscription == "COMMUNITY":
|
||||||
|
community_subscribe(user, slug)
|
||||||
|
except Exception as e:
|
||||||
|
return {"error" : e}
|
||||||
|
|
||||||
@query.field("shoutsReviewed")
|
return {}
|
||||||
|
|
||||||
|
@mutation.field("unsubscribe")
|
||||||
@login_required
|
@login_required
|
||||||
async def shouts_reviewed(_, info, page, size):
|
async def unsubscribe(_, info, subscription, slug):
|
||||||
user = info.context["request"].user
|
user = info.context["request"].user
|
||||||
with local_session() as session:
|
|
||||||
shouts_by_rating = session.query(Shout).\
|
|
||||||
join(ShoutRating).\
|
|
||||||
where(and_(Shout.publishedAt != None, ShoutRating.rater == user.slug))
|
|
||||||
shouts_by_comment = session.query(Shout).\
|
|
||||||
join(Comment).\
|
|
||||||
where(and_(Shout.publishedAt != None, Comment.author == user.id))
|
|
||||||
shouts = shouts_by_rating.union(shouts_by_comment).\
|
|
||||||
order_by(desc(Shout.publishedAt)).\
|
|
||||||
limit(size).\
|
|
||||||
offset( (page - 1) * size)
|
|
||||||
|
|
||||||
return shouts
|
try:
|
||||||
|
if subscription == "AUTHOR":
|
||||||
|
author_unsubscribe(user, slug)
|
||||||
|
elif subscription == "TOPIC":
|
||||||
|
topic_unsubscribe(user, slug)
|
||||||
|
elif subscription == "COMMUNITY":
|
||||||
|
community_unsubscribe(user, slug)
|
||||||
|
except Exception as e:
|
||||||
|
return {"error" : e}
|
||||||
|
|
||||||
@query.field("shoutsCommentedByUser")
|
return {}
|
||||||
async def shouts_commented_by_user(_, info, slug, page, size):
|
|
||||||
user = await UserStorage.get_user_by_slug(slug)
|
|
||||||
if not user:
|
|
||||||
return {}
|
|
||||||
|
|
||||||
with local_session() as session:
|
|
||||||
shouts = session.query(Shout).\
|
|
||||||
join(Comment).\
|
|
||||||
where(Comment.author == user.id).\
|
|
||||||
order_by(desc(Comment.createdAt)).\
|
|
||||||
limit(size).\
|
|
||||||
offset( (page - 1) * size)
|
|
||||||
return shouts
|
|
||||||
|
|
||||||
@query.field("shoutsRatedByUser")
|
@mutation.field("rateShout")
|
||||||
@login_required
|
@login_required
|
||||||
async def shouts_rated_by_user(_, info, page, size):
|
async def rate_shout(_, info, slug, value):
|
||||||
|
auth = info.context["request"].auth
|
||||||
user = info.context["request"].user
|
user = info.context["request"].user
|
||||||
|
|
||||||
with local_session() as session:
|
with local_session() as session:
|
||||||
shouts = session.query(Shout).\
|
rating = session.query(ShoutRating).\
|
||||||
join(ShoutRating).\
|
filter(and_(ShoutRating.rater == user.slug, ShoutRating.shout == slug)).first()
|
||||||
where(ShoutRating.rater == user.slug).\
|
if rating:
|
||||||
order_by(desc(ShoutRating.ts)).\
|
rating.value = value;
|
||||||
limit(size).\
|
rating.ts = datetime.now()
|
||||||
offset( (page - 1) * size)
|
session.commit()
|
||||||
|
else:
|
||||||
|
rating = ShoutRating.create(
|
||||||
|
rater = user.slug,
|
||||||
|
shout = slug,
|
||||||
|
value = value
|
||||||
|
)
|
||||||
|
|
||||||
return {
|
await ShoutRatingStorage.update_rating(rating)
|
||||||
"shouts" : shouts
|
|
||||||
}
|
|
||||||
|
|
||||||
@query.field("userUnpublishedShouts")
|
return {"error" : ""}
|
||||||
@login_required
|
|
||||||
async def user_unpublished_shouts(_, info, page, size):
|
|
||||||
user = info.context["request"].user
|
|
||||||
|
|
||||||
with local_session() as session:
|
|
||||||
shouts = session.query(Shout).\
|
|
||||||
join(ShoutAuthor).\
|
|
||||||
where(and_(Shout.publishedAt == None, ShoutAuthor.user == user.slug)).\
|
|
||||||
order_by(desc(Shout.createdAt)).\
|
|
||||||
limit(size).\
|
|
||||||
offset( (page - 1) * size)
|
|
||||||
|
|
||||||
return {
|
|
||||||
"shouts" : shouts
|
|
||||||
}
|
|
|
@ -126,15 +126,26 @@ type Mutation {
|
||||||
createTopic(input: TopicInput!): TopicResult!
|
createTopic(input: TopicInput!): TopicResult!
|
||||||
updateTopic(input: TopicInput!): TopicResult!
|
updateTopic(input: TopicInput!): TopicResult!
|
||||||
|
|
||||||
|
# comments
|
||||||
createComment(body: String!, shout: String!, replyTo: Int): CommentResult!
|
createComment(body: String!, shout: String!, replyTo: Int): CommentResult!
|
||||||
updateComment(id: Int!, body: String!): CommentResult!
|
updateComment(id: Int!, body: String!): CommentResult!
|
||||||
deleteComment(id: Int!): Result!
|
deleteComment(id: Int!): Result!
|
||||||
rateComment(id: Int!, value: Int!): Result!
|
rateComment(id: Int!, value: Int!): Result!
|
||||||
|
|
||||||
|
# community
|
||||||
createCommunity(title: String!, desc: String!): Community!
|
createCommunity(title: String!, desc: String!): Community!
|
||||||
updateCommunity(community: CommunityInput!): Community!
|
updateCommunity(community: CommunityInput!): Community!
|
||||||
deleteCommunity(id: Int!): Result!
|
deleteCommunity(id: Int!): Result!
|
||||||
|
|
||||||
|
# proposal
|
||||||
|
createProposal(body: String!, range: String): Proposal!
|
||||||
|
updateProposal(body: String!, range: String): Proposal!
|
||||||
|
acceptProposal(id: Int!): Result!
|
||||||
|
declineProposal(id: Int!): Result!
|
||||||
|
disableProposal(id: Int!): Result!
|
||||||
|
deleteProposal(id: Int!): Result!
|
||||||
|
rateProposal(id: Int!): Result!
|
||||||
|
|
||||||
subscribe(what: SubscriptionType!, slug: String!): Result!
|
subscribe(what: SubscriptionType!, slug: String!): Result!
|
||||||
unsubscribe(what: SubscriptionType!, slug: String!): Result!
|
unsubscribe(what: SubscriptionType!, slug: String!): Result!
|
||||||
}
|
}
|
||||||
|
@ -167,6 +178,9 @@ type Query {
|
||||||
shoutsByCommunities(slugs: [String]!, page: Int!, size: Int!): [Shout]!
|
shoutsByCommunities(slugs: [String]!, page: Int!, size: Int!): [Shout]!
|
||||||
getShoutComments(slug: String!): [Comment]!
|
getShoutComments(slug: String!): [Comment]!
|
||||||
|
|
||||||
|
# collab
|
||||||
|
getShoutProposals(slug: String!): [Proposal]!
|
||||||
|
|
||||||
# mainpage
|
# mainpage
|
||||||
topViewed(page: Int!, size: Int!): [Shout]!
|
topViewed(page: Int!, size: Int!): [Shout]!
|
||||||
topMonth(page: Int!, size: Int!): [Shout]!
|
topMonth(page: Int!, size: Int!): [Shout]!
|
||||||
|
@ -353,17 +367,29 @@ type Topic {
|
||||||
topicStat: TopicStat
|
topicStat: TopicStat
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum ProposalStatus {
|
||||||
|
NEW
|
||||||
|
UPDATED
|
||||||
|
UPDATED_RATING
|
||||||
|
ACCEPTED
|
||||||
|
DECLINED
|
||||||
|
DISABLED
|
||||||
|
DELETED
|
||||||
|
}
|
||||||
|
|
||||||
type Proposal {
|
type Proposal {
|
||||||
createdBy: String!
|
shout: String!
|
||||||
shout: string!
|
|
||||||
range: String # full / 0:2340
|
range: String # full / 0:2340
|
||||||
body: String!
|
body: String!
|
||||||
createdAt: DateTime!
|
createdAt: DateTime!
|
||||||
|
createdBy: String!
|
||||||
updatedAt: DateTime
|
updatedAt: DateTime
|
||||||
acceptedAt: DateTime
|
acceptedAt: DateTime
|
||||||
acceptedBy: string
|
acceptedBy: Int
|
||||||
declinedAt: DateTime
|
declinedAt: DateTime
|
||||||
declinedBy: string
|
declinedBy: Int
|
||||||
|
disabledAt: DateTime
|
||||||
|
disabledBy: Int
|
||||||
}
|
}
|
||||||
|
|
||||||
type Token {
|
type Token {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user