* Update server-side database and dynamic resource code for Python 3 * Preserve existing Flipnote, UGO, NTFT, CSS, localization, and Hatena assets * Port Flipnote upload and movie endpoints * Update front page UGO menu generators * Preserve existing database and sample Flipnote data * Add regression tests for database operations and binary formats * Add server resource loading tests * Maintain compatibility with the original DSi Flipnote Studio protocol
68 lines
3.1 KiB
Python
68 lines
3.1 KiB
Python
from twisted.web import resource
|
|
from twisted.internet import reactor
|
|
import time
|
|
|
|
from hatena import Log, NotFound, request_args, request_path
|
|
from DB import Database
|
|
from Hatenatools import UGO
|
|
|
|
|
|
class PyResource(resource.Resource):
|
|
isLeaf = True
|
|
|
|
def __init__(self):
|
|
super().__init__()
|
|
self.pages = []
|
|
self.newestflip = None
|
|
reactor.callLater(4, self.Update)
|
|
|
|
def render(self, request):
|
|
try:
|
|
page = int(request_args(request).get("page", ["1"])[0])
|
|
except ValueError:
|
|
page = 1
|
|
if 1 <= page <= len(self.pages):
|
|
path = "/".join(request_path(request).split("/")[3:])
|
|
Log(request, "%s page %i" % (path, page))
|
|
request.setHeader(b"content-type", b"text/plain")
|
|
return self.pages[page - 1]
|
|
return NotFound.render(request)
|
|
|
|
def Update(self):
|
|
reactor.callLater(60, self.Update)
|
|
current = Database.Newest[0] if Database.Newest else None
|
|
if current != self.newestflip:
|
|
self.newestflip = current
|
|
reactor.callInThread(self.UpdateThreaded, list(Database.Newest))
|
|
|
|
def UpdateThreaded(self, flipnotes):
|
|
flipnotes = list(flipnotes)
|
|
pages = []
|
|
pagecount = (len(flipnotes) + 49) // 50
|
|
pagecount = min(pagecount, 10)
|
|
flipcount = len(flipnotes)
|
|
for i in range(pagecount):
|
|
pages.append(self.MakePage(flipnotes[i * 50 : i * 50 + 50], i + 1, i < pagecount - 1, flipcount))
|
|
if self.pages:
|
|
print(time.strftime("[%H:%M:%S] Updated newmovies.ugo"))
|
|
self.pages = pages
|
|
|
|
def MakePage(self, flipnotes, page, has_next, count):
|
|
ugo = UGO()
|
|
ugo.Loaded = True
|
|
ugo.Items = []
|
|
ugo.Items.append(("layout", (2, 1)))
|
|
ugo.Items.append(("topscreen text", ["New Flipnotes", "Flipnotes", str(count), "", "The newest Flipnotes submitted."], 0))
|
|
ugo.Items.append(("category", "http://flipnote.hatena.com/ds/v2-xx/frontpage/hotmovies.uls", "Most Popular", False))
|
|
ugo.Items.append(("category", "http://flipnote.hatena.com/ds/v2-xx/frontpage/likedmovies.uls", "Most Liked", False))
|
|
ugo.Items.append(("category", "http://flipnote.hatena.com/ds/v2-xx/frontpage/newmovies.uls", "New Flipnotes", True))
|
|
ugo.Items.append(("unknown", ("3", "http://flipnote.hatena.com/ds/v2-xx/help/post_howto.htm", "UABvAHMAdAAgAEYAbABpAHAAbgBvAHQAZQA=")))
|
|
if page > 1:
|
|
ugo.Items.append(("button", 115, "Previous", "http://flipnote.hatena.com/ds/v2-xx/frontpage/newmovies.uls?page=%i" % (page - 1), ("", ""), None))
|
|
for creatorid, filename in flipnotes:
|
|
stars = str(Database.GetFlipnote(creatorid, filename)[2])
|
|
ugo.Items.append(("button", 3, "", "http://flipnote.hatena.com/ds/v2-xx/movie/%s/%s.ppm" % (creatorid, filename), (stars, "765", "573", "0"), (filename + ".ppm", Database.GetFlipnoteTMB(creatorid, filename))))
|
|
if has_next:
|
|
ugo.Items.append(("button", 115, "Next", "http://flipnote.hatena.com/ds/v2-xx/frontpage/newmovies.uls?page=%i" % (page + 1), ("", ""), None))
|
|
return ugo.Pack()
|
