commynity-cudl
All checks were successful
Deploy on push / deploy (push) Successful in 1m5s

This commit is contained in:
Untone 2024-10-21 16:42:30 +03:00
parent c6f160c8cf
commit a4e48eb3f4
6 changed files with 106 additions and 4 deletions

View File

@ -7,6 +7,9 @@
- reaction filter by kinds - reaction filter by kinds
- reaction sort enum added - reaction sort enum added
- community follower roles enum added - community follower roles enum added
- invite status enum added
- topic parents ids added
- community CUDL resolvers added
[0.4.4] [0.4.4]
- followers_stat removed for shout - followers_stat removed for shout

View File

@ -1,11 +1,12 @@
import enum import enum
import time import time
from sqlalchemy import ARRAY, Column, ForeignKey, Integer, String, func from sqlalchemy import ARRAY, Column, ForeignKey, Integer, String, distinct, func
from sqlalchemy.ext.hybrid import hybrid_property from sqlalchemy.ext.hybrid import hybrid_property
from sqlalchemy.orm import relationship from sqlalchemy.orm import relationship
from orm.author import Author from orm.author import Author
from orm.shout import Shout
from services.db import Base from services.db import Base
@ -45,8 +46,7 @@ class Community(Base):
desc = Column(String, nullable=False, default="") desc = Column(String, nullable=False, default="")
pic = Column(String, nullable=False, default="") pic = Column(String, nullable=False, default="")
created_at = Column(Integer, nullable=False, default=lambda: int(time.time())) created_at = Column(Integer, nullable=False, default=lambda: int(time.time()))
created_by = Column(ForeignKey("author.id"), nullable=False)
authors = relationship(Author, secondary="community_author")
@hybrid_property @hybrid_property
def stat(self): def stat(self):
@ -74,3 +74,15 @@ class CommunityStats:
.filter(CommunityFollower.community == self.community.id) .filter(CommunityFollower.community == self.community.id)
.scalar() .scalar()
) )
@property
def authors(self):
# author has a shout with community id and featured_at is not null
return (
self.community.session.query(func.count(distinct(Author.id)))
.join(Shout)
.filter(
Shout.community_id == self.community.id, Shout.featured_at.is_not(None), Author.id.in_(Shout.authors)
)
.scalar()
)

View File

@ -1,7 +1,7 @@
from orm.author import Author from orm.author import Author
from orm.community import Community, CommunityFollower from orm.community import Community, CommunityFollower
from services.db import local_session from services.db import local_session
from services.schema import query from services.schema import mutation, query
@query.field("get_communities_all") @query.field("get_communities_all")
@ -29,3 +29,69 @@ async def get_communities_by_author(_, _info, slug="", user="", author_id=0):
q = q.where(CommunityFollower.author == author_id) q = q.where(CommunityFollower.author == author_id)
return q.all() return q.all()
return [] return []
@mutation.field("join_community")
async def join_community(_, info, slug: str):
author_dict = info.context.get("author", {})
author_id = author_dict.get("id")
with local_session() as session:
community = session.query(Community).where(Community.slug == slug).first()
if not community:
return {"ok": False, "error": "Community not found"}
session.add(CommunityFollower(community=community.id, author=author_id))
session.commit()
return {"ok": True}
@mutation.field("leave_community")
async def leave_community(_, info, slug: str):
author_dict = info.context.get("author", {})
author_id = author_dict.get("id")
with local_session() as session:
session.query(CommunityFollower).where(
CommunityFollower.author == author_id, CommunityFollower.community == slug
).delete()
session.commit()
return {"ok": True}
@mutation.field("create_community")
async def create_community(_, info, community_data):
author_dict = info.context.get("author", {})
author_id = author_dict.get("id")
with local_session() as session:
session.add(Community(author=author_id, **community_data))
session.commit()
return {"ok": True}
@mutation.field("update_community")
async def update_community(_, info, community_data):
author_dict = info.context.get("author", {})
author_id = author_dict.get("id")
slug = community_data.get("slug")
if slug:
with local_session() as session:
try:
session.query(Community).where(Community.created_by == author_id, Community.slug == slug).update(
community_data
)
session.commit()
except Exception as e:
return {"ok": False, "error": str(e)}
return {"ok": True}
return {"ok": False, "error": "Please, set community slug in input"}
@mutation.field("delete_community")
async def delete_community(_, info, slug: str):
author_dict = info.context.get("author", {})
author_id = author_dict.get("id")
with local_session() as session:
try:
session.query(Community).where(Community.slug == slug, Community.created_by == author_id).delete()
session.commit()
return {"ok": True}
except Exception as e:
return {"ok": False, "error": str(e)}

View File

@ -85,3 +85,10 @@ input NotificationSeenInput {
notifications: [Int] notifications: [Int]
thread: Int thread: Int
} }
input CommunityInput {
slug: String
name: String
desc: String
pic: String
}

View File

@ -36,4 +36,11 @@ type Mutation {
notification_mark_seen(notification_id: Int!, seen: Boolean): CommonResult! notification_mark_seen(notification_id: Int!, seen: Boolean): CommonResult!
notifications_seen_after(after: Int!, seen: Boolean): CommonResult! notifications_seen_after(after: Int!, seen: Boolean): CommonResult!
notifications_seen_thread(thread_id: String!, seen: Boolean): CommonResult! notifications_seen_thread(thread_id: String!, seen: Boolean): CommonResult!
# community
join_community(slug: String!): CommonResult!
leave_community(slug: String!): CommonResult!
create_community(input: CommunityInput!): CommonResult!
update_community(input: CommunityInput!): CommonResult!
delete_community(slug: String!): CommonResult!
} }

View File

@ -99,6 +99,12 @@ type Stat {
last_reacted_at: Int last_reacted_at: Int
} }
type CommunityStat {
shouts: Int!
followers: Int!
authors: Int!
}
type Community { type Community {
id: Int! id: Int!
slug: String! slug: String!
@ -107,6 +113,7 @@ type Community {
pic: String! pic: String!
created_at: Int! created_at: Int!
created_by: Author! created_by: Author!
stat: CommunityStat
} }
type Collection { type Collection {