diff --git a/freak/models.py b/freak/models.py index 0cbc61a..d34d567 100644 --- a/freak/models.py +++ b/freak/models.py @@ -16,7 +16,7 @@ from sqlalchemy import Column, Integer, String, ForeignKey, UniqueConstraint, an SmallInteger, select, update, Table from sqlalchemy.orm import Relationship, relationship from suou.sqlalchemy_async import SQLAlchemy -from suou import SiqType, Snowflake, Wanted, deprecated, makelist, not_implemented +from suou import SiqType, Snowflake, Wanted, deprecated, makelist, not_implemented, want_isodate from suou.sqlalchemy import create_session, declarative_base, id_column, parent_children, snowflake_column from werkzeug.security import check_password_hash @@ -706,6 +706,18 @@ class Comment(Base): def url(self): return self.parent_post.url() + f'/comment/{Snowflake(self.id):l}' + async def is_parent_locked(self): + if self.is_locked: + return True + if self.parent_comment_id == None: + return False + async with db as session: + parent = (await session.execute(select(Comment).where(Comment.id == self.parent_comment_id))).scalar() + try: + return parent.is_parent_locked() + except RecursionError: + return True + def report_url(self) -> str: return f'/report/comment/{Snowflake(self.id):l}' @@ -721,6 +733,21 @@ class Comment(Base): def not_removed(cls): return Post.removed_at == None + async def section_info(self): + obj = dict( + id = Snowflake(self.id).to_b32l(), + parent = dict(id=Snowflake(self.parent_comment_id)) if self.parent_comment_id else None, + locked = await self.is_parent_locked(), + created_at = want_isodate(self.created_at) + ) + if self.is_removed: + obj['removed'] = self.removed_reason + else: + obj['content'] = self.text_content + + return obj + + class PostReport(Base): __tablename__ = 'freak_postreport' diff --git a/freak/rest/__init__.py b/freak/rest/__init__.py index 5656d2f..60bec90 100644 --- a/freak/rest/__init__.py +++ b/freak/rest/__init__.py @@ -17,7 +17,7 @@ from freak.accounts import LoginStatus, check_login from freak.algorithms import public_timeline, top_guilds_query, topic_timeline, user_timeline from freak.search import SearchQuery -from ..models import Guild, Post, PostUpvote, User, db +from ..models import Comment, Guild, Post, PostUpvote, User, db from .. import UserLoader, app, app_config, __version__ as freak_version, csrf bp = Blueprint('rest', __name__, url_prefix='/v1') @@ -192,7 +192,25 @@ async def upvote_post(id: int, data: VoteIn): await session.commit() return { 'votes': await p.upvotes() } + +## COMMENTS ## + +@bp.get('/post//comments') +async def post_comments (id: int): + async with db as session: + p: Post | None = (await session.execute(select(Post).where(Post.id == id))).scalar() + + if p is None: + return { 'status': 404, 'error': 'Post not found' }, 404 + l = [] + for com in await p.top_level_comments(): + com: Comment + l.append(await com.section_info()) + + return dict(has=l) + + ## GUILDS ## @@ -332,6 +350,6 @@ async def suggest_guild(data: QueryIn): result: Iterable[Guild] = (await session.execute(sq.limit(10))).scalars() - return dict(has = [g.simple_info() for g in result]) + return dict(has = [g.simple_info() for g in result if await g.allows_posting(current_user.user)])