from twisted.web import resource from hatena import Log, ServerLog, Silent, NotFound, as_text, request_path, request_args, request_headers, client_ip from DB import Database from Hatenatools import TMB class PyResource(resource.Resource): isLeaf = False def __init__(self): super().__init__() self.CreatorID = CreatorIDResource() def getChild(self, name, request): name = as_text(name) if Database.CreatorExists(name): return self.CreatorID if name == "": return self return NotFound def render(self, request): request.setResponseCode(403) return b"403 - Denied access" class CreatorIDResource(resource.Resource): isLeaf = False def __init__(self): super().__init__() self.CreatorIDFile = CreatorIDFileResource() def getChild(self, name, request): creator_id = request_path(request).split("/")[-2] name = as_text(name) filename = ".".join(name.split(".")[:-1]) if Database.FlipnoteExists(creator_id, filename): return self.CreatorIDFile if name == "": return self return NotFound def render(self, request): request.setResponseCode(403) return b"403 - Denied access" class CreatorIDFileResource(resource.Resource): isLeaf = True def render(self, request): creator, file = request_path(request).split("/")[-2:] filetype = file.rsplit(".", 1)[-1].lower() path = "/".join(request_path(request).split("/")[3:]) if filetype == "ppm": Log(request, path) Database.AddView(creator, file[:-4]) request.setHeader(b"content-type", b"text/plain") return Database.GetFlipnotePPM(creator, file[:-4]) if filetype == "info": Log(request, path, True) request.setHeader(b"content-type", b"text/plain") return b"0\n0\n" if filetype == "htm": request.setHeader(b"content-type", b"text/html; charset=utf-8") return self.GenerateDetailsPage(creator, ".".join(file.split(".")[:-1])).encode("UTF-8") if filetype == "star": args = request_args(request) color = args.get("starcolor", ["yellow"])[0].split(",", 1)[0].lower() headers = request_headers(request) if "x-hatena-star-count" not in headers: ServerLog.write( "%s got 403 when requesting %s without a X-Hatena-Star-Count header" % (client_ip(request), path), Silent, ) request.setResponseCode(403) return b"403 - Denied access\nRequest lacks a X-Hatena-Star-Count http header" try: amount = int(headers["x-hatena-star-count"]) except ValueError: amount = 0 if amount < 1 or amount > 65535: ServerLog.write( "%s got 403 when requesting %s with an invalid X-Hatena-Star-Count header" % (client_ip(request), path), Silent, ) request.setResponseCode(403) return b"403 - Denied access\nRequest has an invalid X-Hatena-Star-Count http header" if not Database.AddStar(creator, file[:-5], amount, color): ServerLog.write("%s got 500 when requesting %s" % (client_ip(request), path), Silent) request.setResponseCode(500) return b"500 - Internal server error\nAdding the stars seems to have failed." ServerLog.write( "%s added %i %s stars to %s/%s.ppm" % (client_ip(request), amount, color, creator, file[:-5]), Silent, ) return b"Success" if filetype == "dl": Log(request, path, True) Database.AddDownload(creator, file[:-3]) return b"Noted ;)" ServerLog.write("%s got 403 when requesting %s" % (client_ip(request), path), Silent) request.setResponseCode(403) return b"403 - Denied access" def GenerateDetailsPage(self, CreatorID, filename): flipnote = Database.GetFlipnote(CreatorID, filename) if not flipnote: return "This flipnote doesn't exist!" tmb = TMB().Read(Database.GetFlipnoteTMB(CreatorID, filename)) if not tmb: return "This flipnote is corrupt!" spinoff = "" if tmb.OriginalAuthorID != tmb.EditorAuthorID or tmb.OriginalFilename != tmb.CurrentFilename: if Database.FlipnoteExists(tmb.OriginalAuthorID, tmb.OriginalFilename[:-4]): spinoff = SpinoffTemplate1.replace("%%CreatorID%%", tmb.OriginalAuthorID).replace("%%Filename%%", tmb.OriginalFilename[:-4]) elif tmb.OriginalAuthorID != tmb.EditorAuthorID: spinoff = SpinoffTemplate2 entries = [] content = '%s' % (CreatorID, tmb.Username) entries.append(PageEntryTemplate.replace("%%Name%%", "Creator").replace("%%Content%%", content)) content = '★ %s' % (CreatorID, filename, flipnote[2]) for css, value in zip(("1", "2", "3", "4"), flipnote[3:7]): content += '
★ %s' % (CreatorID, filename, css, css, value) entries.append(PageEntryTemplate.replace("%%Name%%", "Stars").replace("%%Content%%", content)) entries.append(PageEntryTemplate.replace("%%Name%%", "Views").replace("%%Content%%", str(flipnote[1]))) entries.append(PageEntryTemplate.replace("%%Name%%", "Downloads").replace("%%Content%%", str(flipnote[8]))) if flipnote[7]: content = '%s' % (flipnote[7], flipnote[7]) entries.append(PageEntryTemplate.replace("%%Name%%", "Channel").replace("%%Content%%", content)) return ( DetailsPageTemplate.replace("%%CreatorID%%", CreatorID) .replace("%%Filename%%", filename) .replace("%%Username%%", tmb.Username) .replace("%%CommentCount%%", "0") .replace("%%Spinoff%%", spinoff) .replace("%%PageEntries%%", PageEntrySeparator.join(entries)) ) #templates: DetailsPageTemplate = """ Flipnote by %%Username%%
Description
Comments(%%CommentCount%%)
%%Spinoff%% %%PageEntries%%
""" SpinoffTemplate1 = """
This Flipnote is a spin-off.
Original Flipnote
""" SpinoffTemplate2 = """
This Flipnote is a spin-off.
""" PageEntryTemplate = """
%%Name%%
%%Content%%
""" PageEntrySeparator="""
"""