forked from retoor/snek
116 lines
4.4 KiB
Python
116 lines
4.4 KiB
Python
# forum_app.py
|
|
import aiohttp.web
|
|
from snek.view.forum import ForumIndexView, ForumView, ForumWebSocketView
|
|
|
|
|
|
class ForumApplication(aiohttp.web.Application):
|
|
def __init__(self, parent, *args, **kwargs):
|
|
super().__init__(*args, **kwargs)
|
|
self.parent = parent
|
|
self.render_template = self.parent.render_template
|
|
# Set up routes
|
|
self.setup_routes()
|
|
|
|
# Set up notification listeners
|
|
self.setup_notifications()
|
|
|
|
@property
|
|
def db(self):
|
|
return self.parent.db
|
|
|
|
@property
|
|
def services(self):
|
|
return self.parent.services
|
|
|
|
def setup_routes(self):
|
|
"""Set up all forum routes"""
|
|
# API routes
|
|
self.router.add_view("/index.html", ForumIndexView)
|
|
self.router.add_route("GET", "/api/forums", ForumView.get_forums)
|
|
self.router.add_route("GET", "/api/forums/{slug}", ForumView.get_forum)
|
|
self.router.add_route("POST", "/api/forums/{slug}/threads", ForumView.create_thread)
|
|
self.router.add_route("GET", "/api/threads/{thread_slug}", ForumView.get_thread)
|
|
self.router.add_route("POST", "/api/threads/{thread_uid}/posts", ForumView.create_post)
|
|
self.router.add_route("PUT", "/api/posts/{post_uid}", ForumView.edit_post)
|
|
self.router.add_route("DELETE", "/api/posts/{post_uid}", ForumView.delete_post)
|
|
self.router.add_route("POST", "/api/posts/{post_uid}/like", ForumView.toggle_like)
|
|
self.router.add_route("POST", "/api/threads/{thread_uid}/pin", ForumView.toggle_pin)
|
|
self.router.add_route("POST", "/api/threads/{thread_uid}/lock", ForumView.toggle_lock)
|
|
|
|
# WebSocket route
|
|
self.router.add_view("/ws", ForumWebSocketView)
|
|
|
|
# Static HTML route
|
|
self.router.add_route("GET", "/{path:.*}", self.serve_forum_html)
|
|
|
|
def setup_notifications(self):
|
|
"""Set up notification listeners for WebSocket broadcasting"""
|
|
# Forum notifications
|
|
self.services.forum.add_notification_listener("forum_created", self.on_forum_event)
|
|
|
|
# Thread notifications
|
|
self.services.thread.add_notification_listener("thread_created", self.on_thread_event)
|
|
|
|
# Post notifications
|
|
self.services.post.add_notification_listener("post_created", self.on_post_event)
|
|
self.services.post.add_notification_listener("post_edited", self.on_post_event)
|
|
self.services.post.add_notification_listener("post_deleted", self.on_post_event)
|
|
|
|
# Like notifications
|
|
self.services.post_like.add_notification_listener("post_liked", self.on_like_event)
|
|
self.services.post_like.add_notification_listener("post_unliked", self.on_like_event)
|
|
|
|
async def on_forum_event(self, event_type, data):
|
|
"""Handle forum events"""
|
|
await ForumWebSocketView.broadcast_update(self, event_type, data)
|
|
|
|
async def on_thread_event(self, event_type, data):
|
|
"""Handle thread events"""
|
|
await ForumWebSocketView.broadcast_update(self, event_type, data)
|
|
|
|
async def on_post_event(self, event_type, data):
|
|
"""Handle post events"""
|
|
await ForumWebSocketView.broadcast_update(self, event_type, data)
|
|
|
|
async def on_like_event(self, event_type, data):
|
|
"""Handle like events"""
|
|
await ForumWebSocketView.broadcast_update(self, event_type, data)
|
|
|
|
async def serve_forum_html(self, request):
|
|
"""Serve the forum HTML with the web component"""
|
|
html = """<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>Forum</title>
|
|
<script type="module" src="/forum/static/snek-forum.js"></script>
|
|
<style>
|
|
body {
|
|
margin: 0;
|
|
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
|
background-color: #f5f5f5;
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<snek-forum></snek-forum>
|
|
</body>
|
|
</html>"""
|
|
return await self.parent.render_template("forum.html", request)
|
|
|
|
|
|
#return aiohttp.web.Response(text=html, content_type="text/html")
|
|
|
|
|
|
# Integration with main app
|
|
def setup_forum(app):
|
|
"""Set up forum sub-application"""
|
|
forum_app = ForumApplication(app)
|
|
app.add_subapp("/forum", forum_app)
|
|
app.forum_app = forum_app
|
|
# Register models and services if needed
|
|
# This would typically be done in your main app initialization
|
|
|
|
return forum_app
|