import html from twisted.web import resource from DB import Database from hatena import NotFound, as_text, client_ip from reximemo import dialog, dsi_text_html, dsi_url, flipnote_buttons, html_page, make_menu, page_number, pagination_buttons, posting_account, read_ppm_upload class PyResource(resource.Resource): isLeaf = False def getChild(self, name, request): text = as_text(name) base, dot, ext = text.partition(".") if not dot or not base.isdigit() or ext not in {"ugo", "uls", "htm", "post"}: return NotFound channel = Database.get_channel(int(base)) return ChannelResource(int(base), ext) if channel else NotFound def render(self, request): request.setResponseCode(403); return b"" class ChannelResource(resource.Resource): isLeaf = True def __init__(self, channel_id, ext): super().__init__(); self.channel_id = channel_id; self.ext = ext def render_GET(self, request): channel = Database.get_channel(self.channel_id) if not channel: return NotFound.render(request) if self.ext in {"ugo", "uls"}: total = Database.count_flipnotes(channel_id=self.channel_id) page = page_number(request, total) rows = Database.list_flipnotes(channel_id=self.channel_id, page=page, per_page=50) pager = pagination_buttons(request, f"ch/{self.channel_id}.uls", page, total) prev = [item for item in pager if item["label"].startswith("Previous")] nxt = [item for item in pager if item["label"].startswith("Next")] request.setHeader(b"content-type", b"text/plain") return make_menu( layout=(2,1), title=channel["title"], subtitle_top="Channel", subtitle_bottom=channel["description"], left="Flipnotes", right=str(total), buttons=prev + flipnote_buttons(request, rows) + nxt, corner={"label":"Post", "url":dsi_url(request, f"ch/{self.channel_id}.post")}, ) if self.ext == "htm": return html_page(request, channel["title"], '
%s

%s

Browse

' % (dsi_text_html(channel["title"]), dsi_text_html(channel["description"], preserve_newlines=True), html.escape(dsi_url(request, f"ch/{self.channel_id}.uls"), quote=True))) request.setResponseCode(405); return b"" def render_POST(self, request): if self.ext != "post": request.setResponseCode(405); return b"" account, denied = posting_account(request) if denied is not None: return denied try: data = read_ppm_upload(request) result = Database.AddFlipnote(data, str(self.channel_id), account["id"] if account else None, client_ip(request)) except ValueError as exc: return dialog(request, str(exc)) except Exception: result = False if not result: return dialog(request, "Unable to post this Flipnote. It may already exist or be invalid.") return b""