Moved the database to a separate file, getting ready for mondoDB support. Added a more welcoming flipnote

This commit is contained in:
pbsds committed 2014-01-30 19:39:59 +01:00
1 parent a5d5a82ef3
commit 7d0b413961
14 files changed
+218 -161

No files matched your search

+11 -123
View File
@@ -1,8 +1,9 @@
from twisted.web import static, resource
from twisted.internet import reactor
import sys, os, atexit, glob, imp
import sys, os, glob, imp
from Hatenatools import *#UGO, PPM, TMB and NTFT
#from DB import Database#flipnote handler
#from DB import Database#flipnote handler
ServerLog = None#Is set to the log class by server.py
Silent = False
@@ -16,9 +17,10 @@ class AccessDenied(resource.Resource):
isLeaf = True
def render(self, request):
ServerLog.write("%s got 403 when requesting \"%s\"" % (request.getClientIP(), request.path), Silent)
print "debug:",request.getAllHeaders()
request.setResponseCode(403)
return "403 - Access denied\nThis proxy is only for Flipnote Hatena for the DSi."
return "403 - Access denied\nThis proxy is only allowed to use for Flipnote Hatena for the DSi."
AccessDenied = AccessDenied()
class NotFound(resource.Resource):
isLeaf = True
@@ -28,7 +30,7 @@ class NotFound(resource.Resource):
ServerLog.write("%s got 404 when requesting \"%s\"" % (request.getClientIP(), path), Silent)
request.setResponseCode(404)
return "404 - Not Found\nThis proxy is only for Flipnote Hatena for the DSi."
return "404 - Not Found\nThis proxy is only allowed to use for Flipnote Hatena for the DSi."
NotFound = NotFound()
class ConnectionTest(resource.Resource):#used for people setting up the proxy in their DSi. It's nice to see it's actually working.
#http://conntest.nintendowifi.net/
@@ -39,7 +41,6 @@ class ConnectionTest(resource.Resource):#used for people setting up the proxy in
return '<html><head><title>HTML Page</title></head><body bgcolor="#FFFFFF">This is test.html page</body></html>'
ConnectionTest = ConnectionTest()
#Root structure:
class Root(resource.Resource):#filters out non-hantena clients
isLeaf = False
@@ -71,7 +72,7 @@ class Root(resource.Resource):#filters out non-hantena clients
if request.getHost() == "conntest.nintendowifi.net":
return ConnectionTest
Log(request, "root")
return "Welcome to hatena.pbsds.net!\nThis is in early stages, so please don't expect too much."
return "Welcome to hatena.pbsds.net!\nThis is still in early stages, so please don't expect too much."
class ds(resource.Resource):#child of Root
isLeaf = False
def __init__(self):
@@ -93,7 +94,7 @@ class UgoRoot(resource.Resource):#child of ds. (v2-xx)
def __init__(self):
resource.Resource.__init__(self)
LoadHatenaStructure(self)
LoadHatenadirStructure(self)
def getChild(self, name, request):
if name == "":
return self
@@ -161,8 +162,8 @@ class FolderResource(resource.Resource):
def render(self, request):
path = "/".join(request.path.split("/")[3:])
Log(request, path)
return "This is a folder, but I'm to lazy to list the contents..."
def LoadHatenaStructure(Resource, path="hatenadir/ds/v2-xx", root = True):
return "I am a folder, but I'm to lazy to list my contents..."
def LoadHatenadirStructure(Resource, path="hatenadir/ds/v2-xx", root = True):
for i in glob.glob("%s\*" % path):
if os.path.isfile(i):
filename = os.path.basename(i)
@@ -194,125 +195,12 @@ def LoadHatenaStructure(Resource, path="hatenadir/ds/v2-xx", root = True):
elif os.path.isdir(i):
if os.path.basename(i)[:2] <> "__":
folder = FolderResource()
LoadHatenaStructure(folder, os.path.join(path, os.path.basename(i)), False)
LoadHatenadirStructure(folder, os.path.join(path, os.path.basename(i)), False)
Resource.putChild(os.path.basename(i), folder)
#Flipnote handler:
class Database:
def __init__(self):
#read:
f = open("database/new_flipnotes.dat", "rb")#contains the newest 5000 flipnotes
self.Newest = [tuple(i.split("\t")) for i in f.read().split("\n")]#[i] = [creatorID, filename]
self.new = False#True when new flipnotes has been uploaded
f.close()
self.Creator = {}#to store creator info updates before writing to disk. Creator[id][n] = [filename, views, stars, green stars, red stars, blue stars, purple stars, Channel]
reactor.callLater(60*3, self.flusher)
atexit.register(self.write)
#to check if an update is neccesary:
self.Views = 0
self.Stars = 0
def flusher(self):#Automatically flushes the files every 3 minutes and trims down memory usage
reactor.callLater(60*3, self.flusher)
#trim newest:
if len(self.Newest) > 5000:
self.Newest = self.Newest[:5000]
self.write()
def write(self):
if self.new:
f = open("database/new_flipnotes.dat", "wb")
f.write("\n".join(("\t".join(i) for i in self.Newest)))
f.close()
self.new = False
for ID in self.Creator.keys():
f = open("database/Creators/%s/flipnotes.dat" % ID, "wb")
f.write("\n".join(("\t".join(map(str, i)) for i in self.Creator[ID])))
f.close()
del self.Creator[ID]
#helpers:
def FlipnotePath(self, CreatorID, filename):
return "database/Creators/%s/%s" % (CreatorID, filename)
def CreatorExists(self, CreatorID):
return os.path.exists("database/Creators/" + CreatorID) or (CreatorID in self.Creator)
def FlipnoteExists(self, CreatorID, filename):
return os.path.exists("database/Creators/%s/%s.ppm" % (CreatorID, filename))
#interface:
def GetCreator(self, CreatorID, Store=False):#"Store" holds it in memory, use this when making changes or reading it often
if CreatorID in self.Creator:
return self.Creator[CreatorID]
else:
if not os.path.exists("database/Creators/" + CreatorID):
return None
f = open("database/Creators/%s/flipnotes.dat" % CreatorID, "rb")
ret = [i.split("\t") for i in f.read().split("\n")]
f.close()
if Store:
self.Creator[CreatorID] = ret
return ret
def GetFlipnote(self, CreatorID, filename):#[filename, views, stars, green stars, red stars, blue stars, purple stars, Channel]
for i in (self.GetCreator(CreatorID) or []):
if i[0] == filename:
return i
return False
def AddFlipnote(self, content, Channel=""):
tmb = TMB().Read(content)
if not tmb:
return False
#CreatorID = tmb.Username
CreatorID = tmb.EditorAuthorID
filename = tmb.CurrentFilename[:-4]
del tmb
if os.path.exists("database/Creators/%s/%s.ppm" % (CreatorID, filename)):#already exists
return False
#add to database:
self.new = True
self.Newest.insert(0, (CreatorID, filename))
if not self.GetCreator(CreatorID, True):
self.Creator[CreatorID] = [[filename, 0, 0, 0, 0, 0, 0, Channel]]
else:
self.Creator[CreatorID].append([filename, 0, 0, 0, 0, 0, 0, Channel])
#write flipnote to file:
if not os.path.isdir("database/Creators/" + CreatorID):
os.mkdir("database/Creators/" + CreatorID)
f = open("database/Creators/%s/%s.ppm" % (CreatorID, filename), "wb")
f.write(content)
f.close()
return CreatorID, filename
def AddView(self, CreatorID, filename):
for i, flipnote in enumerate(self.GetCreator(CreatorID, True) or []):
if flipnote[0] == filename:
self.Creator[CreatorID][i][1] = int(flipnote[1]) + 1
self.Views += 1
return True
return False
def AddStar(self, CreatorID, filename, amount=1):
for i, flipnote in enumerate(self.GetCreator(CreatorID, True) or []):
if flipnote[0] == filename:
self.Creator[CreatorID][i][2] = int(flipnote[2]) + amount
self.Stars += 1
return True
return False
Database = Database()
#when loading:
def Setup():
print "Setting up hatena...",
root = Root()
print "Done!"
return root