Implement a UUID lookup cache, to avoid hitting the mojang server so much
The cache is a gzip'd JSON file. Soon we will have a small script to help manage the cache See #1090 and #1117
This commit is contained in:
@@ -23,6 +23,7 @@ import re
|
|||||||
import urllib2
|
import urllib2
|
||||||
import Queue
|
import Queue
|
||||||
import multiprocessing
|
import multiprocessing
|
||||||
|
import gzip
|
||||||
|
|
||||||
from multiprocessing import Process
|
from multiprocessing import Process
|
||||||
from multiprocessing import Pool
|
from multiprocessing import Pool
|
||||||
@@ -121,6 +122,30 @@ def handleEntities(rset, outputdir, render, rname, config):
|
|||||||
class PlayerDict(dict):
|
class PlayerDict(dict):
|
||||||
use_uuid = False
|
use_uuid = False
|
||||||
_name = ''
|
_name = ''
|
||||||
|
uuid_cache = None # A cache the UUID->profile lookups
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def load_cache(cls, outputdir):
|
||||||
|
cache_file = os.path.join(outputdir, "uuidcache.dat")
|
||||||
|
pid = multiprocessing.current_process().pid
|
||||||
|
if os.path.exists(cache_file):
|
||||||
|
gz = gzip.GzipFile(cache_file)
|
||||||
|
cls.uuid_cache = json.load(gz)
|
||||||
|
logging.info("Loaded UUID cache from %r with %d entries", cache_file, len(cls.uuid_cache.keys()))
|
||||||
|
else:
|
||||||
|
cls.uuid_cache = {}
|
||||||
|
logging.info("Initialized an empty UUID cache")
|
||||||
|
cls.save_cache(outputdir)
|
||||||
|
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def save_cache(cls, outputdir):
|
||||||
|
cache_file = os.path.join(outputdir, "uuidcache.dat")
|
||||||
|
gz = gzip.GzipFile(cache_file, "wb")
|
||||||
|
json.dump(cls.uuid_cache, gz)
|
||||||
|
logging.info("Wrote UUID cache with %d entries", len(cls.uuid_cache.keys()))
|
||||||
|
|
||||||
|
|
||||||
def __getitem__(self, item):
|
def __getitem__(self, item):
|
||||||
if item == "EntityId":
|
if item == "EntityId":
|
||||||
if not super(PlayerDict, self).has_key("EntityId"):
|
if not super(PlayerDict, self).has_key("EntityId"):
|
||||||
@@ -132,14 +157,22 @@ class PlayerDict(dict):
|
|||||||
return super(PlayerDict, self).__getitem__(item)
|
return super(PlayerDict, self).__getitem__(item)
|
||||||
|
|
||||||
def get_name_from_uuid(self):
|
def get_name_from_uuid(self):
|
||||||
|
sname = self._name.replace('-','')
|
||||||
try:
|
try:
|
||||||
profile = json.loads(urllib2.urlopen(UUID_LOOKUP_URL + self._name.replace('-','')).read())
|
profile = PlayerDict.uuid_cache[sname]
|
||||||
|
return profile['name']
|
||||||
|
except (KeyError,):
|
||||||
|
pass
|
||||||
|
|
||||||
|
try:
|
||||||
|
profile = json.loads(urllib2.urlopen(UUID_LOOKUP_URL + sname).read())
|
||||||
if 'name' in profile:
|
if 'name' in profile:
|
||||||
|
PlayerDict.uuid_cache[sname] = profile
|
||||||
return profile['name']
|
return profile['name']
|
||||||
except (ValueError, urllib2.URLError):
|
except (ValueError, urllib2.URLError):
|
||||||
logging.warning("Unable to get player name for UUID %s", self._name)
|
logging.warning("Unable to get player name for UUID %s", self._name)
|
||||||
|
|
||||||
def handlePlayers(rset, render, worldpath):
|
def handlePlayers(rset, render, worldpath, outputdir):
|
||||||
if not hasattr(rset, "_pois"):
|
if not hasattr(rset, "_pois"):
|
||||||
rset._pois = dict(TileEntities=[], Entities=[])
|
rset._pois = dict(TileEntities=[], Entities=[])
|
||||||
|
|
||||||
@@ -168,6 +201,7 @@ def handlePlayers(rset, render, worldpath):
|
|||||||
isSinglePlayer = True
|
isSinglePlayer = True
|
||||||
|
|
||||||
rset._pois['Players'] = []
|
rset._pois['Players'] = []
|
||||||
|
|
||||||
for playerfile in playerfiles:
|
for playerfile in playerfiles:
|
||||||
try:
|
try:
|
||||||
data = PlayerDict(nbt.load(os.path.join(playerdir, playerfile))[1])
|
data = PlayerDict(nbt.load(os.path.join(playerdir, playerfile))[1])
|
||||||
@@ -252,6 +286,8 @@ def main():
|
|||||||
markersets = set()
|
markersets = set()
|
||||||
markers = dict()
|
markers = dict()
|
||||||
|
|
||||||
|
PlayerDict.load_cache(destdir)
|
||||||
|
|
||||||
for rname, render in config['renders'].iteritems():
|
for rname, render in config['renders'].iteritems():
|
||||||
try:
|
try:
|
||||||
worldpath = config['worlds'][render['world']]
|
worldpath = config['worlds'][render['world']]
|
||||||
@@ -291,7 +327,7 @@ def main():
|
|||||||
if not options.skipscan:
|
if not options.skipscan:
|
||||||
handleEntities(rset, os.path.join(destdir, rname), render, rname, config)
|
handleEntities(rset, os.path.join(destdir, rname), render, rname, config)
|
||||||
|
|
||||||
handlePlayers(rset, render, worldpath)
|
handlePlayers(rset, render, worldpath, destdir)
|
||||||
handleManual(rset, render['manualpois'])
|
handleManual(rset, render['manualpois'])
|
||||||
|
|
||||||
logging.info("Done handling POIs")
|
logging.info("Done handling POIs")
|
||||||
@@ -402,6 +438,8 @@ def main():
|
|||||||
markerSetDict[name]['raw'].append(d)
|
markerSetDict[name]['raw'].append(d)
|
||||||
#print markerSetDict
|
#print markerSetDict
|
||||||
|
|
||||||
|
PlayerDict.save_cache(destdir)
|
||||||
|
|
||||||
with open(os.path.join(destdir, "markersDB.js"), "w") as output:
|
with open(os.path.join(destdir, "markersDB.js"), "w") as output:
|
||||||
output.write("var markersDB=")
|
output.write("var markersDB=")
|
||||||
json.dump(markerSetDict, output, indent=2)
|
json.dump(markerSetDict, output, indent=2)
|
||||||
|
|||||||
Reference in New Issue
Block a user