diff --git a/src/snek/model/forum.py b/src/snek/model/forum.py index 59ef23a..9c037a1 100644 --- a/src/snek/model/forum.py +++ b/src/snek/model/forum.py @@ -17,13 +17,15 @@ class ForumModel(BaseModel): last_thread_uid = ModelField(name="last_thread_uid", required=False, kind=str) async def get_threads(self, limit=50, offset=0): - return await self.app.services.thread.find( + async for thread in self.app.services.thread.find( forum_uid=self["uid"], deleted_at=None, _limit=limit, _offset=offset, - _order_by="is_pinned DESC, last_post_at DESC" - ) + order_by="-last_post_at" + #order_by="is_pinned DESC, last_post_at DESC" + ): + yield thread async def increment_thread_count(self): self["thread_count"] += 1 @@ -49,13 +51,14 @@ class ThreadModel(BaseModel): last_post_by_uid = ModelField(name="last_post_by_uid", required=False, kind=str) async def get_posts(self, limit=50, offset=0): - return await self.app.services.post.find( + async for post in self.app.services.post.find( thread_uid=self["uid"], deleted_at=None, _limit=limit, _offset=offset, - _order_by="created_at ASC" - ) + order_by="created_at" + ): + yield post async def increment_view_count(self): self["view_count"] += 1 diff --git a/src/snek/service/forum.py b/src/snek/service/forum.py index 253e719..3a6d552 100644 --- a/src/snek/service/forum.py +++ b/src/snek/service/forum.py @@ -4,14 +4,15 @@ import re import uuid from collections import defaultdict from typing import Any, Awaitable, Callable, Dict, List - +from snek.system.model import now EventListener = Callable[[str, Any], Awaitable[None]] | Callable[[str, Any], None] class BaseForumService(BaseService): """ Base mix-in that gives a service `add_notification_listener`, an internal `_dispatch_event` helper, and a public `notify` method. """ - + def get_timestamp(self): + return now() def generate_uid(self): return str(uuid.uuid4()) @@ -93,7 +94,7 @@ class ForumService(BaseForumService): return slug async def get_active_forums(self): - async for forum in self.find(is_active=True, _order_by="position ASC, created_at ASC"): + async for forum in self.find(is_active=True, order_by="position"): yield forum async def update_last_post(self, forum_uid, thread_uid): @@ -108,6 +109,8 @@ class ForumService(BaseForumService): class ThreadService(BaseForumService): mapper_name = "thread" + + async def create_thread(self, forum_uid, title, content, created_by_uid): # Generate slug slug = self.services.forum.generate_slug(title) diff --git a/src/snek/system/model.py b/src/snek/system/model.py index 9e9830d..7cc8456 100644 --- a/src/snek/system/model.py +++ b/src/snek/system/model.py @@ -255,6 +255,9 @@ class BaseModel: def mapper(self): return self._mapper + def save(self): + return self.mapper.save(self) + @mapper.setter def mapper(self, value): self._mapper = value diff --git a/src/snek/templates/forum.html b/src/snek/templates/forum.html index 4930417..ddbc68a 100644 --- a/src/snek/templates/forum.html +++ b/src/snek/templates/forum.html @@ -1,13 +1,20 @@ - - - - - - Forum Component - - - + + +{% endblock %} - - - diff --git a/src/snek/view/forum.py b/src/snek/view/forum.py index 870f9b1..c72a248 100644 --- a/src/snek/view/forum.py +++ b/src/snek/view/forum.py @@ -101,9 +101,10 @@ class ForumView(BaseView): async def get_forum(self): request = self self = request.app + setattr(self, "request", request) """GET /forum/api/forums/:slug - Get forum by slug""" slug = self.request.match_info["slug"] - forum = await self.services.forum.find_one(slug=slug, is_active=True) + forum = await self.services.forum.get(slug=slug, is_active=True) if not forum: return web.json_response({"error": "Forum not found"}, status=404) @@ -163,12 +164,14 @@ class ForumView(BaseView): async def create_thread(self): request = self self = request.app + + setattr(self, "request", request) """POST /forum/api/forums/:slug/threads - Create new thread""" if not self.request.session.get("logged_in"): return web.json_response({"error": "Unauthorized"}, status=401) slug = self.request.match_info["slug"] - forum = await self.services.forum.find_one(slug=slug, is_active=True) + forum = await self.services.forum.get(slug=slug, is_active=True) if not forum: return web.json_response({"error": "Forum not found"}, status=404) @@ -201,9 +204,11 @@ class ForumView(BaseView): async def get_thread(self): request = self self = request.app + + setattr(self, "request", request) """GET /forum/api/threads/:thread_slug - Get thread with posts""" thread_slug = self.request.match_info["thread_slug"] - thread = await self.services.thread.find_one(slug=thread_slug) + thread = await self.services.thread.get(slug=thread_slug) if not thread: return web.json_response({"error": "Thread not found"}, status=404) @@ -277,6 +282,8 @@ class ForumView(BaseView): async def create_post(self): request = self self = request.app + + setattr(self, "request", request) """POST /forum/api/threads/:thread_uid/posts - Create new post""" if not self.request.session.get("logged_in"): return web.json_response({"error": "Unauthorized"}, status=401) @@ -324,6 +331,8 @@ class ForumView(BaseView): async def edit_post(self): request = self self = request.app + + setattr(self, "request", request) """PUT /forum/api/posts/:post_uid - Edit post""" if not self.request.session.get("logged_in"): return web.json_response({"error": "Unauthorized"}, status=401) @@ -355,6 +364,8 @@ class ForumView(BaseView): async def delete_post(self): request = self self = request.app + + setattr(self, "request", request) """DELETE /forum/api/posts/:post_uid - Delete post""" if not self.request.session.get("logged_in"): return web.json_response({"error": "Unauthorized"}, status=401) @@ -374,6 +385,8 @@ class ForumView(BaseView): async def toggle_like(self): request = self self = request.app + + setattr(self, "request", request) """POST /forum/api/posts/:post_uid/like - Toggle post like""" if not self.request.session.get("logged_in"): return web.json_response({"error": "Unauthorized"}, status=401) @@ -399,6 +412,8 @@ class ForumView(BaseView): async def toggle_pin(self): request = self self = request.app + + setattr(self, "request", request) """POST /forum/api/threads/:thread_uid/pin - Toggle thread pin""" if not self.request.session.get("logged_in"): return web.json_response({"error": "Unauthorized"}, status=401) @@ -418,6 +433,8 @@ class ForumView(BaseView): async def toggle_lock(self): request = self self = request.app + + setattr(self, "request", request) """POST /forum/api/threads/:thread_uid/lock - Toggle thread lock""" if not self.request.session.get("logged_in"): return web.json_response({"error": "Unauthorized"}, status=401)