From 270741eb8f229a9b95bdb37745f8310554f7701e Mon Sep 17 00:00:00 2001 From: Andrew Chin Date: Sun, 27 Dec 2015 14:59:03 -0500 Subject: [PATCH 1/2] genpoi UUID improvements * When reading the cache, catch some errors on load, instead of crashing * When writing to cache, write to tmp file, then move it into place. This should be more robust if a ctrl+c is recieved while writing the cache Addresses #1266 --- overviewer_core/aux_files/genPOI.py | 29 +++++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/overviewer_core/aux_files/genPOI.py b/overviewer_core/aux_files/genPOI.py index 7fadcc4..a237ad4 100755 --- a/overviewer_core/aux_files/genPOI.py +++ b/overviewer_core/aux_files/genPOI.py @@ -24,6 +24,7 @@ import re import sys import time import urllib2 +import datetime from collections import defaultdict from multiprocessing import Pool @@ -210,9 +211,21 @@ class PlayerDict(dict): def load_cache(cls, outputdir): cache_file = os.path.join(outputdir, "uuidcache.dat") 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())) + try: + 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())) + except (ValueError, IOError): + logging.warning("Failed to load UUID cache -- it might be corrupt") + cls.uuid_cache = {} + corrupted_cache = cache_file + ".corrupted." + datetime.datetime.now().isoformat() + try: + os.rename(cache_file, corrupted_cache) + logging.warning("If %s does not appear to contain meaningful data, you may safely delete it", corrupted_cache) + except OSError: + logging.warning("Failed to backup corrupted UUID cache") + + logging.info("Initialized an empty UUID cache") else: cls.uuid_cache = {} logging.info("Initialized an empty UUID cache") @@ -220,9 +233,13 @@ class PlayerDict(dict): @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())) + try: + gz = gzip.GzipFile(cache_file + ".tmp", "wb") + json.dump(cls.uuid_cache, gz) + os.rename(cache_file + ".tmp", cache_file) + logging.info("Wrote UUID cache with %d entries", len(cls.uuid_cache.keys())) + except (IOError, OSError): + logging.warning("Failed to save UUID cache!") def __getitem__(self, item): if item == "EntityId": From 2e3450756860c793b34f2ccbee780f14edd08132 Mon Sep 17 00:00:00 2001 From: Andrew Chin Date: Mon, 1 Feb 2016 09:32:35 -0500 Subject: [PATCH 2/2] Use FileReplacer to manage the uuid cache file --- overviewer_core/aux_files/genPOI.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/overviewer_core/aux_files/genPOI.py b/overviewer_core/aux_files/genPOI.py index a237ad4..6178e2a 100755 --- a/overviewer_core/aux_files/genPOI.py +++ b/overviewer_core/aux_files/genPOI.py @@ -33,6 +33,7 @@ from optparse import OptionParser from overviewer_core import logger from overviewer_core import nbt from overviewer_core import configParser, world +from overviewer_core.files import FileReplacer UUID_LOOKUP_URL = 'https://sessionserver.mojang.com/session/minecraft/profile/' @@ -233,13 +234,11 @@ class PlayerDict(dict): @classmethod def save_cache(cls, outputdir): cache_file = os.path.join(outputdir, "uuidcache.dat") - try: - gz = gzip.GzipFile(cache_file + ".tmp", "wb") + + with FileReplacer(cache_file) as cache_file_name: + gz = gzip.GzipFile(cache_file_name, "wb") json.dump(cls.uuid_cache, gz) - os.rename(cache_file + ".tmp", cache_file) logging.info("Wrote UUID cache with %d entries", len(cls.uuid_cache.keys())) - except (IOError, OSError): - logging.warning("Failed to save UUID cache!") def __getitem__(self, item): if item == "EntityId":