diff --git a/overviewer.py b/overviewer.py index b005394..b33acfa 100755 --- a/overviewer.py +++ b/overviewer.py @@ -42,8 +42,6 @@ from overviewer_core import configParser, tileset, assetmanager, dispatcher from overviewer_core import cache from overviewer_core import observer -LOG = logging.getLogger('overviewer_core') - helptext = """ %prog [--rendermodes=...] [options] %prog --config= [options]""" @@ -161,14 +159,14 @@ def main(): from overviewer_core.textures import Textures tex = Textures() - LOG.info("Looking for a few common texture files...") + logging.info("Looking for a few common texture files...") try: f = tex.find_file("assets/minecraft/textures/blocks/sandstone_top.png", verbose=True) f = tex.find_file("assets/minecraft/textures/blocks/grass_top.png", verbose=True) f = tex.find_file("assets/minecraft/textures/blocks/diamond_ore.png", verbose=True) f = tex.find_file("assets/minecraft/textures/blocks/planks_acacia.png", verbose=True) except IOError: - LOG.error("Could not find any texture files.") + logging.error("Could not find any texture files.") return 1 return 0 @@ -188,7 +186,7 @@ def main(): else: # more helpful message for users who know what they're doing - LOG.error("You must either specify --config or give me a world directory and output directory") + logging.error("You must either specify --config or give me a world directory and output directory") parser.print_help() list_worlds() return 1 @@ -205,12 +203,12 @@ def main(): print("worlds['myworld'] = %r" % args[0]) print("outputdir = %r" % (args[1] if len(args) > 1 else "/path/to/output")) print() - LOG.error("Cannot specify both --config AND a world + output directory on the command line.") + logging.error("Cannot specify both --config AND a world + output directory on the command line.") parser.print_help() return 1 if not options.config and len(args) < 2: - LOG.error("You must specify both the world directory and an output directory") + logging.error("You must specify both the world directory and an output directory") parser.print_help() return 1 if not options.config and len(args) > 2: @@ -220,10 +218,10 @@ def main(): if not os.path.exists(args[start]): for end in range(start+1, len(args)+1): if os.path.exists(" ".join(args[start:end])): - LOG.warning("It looks like you meant to specify \"%s\" as your world dir or your output\n\ + logging.warning("It looks like you meant to specify \"%s\" as your world dir or your output\n\ dir but you forgot to put quotes around the directory, since it contains spaces." % " ".join(args[start:end])) return 1 - LOG.error("Too many command line arguments") + logging.error("Too many command line arguments") parser.print_help() return 1 @@ -235,8 +233,8 @@ dir but you forgot to put quotes around the directory, since it contains spaces. if not options.config: # No config file mode. worldpath, destdir = map(os.path.expanduser, args) - LOG.debug("Using %r as the world directory", worldpath) - LOG.debug("Using %r as the output directory", destdir) + logging.debug("Using %r as the world directory", worldpath) + logging.debug("Using %r as the output directory", destdir) mw_parser.set_config_item("worlds", {'world': worldpath}) mw_parser.set_config_item("outputdir", destdir) @@ -257,7 +255,7 @@ dir but you forgot to put quotes around the directory, since it contains spaces. else: if options.rendermodes: - LOG.error("You cannot specify --rendermodes if you give a config file. Configure your rendermodes in the config file instead") + logging.error("You cannot specify --rendermodes if you give a config file. Configure your rendermodes in the config file instead") parser.print_help() return 1 @@ -266,7 +264,7 @@ dir but you forgot to put quotes around the directory, since it contains spaces. mw_parser.parse(os.path.expanduser(options.config)) except configParser.MissingConfigException as e: # this isn't a "bug", so don't print scary traceback - LOG.error(str(e)) + logging.error(str(e)) util.nice_exit(1) # Add in the command options here, perhaps overriding values specified in @@ -279,16 +277,16 @@ dir but you forgot to put quotes around the directory, since it contains spaces. config = mw_parser.get_validated_config() except Exception as ex: if options.verbose: - LOG.exception("An error was encountered with your configuration. See the info below.") + logging.exception("An error was encountered with your configuration. See the info below.") else: # no need to print scary traceback! just - LOG.error("An error was encountered with your configuration.") - LOG.error(str(ex)) + logging.error("An error was encountered with your configuration.") + logging.error(str(ex)) return 1 if options.check_terrain: # we are already in the "if configfile" branch - LOG.info("Looking for a few common texture files...") + logging.info("Looking for a few common texture files...") for render_name, render in config['renders'].iteritems(): - LOG.info("Looking at render %r", render_name) + logging.info("Looking at render %r", render_name) # find or create the textures object texopts = util.dict_subset(render, ["texturepath"]) @@ -302,8 +300,8 @@ dir but you forgot to put quotes around the directory, since it contains spaces. ############################################################ # Final validation steps and creation of the destination directory - LOG.info("Welcome to Minecraft Overviewer!") - LOG.debug("Current log level: {0}".format(LOG.level)) + logging.info("Welcome to Minecraft Overviewer!") + logging.debug("Current log level: {0}".format(logging.getLogger().level)) # Override some render configdict options depending on one-time command line # modifiers @@ -312,26 +310,26 @@ dir but you forgot to put quotes around the directory, since it contains spaces. bool(options.checktiles) + bool(options.notilechecks) ) > 1: - LOG.error("You cannot specify more than one of --forcerender, "+ + logging.error("You cannot specify more than one of --forcerender, "+ "--check-tiles, and --no-tile-checks. These options conflict.") parser.print_help() return 1 if options.forcerender: - LOG.info("Forcerender mode activated. ALL tiles will be rendered") + logging.info("Forcerender mode activated. ALL tiles will be rendered") for render in config['renders'].itervalues(): render['renderchecks'] = 2 elif options.checktiles: - LOG.info("Checking all tiles for updates manually.") + logging.info("Checking all tiles for updates manually.") for render in config['renders'].itervalues(): render['renderchecks'] = 1 elif options.notilechecks: - LOG.info("Disabling all tile mtime checks. Only rendering tiles "+ + logging.info("Disabling all tile mtime checks. Only rendering tiles "+ "that need updating since last render") for render in config['renders'].itervalues(): render['renderchecks'] = 0 if not config['renders']: - LOG.error("You must specify at least one render in your config file. See the docs if you're having trouble") + logging.error("You must specify at least one render in your config file. See the docs if you're having trouble") return 1 ##################### @@ -342,7 +340,7 @@ dir but you forgot to put quotes around the directory, since it contains spaces. try: worldpath = config['worlds'][render['world']] except KeyError: - LOG.error("Render %s's world is '%s', but I could not find a corresponding entry in the worlds dictionary.", + logging.error("Render %s's world is '%s', but I could not find a corresponding entry in the worlds dictionary.", rname, render['world']) return 1 render['worldname_orig'] = render['world'] @@ -359,23 +357,23 @@ dir but you forgot to put quotes around the directory, since it contains spaces. try: renderLink = config['renders'][x] except KeyError: - LOG.error("Render %s's overlay is '%s', but I could not find a corresponding entry in the renders dictionary.", + logging.error("Render %s's overlay is '%s', but I could not find a corresponding entry in the renders dictionary.", rname, x) return 1 else: - LOG.error("Render %s's overlay contains itself.", rname) + logging.error("Render %s's overlay contains itself.", rname) return 1 destdir = config['outputdir'] if not destdir: - LOG.error("You must specify the output directory in your config file.") - LOG.error("e.g. outputdir = '/path/to/outputdir'") + logging.error("You must specify the output directory in your config file.") + logging.error("e.g. outputdir = '/path/to/outputdir'") return 1 if not os.path.exists(destdir): try: os.mkdir(destdir) except OSError: - LOG.exception("Could not create the output directory.") + logging.exception("Could not create the output directory.") return 1 ######################################################################## @@ -387,7 +385,7 @@ dir but you forgot to put quotes around the directory, since it contains spaces. # If we've been asked to update web assets, do that and then exit if options.update_web_assets: assetMrg.output_noconfig() - LOG.info("Web assets have been updated") + logging.info("Web assets have been updated") return 0 # The changelist support. @@ -397,7 +395,7 @@ dir but you forgot to put quotes around the directory, since it contains spaces. path = render['changelist'] if path not in changelists: out = open(path, "w") - LOG.debug("Opening changelist %s (%s)", out, out.fileno()) + logging.debug("Opening changelist %s (%s)", out, out.fileno()) changelists[path] = out else: out = changelists[path] @@ -419,7 +417,7 @@ dir but you forgot to put quotes around the directory, since it contains spaces. renders = config['renders'] for render_name, render in renders.iteritems(): - LOG.debug("Found the following render thing: %r", render) + logging.debug("Found the following render thing: %r", render) # find or create the world object try: @@ -441,13 +439,13 @@ dir but you forgot to put quotes around the directory, since it contains spaces. tex = texcache[texopts_key] try: - LOG.debug("Asking for regionset %r" % render['dimension'][1]) + logging.debug("Asking for regionset %r" % render['dimension'][1]) rset = w.get_regionset(render['dimension'][1]) except IndexError: - LOG.error("Sorry, I can't find anything to render! Are you sure there are .mca files in the world directory?") + logging.error("Sorry, I can't find anything to render! Are you sure there are .mca files in the world directory?") return 1 if rset == None: # indicates no such dimension was found: - LOG.error("Sorry, you requested dimension '%s' for %s, but I couldn't find it", render['dimension'][0], render_name) + logging.error("Sorry, you requested dimension '%s' for %s, but I couldn't find it", render['dimension'][0], render_name) return 1 ################# @@ -467,7 +465,7 @@ dir but you forgot to put quotes around the directory, since it contains spaces. # object if (render['northdirection'] > 0): rset = world.RotatedRegionSet(rset, render['northdirection']) - LOG.debug("Using RegionSet %r", rset) + logging.debug("Using RegionSet %r", rset) ############################### # Do the final prep and create the TileSet object @@ -501,13 +499,13 @@ dir but you forgot to put quotes around the directory, since it contains spaces. assetMrg.finalize(tilesets) for out in changelists.itervalues(): - LOG.debug("Closing %s (%s)", out, out.fileno()) + logging.debug("Closing %s (%s)", out, out.fileno()) out.close() if config['processes'] == 1: - LOG.debug("Final cache stats:") + logging.debug("Final cache stats:") for c in caches: - LOG.debug("\t%s: %s hits, %s misses", c.__class__.__name__, c.hits, c.misses) + logging.debug("\t%s: %s hits, %s misses", c.__class__.__name__, c.hits, c.misses) if options.pid: os.remove(options.pid) @@ -552,10 +550,10 @@ if __name__ == "__main__": util.nice_exit(ret) except textures.TextureException as e: # this isn't a "bug", so don't print scary traceback - LOG.error(str(e)) + logging.error(str(e)) util.nice_exit(1) except Exception as e: - LOG.exception("""An error has occurred. This may be a bug. Please let us know! + logging.exception("""An error has occurred. This may be a bug. Please let us know! See http://docs.overviewer.org/en/latest/index.html#help This is the error that occurred:""") diff --git a/overviewer_core/assetmanager.py b/overviewer_core/assetmanager.py index b37857d..96d8bb2 100644 --- a/overviewer_core/assetmanager.py +++ b/overviewer_core/assetmanager.py @@ -27,10 +27,6 @@ import world import util from files import FileReplacer, mirror_dir - -LOG = logging.getLogger(__name__) - - class AssetManager(object): """\ These objects provide an interface to metadata and persistent data, and at the @@ -55,8 +51,8 @@ directory. self.overviewerConfig = json.loads(overviewerConfig_str) except Exception, e: if os.path.exists(os.path.join(self.outputdir, "overviewerConfig.js")): - LOG.warning("A previous overviewerConfig.js was found, but I couldn't read it for some reason. Continuing with a blank config") - LOG.debug(traceback.format_exc()) + logging.warning("A previous overviewerConfig.js was found, but I couldn't read it for some reason. Continuing with a blank config") + logging.debug(traceback.format_exc()) self.overviewerConfig = dict(tilesets=dict()) # Make sure python knows the preferred encoding. If it does not, set it diff --git a/overviewer_core/aux_files/genPOI.py b/overviewer_core/aux_files/genPOI.py index b049463..ad8858d 100755 --- a/overviewer_core/aux_files/genPOI.py +++ b/overviewer_core/aux_files/genPOI.py @@ -31,9 +31,6 @@ from overviewer_core import logger from overviewer_core import nbt from overviewer_core import configParser, world -LOG = logging.getLogger(__name__) - - def replaceBads(s): "Replaces bad characters with good characters!" bads = [" ", "(", ")"] @@ -69,7 +66,7 @@ def handleEntities(rset, outputdir, render, rname, config): if hasattr(rset, "_pois"): return - LOG.info("Looking for entities in %r", rset) + logging.info("Looking for entities in %r", rset) filters = render['markers'] rset._pois = dict(TileEntities=[], Entities=[]) @@ -109,7 +106,7 @@ def handleEntities(rset, outputdir, render, rname, config): rset._pois['TileEntities'] += data['TileEntities'] rset._pois['Entities'] += data['Entities'] - LOG.info("Done.") + logging.info("Done.") def handlePlayers(rset, render, worldpath): if not hasattr(rset, "_pois"): @@ -146,7 +143,7 @@ def handlePlayers(rset, render, worldpath): if isSinglePlayer: data = data['Data']['Player'] except IOError: - LOG.warning("Skipping bad player dat file %r", playerfile) + logging.warning("Skipping bad player dat file %r", playerfile) continue playername = playerfile.split(".")[0] if isSinglePlayer: @@ -207,7 +204,7 @@ def main(): try: config = mw_parser.get_validated_config() except Exception: - LOG.exception("An error was encountered with your configuration. See the info below.") + logging.exception("An error was encountered with your configuration. See the info below.") return 1 destdir = config['outputdir'] @@ -221,7 +218,7 @@ def main(): try: worldpath = config['worlds'][render['world']] except KeyError: - LOG.error("Render %s's world is '%s', but I could not find a corresponding entry in the worlds dictionary.", + logging.error("Render %s's world is '%s', but I could not find a corresponding entry in the worlds dictionary.", rname, render['world']) return 1 render['worldname_orig'] = render['world'] @@ -236,7 +233,7 @@ def main(): rset = w.get_regionset(render['dimension'][1]) if rset == None: # indicates no such dimension was found: - LOG.error("Sorry, you requested dimension '%s' for the render '%s', but I couldn't find it", render['dimension'][0], rname) + logging.error("Sorry, you requested dimension '%s' for the render '%s', but I couldn't find it", render['dimension'][0], rname) return 1 for f in render['markers']: @@ -259,8 +256,8 @@ def main(): handlePlayers(rset, render, worldpath) handleManual(rset, render['manualpois']) - LOG.info("Done handling POIs") - LOG.info("Writing out javascript files") + logging.info("Done handling POIs") + logging.info("Writing out javascript files") markerSetDict = dict() for (flter, rset) in markersets: # generate a unique name for this markerset. it will not be user visible @@ -379,7 +376,7 @@ def main(): output.write("overviewer.util.injectMarkerScript('markersDB.js');\n") output.write("overviewer.util.injectMarkerScript('markers.js');\n") output.write("overviewer.collections.haveSigns=true;\n") - LOG.info("Done") + logging.info("Done") if __name__ == "__main__": main() diff --git a/overviewer_core/cache.py b/overviewer_core/cache.py index 6877e2b..d21dbc5 100644 --- a/overviewer_core/cache.py +++ b/overviewer_core/cache.py @@ -21,6 +21,7 @@ attribute. """ import functools +import logging import cPickle class LRUCache(object): diff --git a/overviewer_core/configParser.py b/overviewer_core/configParser.py index 2d88475..cad7c75 100644 --- a/overviewer_core/configParser.py +++ b/overviewer_core/configParser.py @@ -7,9 +7,6 @@ import traceback import settingsDefinition import settingsValidators -LOG = logging.getLogger(__name__) - - class MissingConfigException(Exception): "To be thrown when the config file can't be found" pass @@ -86,14 +83,14 @@ class MultiWorldParser(object): except Exception, ex: if isinstance(ex, SyntaxError): - LOG.error("Syntax error parsing %s" % settings_file) - LOG.error("The traceback below will tell you which line triggered the syntax error\n") + logging.error("Syntax error parsing %s" % settings_file) + logging.error("The traceback below will tell you which line triggered the syntax error\n") elif isinstance(ex, NameError): - LOG.error("NameError parsing %s" % settings_file) - LOG.error("The traceback below will tell you which line referenced the non-existent variable\n") + logging.error("NameError parsing %s" % settings_file) + logging.error("The traceback below will tell you which line referenced the non-existent variable\n") else: - LOG.error("Error parsing %s" % settings_file) - LOG.error("The traceback below will tell you which line triggered the error\n") + logging.error("Error parsing %s" % settings_file) + logging.error("The traceback below will tell you which line triggered the error\n") # skip the execfile part of the traceback exc_type, exc_value, exc_traceback = sys.exc_info() @@ -105,8 +102,8 @@ class MultiWorldParser(object): else: if "execfile" in l: print_rest = True # on windows, our traceback as no 'execfile'. in this case, print everything - if print_rest: LOG.error("Partial traceback:\n" + "\n".join(lines)) - else: LOG.error("Partial traceback:\n" + "\n".join(formatted_lines)) + if print_rest: logging.error("Partial traceback:\n" + "\n".join(lines)) + else: logging.error("Partial traceback:\n" + "\n".join(formatted_lines)) sys.exit(1) # At this point, make a pass through the file to possibly set global diff --git a/overviewer_core/files.py b/overviewer_core/files.py index 51de642..dc680bb 100644 --- a/overviewer_core/files.py +++ b/overviewer_core/files.py @@ -20,8 +20,6 @@ import shutil import logging import stat -LOG = logging.getLogger(__name__) - ## useful recursive copy, that ignores common OS cruft def mirror_dir(src, dst, entities=None): '''copies all of the entities from src to dst''' @@ -106,7 +104,7 @@ if renameworks: try: os.remove(self.tmpname) except Exception, e: - LOG.warning("An error was raised, so I was doing " + logging.warning("An error was raised, so I was doing " "some cleanup first, but I couldn't remove " "'%s'!", self.tmpname) else: diff --git a/overviewer_core/logger.py b/overviewer_core/logger.py index 48d5bb9..4fd36a3 100644 --- a/overviewer_core/logger.py +++ b/overviewer_core/logger.py @@ -20,8 +20,8 @@ import platform import ctypes from cStringIO import StringIO -# Some cool code for colored logging: For background, add 40. For foreground, -# add 30 +# Some cool code for colored logging: +# For background, add 40. For foreground, add 30 BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE = range(8) RESET_SEQ = "\033[0m" @@ -50,28 +50,6 @@ HIGHLIGHT = { 'WARNING': YELLOW, } -LOG = logging.getLogger(__name__) - - -class InverseLevelFilter(object): - """ - This filter removes all messages *above* a certain threshold - (``max_level``). By default, setting a logger level will log all messages - *above* that level and ignore all messages *below* it. This filter - inverses this logic and only logs messages *below* the given level. - - Note that the given level in ``max_level`` is *excluded* as well. This - means that ``InverseLevelFilter(logging.WARN)`` (the default) will log - messages with the level ``DEBUG`` and ``INFO`` (and everything in - between), but *not* ``WARN`` and above!. - """ - - def __init__(self, max_level=logging.WARN): - self.max_level = max_level - - def filter(self, record): - return record.levelno < self.max_level - class WindowsOutputStream(object): """A file-like object that proxies sys.stderr and interprets simple ANSI @@ -287,44 +265,36 @@ def configure(loglevel=logging.INFO, verbose=False, simple=False): """ - logger = logging.getLogger('overviewer_core') - logger.setLevel(loglevel) - is_windows = platform.system() == 'Windows' + logger = logging.getLogger() + outstream = sys.stdout - errstream = sys.stderr - errformatter = DumbFormatter(verbose) - outformatter = DumbFormatter(verbose) + if simple: + formatter = DumbFormatter(verbose) - if (is_windows or outstream.isatty()) and not simple: - # Our custom output stream processor knows how to deal with select - # ANSI color escape sequences - errformatter = ANSIColorFormatter(verbose) - outformatter = ANSIColorFormatter(verbose) + elif platform.system() == 'Windows': + # Our custom output stream processor knows how to deal with select ANSI + # color escape sequences + outstream = WindowsOutputStream(outstream) + formatter = ANSIColorFormatter(verbose) + elif outstream.isatty(): + # terminal logging with ANSI color + formatter = ANSIColorFormatter(verbose) - if not logger.handlers: - # No handlers have been configure yet... (probably the first call of - # logger.configure) + else: + # Let's not assume anything. Just text. + formatter = DumbFormatter(verbose) - if is_windows: - outstream = WindowsOutputStream(outstream) - errstream = WindowsOutputStream(errstream) + if hasattr(logger, 'overviewerHandler'): + # we have already set up logging so just replace the formatter + # this time with the new values + logger.overviewerHandler.setFormatter(formatter) + logger.setLevel(loglevel) - out_handler = logging.StreamHandler(outstream) - out_handler.addFilter(InverseLevelFilter(max_level=logging.WARN)) - out_handler.set_name('overviewer_stdout_handler') - err_handler = logging.StreamHandler(errstream) - err_handler.set_name('overviewer_stderr_handler') - err_handler.setLevel(logging.WARN) - logger.addHandler(out_handler) - logger.addHandler(err_handler) - - try: - out_handler = logging._handlers['overviewer_stdout_handler'] - err_handler = logging._handlers['overviewer_stderr_handler'] - out_handler.setFormatter(outformatter) - err_handler.setFormatter(errformatter) - out_handler.setLevel(loglevel) - except KeyError as exc: - LOG.warn('Unable to change log handler format ' - '(KeyError for {0})'.format(exc)) + else: + # Save our handler here so we can tell which handler was ours if the + # function is called again + logger.overviewerHandler = logging.StreamHandler(outstream) + logger.overviewerHandler.setFormatter(formatter) + logger.addHandler(logger.overviewerHandler) + logger.setLevel(loglevel) diff --git a/overviewer_core/observer.py b/overviewer_core/observer.py index b64cc39..48e2632 100644 --- a/overviewer_core/observer.py +++ b/overviewer_core/observer.py @@ -20,8 +20,6 @@ import sys import os import json -LOG = logging.getLogger(__name__) - class Observer(object): """Base class that defines the observer interface. """ @@ -95,14 +93,14 @@ class LoggingObserver(Observer): self.last_update = -101 def finish(self): - LOG.info("Rendered %d of %d. %d%% complete", self.get_max_value(), + logging.info("Rendered %d of %d. %d%% complete", self.get_max_value(), self.get_max_value(), 100.0) super(LoggingObserver, self).finish() def update(self, current_value): super(LoggingObserver, self).update(current_value) if self._need_update(): - LOG.info("Rendered %d of %d. %d%% complete", + logging.info("Rendered %d of %d. %d%% complete", self.get_current_value(), self.get_max_value(), self.get_percentage()) self.last_update = current_value @@ -139,7 +137,7 @@ class ProgressBarObserver(progressbar.ProgressBar, Observer): def start(self, max_value): self._set_max_value(max_value) - LOG.info("Rendering %d total tiles." % max_value) + logging.info("Rendering %d total tiles." % max_value) super(ProgressBarObserver, self).start() def is_started(self): @@ -149,7 +147,7 @@ class ProgressBarObserver(progressbar.ProgressBar, Observer): self._end_time = time.time() super(ProgressBarObserver, self).finish() self.fd.write('\n') - LOG.info("Rendering complete!") + logging.info("Rendering complete!") def update(self, current_value): if super(ProgressBarObserver, self).update(current_value): diff --git a/overviewer_core/textures.py b/overviewer_core/textures.py index 34f8989..c7fc482 100644 --- a/overviewer_core/textures.py +++ b/overviewer_core/textures.py @@ -29,9 +29,6 @@ import functools import util from c_overviewer import alpha_over -LOG = logging.getLogger(__name__) - - class TextureException(Exception): "To be thrown when a texture is not found." pass @@ -148,7 +145,7 @@ class Textures(object): 'environment/'. """ - if verbose: LOG.info("Starting search for {0}".format(filename)) + if verbose: logging.info("Starting search for {0}".format(filename)) # a list of subdirectories to search for a given file, # after the obvious '.' @@ -181,7 +178,7 @@ class Textures(object): if os.path.isdir(self.find_file_local_path): path = search_dir(self.find_file_local_path) if path: - if verbose: LOG.info("Found %s in '%s'", filename, path) + if verbose: logging.info("Found %s in '%s'", filename, path) return open(path, mode) elif os.path.isfile(self.find_file_local_path): # Must be a resource pack. Look for the requested file within @@ -193,7 +190,7 @@ class Textures(object): # pack.getinfo() will raise KeyError if the file is # not found. pack.getinfo(packfilename) - if verbose: LOG.info("Found %s in '%s'", packfilename, self.find_file_local_path) + if verbose: logging.info("Found %s in '%s'", packfilename, self.find_file_local_path) return pack.open(packfilename) except (KeyError, IOError): pass @@ -211,24 +208,24 @@ class Textures(object): # If we haven't returned at this point, then the requested file was NOT # found in the user-specified texture path or resource pack. - if verbose: LOG.info("Did not find the file in specified texture path") + if verbose: logging.info("Did not find the file in specified texture path") # Look in the location of the overviewer executable for the given path programdir = util.get_program_path() path = search_dir(programdir) if path: - if verbose: LOG.info("Found %s in '%s'", filename, path) + if verbose: logging.info("Found %s in '%s'", filename, path) return open(path, mode) if sys.platform.startswith("darwin"): path = search_dir("/Applications/Minecraft") if path: - if verbose: LOG.info("Found %s in '%s'", filename, path) + if verbose: logging.info("Found %s in '%s'", filename, path) return open(path, mode) - if verbose: LOG.info("Did not find the file in overviewer executable directory") - if verbose: LOG.info("Looking for installed minecraft jar files...") + if verbose: logging.info("Did not find the file in overviewer executable directory") + if verbose: logging.info("Looking for installed minecraft jar files...") # Find an installed minecraft client jar and look in it for the texture # file we need. @@ -245,7 +242,7 @@ class Textures(object): try: versions = os.listdir(versiondir) - if verbose: LOG.info("Found these versions: {0}".format(versions)) + if verbose: logging.info("Found these versions: {0}".format(versions)) except OSError: # Directory doesn't exist? Ignore it. It will find no versions and # fall through the checks below to the error at the bottom of the @@ -274,7 +271,7 @@ class Textures(object): most_recent_version = versionparts if most_recent_version != [0,0,0]: - if verbose: LOG.info("Most recent version >=1.7.0: {0}. Searching it for the file...".format(most_recent_version)) + if verbose: logging.info("Most recent version >=1.7.0: {0}. Searching it for the file...".format(most_recent_version)) jarname = ".".join(str(x) for x in most_recent_version) jarpath = os.path.join(versiondir, jarname, jarname + ".jar") @@ -284,15 +281,15 @@ class Textures(object): for jarfilename in search_zip_paths: try: jar.getinfo(jarfilename) - if verbose: LOG.info("Found %s in '%s'", jarfilename, jarpath) + if verbose: logging.info("Found %s in '%s'", jarfilename, jarpath) self.jar, self.jarpath = jar, jarpath return jar.open(jarfilename) except (KeyError, IOError), e: pass - if verbose: LOG.info("Did not find file {0} in jar {1}".format(filename, jarpath)) + if verbose: logging.info("Did not find file {0} in jar {1}".format(filename, jarpath)) else: - if verbose: LOG.info("Did not find any non-snapshot minecraft jars >=1.7.0") + if verbose: logging.info("Did not find any non-snapshot minecraft jars >=1.7.0") # Last ditch effort: look for the file is stored in with the overviewer # installation. We include a few files that aren't included with Minecraft @@ -300,16 +297,16 @@ class Textures(object): # they were generated by the game and not stored as images. Nowdays I # believe that's not true, but we still have a few files distributed # with overviewer. - if verbose: LOG.info("Looking for texture in overviewer_core/data/textures") + if verbose: logging.info("Looking for texture in overviewer_core/data/textures") path = search_dir(os.path.join(programdir, "overviewer_core", "data", "textures")) if path: - if verbose: LOG.info("Found %s in '%s'", filename, path) + if verbose: logging.info("Found %s in '%s'", filename, path) return open(path, mode) elif hasattr(sys, "frozen") or imp.is_frozen("__main__"): # windows special case, when the package dir doesn't exist path = search_dir(os.path.join(programdir, "textures")) if path: - if verbose: LOG.info("Found %s in '%s'", filename, path) + if verbose: logging.info("Found %s in '%s'", filename, path) return open(path, mode) raise TextureException("Could not find the textures while searching for '{0}'. Try specifying the 'texturepath' option in your config file.\nSet it to the path to a Minecraft Resource pack.\nAlternately, install the Minecraft client (which includes textures)\nAlso see \n(Remember, this version of Overviewer requires a 1.7-compatible resource pack)\n(Also note that I won't automatically use snapshots; you'll have to use the texturepath option to use a snapshot jar)".format(filename)) @@ -415,7 +412,7 @@ class Textures(object): try: lightcolor = list(self.load_image("light_normal.png").getdata()) except Exception: - LOG.warning("Light color image could not be found.") + logging.warning("Light color image could not be found.") lightcolor = None self.lightcolor = lightcolor return lightcolor diff --git a/overviewer_core/tileset.py b/overviewer_core/tileset.py index 8869788..fe05064 100644 --- a/overviewer_core/tileset.py +++ b/overviewer_core/tileset.py @@ -37,10 +37,6 @@ import rendermodes import c_overviewer from c_overviewer import resize_half - -LOG = logging.getLogger(__name__) - - """ tileset.py contains the TileSet class, and in general, routines that manage a @@ -297,24 +293,24 @@ class TileSet(object): if os.path.exists(self.outputdir): # Somehow there's no config but the output dir DOES exist. # That's strange! - LOG.warning( + logging.warning( "For render '%s' I couldn't find any persistent config, " "but I did find my tile directory already exists. This " "shouldn't normally happen, something may be up, but I " "think I can continue...", self.options['name']) - LOG.info("Switching to --check-tiles mode") + logging.info("Switching to --check-tiles mode") self.options['renderchecks'] = 1 else: # This is the typical code path for an initial render, make # this a "forcerender" self.options['renderchecks'] = 2 - LOG.debug("This is the first time rendering %s. Doing" + + logging.debug("This is the first time rendering %s. Doing" + " a full-render", self.options['name']) elif not os.path.exists(self.outputdir): # Somehow the outputdir got erased but the metadata file is # still there. That's strange! - LOG.warning( + logging.warning( "This is strange. There is metadata for render '%s' but " "the output directory is missing. This shouldn't " "normally happen. I guess we have no choice but to do a " @@ -323,18 +319,18 @@ class TileSet(object): elif config.get("render_in_progress", False): # The last render must have been interrupted. The default should be # a check-tiles render then - LOG.warning( + logging.warning( "The last render for '%s' didn't finish. I'll be " + "scanning all the tiles to make sure everything's up "+ "to date.", self.options['name'], ) - LOG.warning("The total tile count will be (possibly "+ + logging.warning("The total tile count will be (possibly "+ "wildly) inaccurate, because I don't know how many "+ "tiles need rendering. I'll be checking them as I go") self.options['renderchecks'] = 1 else: - LOG.debug("No rendercheck mode specified for %s. "+ + logging.debug("No rendercheck mode specified for %s. "+ "Rendering tile whose chunks have changed since %s", self.options['name'], time.strftime("%x %X", time.localtime(self.last_rendertime)), @@ -343,7 +339,7 @@ class TileSet(object): if not os.path.exists(self.outputdir): if self.options['renderchecks'] != 2: - LOG.warning( + logging.warning( "The tile directory didn't exist, but you have specified " "explicitly not to do a --fullrender (which is the default for " "this situation). I'm overriding your decision and setting " @@ -381,7 +377,7 @@ class TileSet(object): # This warning goes here so it's only shown once if self.treedepth >= 15: - LOG.warning("Just letting you know, your map requries %s zoom levels. This is REALLY big!", + logging.warning("Just letting you know, your map requries %s zoom levels. This is REALLY big!", self.treedepth) # Do any tile re-arranging if necessary. Skip if there was no config @@ -422,7 +418,7 @@ class TileSet(object): # The following block of code implementes the changelist functionality. fd = self.options.get("changelist", None) if fd: - LOG.debug("Changelist activated for %s (fileno %s)", self, fd) + logging.debug("Changelist activated for %s (fileno %s)", self, fd) # This re-implements some of the logic from do_work() def write_out(tilepath): if len(tilepath) == self.treedepth: @@ -614,20 +610,20 @@ class TileSet(object): # Skip a depth 1 tree. A depth 1 tree pretty much can't happen, so # when we detect this it usually means the tree is actually empty return - LOG.debug("Current tree depth for %s is reportedly %s. Target tree depth is %s", + logging.debug("Current tree depth for %s is reportedly %s. Target tree depth is %s", self.options['name'], curdepth, self.treedepth) if self.treedepth != curdepth: if self.treedepth > curdepth: - LOG.warning("Your map seems to have expanded beyond its previous bounds.") - LOG.warning( "Doing some tile re-arrangements... just a sec...") + logging.warning("Your map seems to have expanded beyond its previous bounds.") + logging.warning( "Doing some tile re-arrangements... just a sec...") for _ in xrange(self.treedepth-curdepth): self._increase_depth() elif self.treedepth < curdepth: - LOG.warning("Your map seems to have shrunk. Did you delete some chunks? No problem. Re-arranging tiles, just a sec...") + logging.warning("Your map seems to have shrunk. Did you delete some chunks? No problem. Re-arranging tiles, just a sec...") for _ in xrange(curdepth - self.treedepth): self._decrease_depth() - LOG.info( + logging.info( "There done. I'm switching to --check-tiles mode for " "this one render. This will make sure any old tiles that " "should no longer exist are deleted.") @@ -797,7 +793,7 @@ class TileSet(object): dirty.add(tile.path) t = int(time.time()-stime) - LOG.debug("Finished chunk scan for %s. %s chunks scanned in %s second%s", + logging.debug("Finished chunk scan for %s. %s chunks scanned in %s second%s", self.options['name'], chunkcount, t, "s" if t != 1 else "") @@ -860,10 +856,10 @@ class TileSet(object): # Ignore errors if it's "file doesn't exist" if e.errno != errno.ENOENT: raise - LOG.warning("Tile %s was requested for render, but no children were found! This is probably a bug", imgpath) + logging.warning("Tile %s was requested for render, but no children were found! This is probably a bug", imgpath) return - #LOG.debug("writing out compositetile {0}".format(imgpath)) + #logging.debug("writing out compositetile {0}".format(imgpath)) # Create the actual image now img = Image.new("RGBA", (384, 384), self.options['bgcolor']) @@ -880,12 +876,12 @@ class TileSet(object): resize_half(quad, src) img.paste(quad, path[0]) except Exception, e: - LOG.warning("Couldn't open %s. It may be corrupt. Error was '%s'", path[1], e) - LOG.warning("I'm going to try and delete it. You will need to run the render again and with --check-tiles") + logging.warning("Couldn't open %s. It may be corrupt. Error was '%s'", path[1], e) + logging.warning("I'm going to try and delete it. You will need to run the render again and with --check-tiles") try: os.unlink(path[1]) except Exception, e: - LOG.error("While attempting to delete corrupt image %s, an error was encountered. You will need to delete it yourself. Error was '%s'", path[1], e) + logging.error("While attempting to delete corrupt image %s, an error was encountered. You will need to delete it yourself. Error was '%s'", path[1], e) # Save it with FileReplacer(imgpath) as tmppath: @@ -921,7 +917,7 @@ class TileSet(object): if not chunks: # No chunks were found in this tile - LOG.warning("%s was requested for render, but no chunks found! This may be a bug", tile) + logging.warning("%s was requested for render, but no chunks found! This may be a bug", tile) try: os.unlink(imgpath) except OSError, e: @@ -929,7 +925,7 @@ class TileSet(object): if e.errno != errno.ENOENT: raise else: - LOG.debug("%s deleted", tile) + logging.debug("%s deleted", tile) return # Create the directory if not exists @@ -944,7 +940,7 @@ class TileSet(object): if e.errno != errno.EEXIST: raise - #LOG.debug("writing out worldtile {0}".format(imgpath)) + #logging.debug("writing out worldtile {0}".format(imgpath)) # Compile this image tileimg = Image.new("RGBA", (384, 384), self.options['bgcolor']) @@ -969,10 +965,10 @@ class TileSet(object): except nbt.CorruptionError: # A warning and traceback was already printed by world.py's # get_chunk() - LOG.debug("Skipping the render of corrupt chunk at %s,%s and moving on.", chunkx, chunkz) + logging.debug("Skipping the render of corrupt chunk at %s,%s and moving on.", chunkx, chunkz) except Exception, e: - LOG.error("Could not render chunk %s,%s for some reason. This is likely a render primitive option error.", chunkx, chunkz) - LOG.error("Full error was:", exc_info=1) + logging.error("Could not render chunk %s,%s for some reason. This is likely a render primitive option error.", chunkx, chunkz) + logging.error("Full error was:", exc_info=1) sys.exit(1) ## Semi-handy routine for debugging the drawing routine @@ -1048,14 +1044,14 @@ class TileSet(object): max_chunk_mtime = max(c[5] for c in get_chunks_by_tile(tileobj, self.regionset)) except ValueError: # max got an empty sequence! something went horribly wrong - LOG.warning("tile %s expected contains no chunks! this may be a bug", path) + logging.warning("tile %s expected contains no chunks! this may be a bug", path) max_chunk_mtime = 0 if tile_mtime > 120 + max_chunk_mtime: # If a tile has been modified more recently than any of its # chunks, then this could indicate a potential issue with # this or future renders. - LOG.warning( + logging.warning( "I found a tile with a more recent modification time " "than any of its chunks. This can happen when a tile has " "been modified with an outside program, or by a copy " @@ -1065,7 +1061,7 @@ class TileSet(object): "preserve the mtimes Overviewer sets. Please see our FAQ " "page on docs.overviewer.org or ask us in IRC for more " "information") - LOG.warning("Tile was: %s", imgpath) + logging.warning("Tile was: %s", imgpath) if max_chunk_mtime > tile_mtime: # chunks have a more recent mtime than the tile. Render the tile @@ -1118,7 +1114,7 @@ class TileSet(object): # Check this tile's mtime imgpath = os.path.join(self.outputdir, *(str(x) for x in path)) imgpath += "." + self.imgextension - LOG.debug("Testing mtime for composite-tile %s", imgpath) + logging.debug("Testing mtime for composite-tile %s", imgpath) try: tile_mtime = os.stat(imgpath)[stat.ST_MTIME] except OSError, e: @@ -1146,17 +1142,17 @@ class TileSet(object): if os.path.exists(imgpath): # No need to catch ENOENT since this is only called from the # master process - LOG.debug("Found an image that shouldn't exist. Deleting it: %s", imgpath) + logging.debug("Found an image that shouldn't exist. Deleting it: %s", imgpath) os.remove(imgpath) else: # path referrs to a composite tile, and by extension a directory dirpath = os.path.join(self.outputdir, *(str(x) for x in path)) imgpath = dirpath + "." + self.imgextension if os.path.exists(imgpath): - LOG.debug("Found an image that shouldn't exist. Deleting it: %s", imgpath) + logging.debug("Found an image that shouldn't exist. Deleting it: %s", imgpath) os.remove(imgpath) if os.path.exists(dirpath): - LOG.debug("Found a subtree that shouldn't exist. Deleting it: %s", dirpath) + logging.debug("Found a subtree that shouldn't exist. Deleting it: %s", dirpath) shutil.rmtree(dirpath) ## diff --git a/overviewer_core/world.py b/overviewer_core/world.py index 5b0f994..ecf5f22 100644 --- a/overviewer_core/world.py +++ b/overviewer_core/world.py @@ -27,8 +27,6 @@ import numpy from . import nbt from . import cache -LOG = logging.getLogger(__name__) - """ This module has routines for extracting information about available worlds @@ -51,7 +49,7 @@ def log_other_exceptions(func): except ChunkDoesntExist: raise except Exception, e: - LOG.exception("%s raised this exception", func.func_name) + logging.exception("%s raised this exception", func.func_name) raise return newfunc @@ -106,7 +104,7 @@ class World(object): # Hard-code this to only work with format version 19133, "Anvil" if not ('version' in data and data['version'] == 19133): - LOG.critical("Sorry, This version of Minecraft-Overviewer only works with the 'Anvil' chunk format") + logging.critical("Sorry, This version of Minecraft-Overviewer only works with the 'Anvil' chunk format") raise ValueError("World at %s is not compatible with Overviewer" % self.worlddir) # This isn't much data, around 15 keys and values for vanilla worlds. @@ -155,7 +153,7 @@ class World(object): return self.regionsets[index] else: # assume a get_type() value candids = [x for x in self.regionsets if x.get_type() == index] - LOG.debug("You asked for %r, and I found the following candids: %r", index, candids) + logging.debug("You asked for %r, and I found the following candids: %r", index, candids) if len(candids) > 0: return candids[0] else: @@ -251,8 +249,8 @@ class RegionSet(object): """ self.regiondir = os.path.normpath(regiondir) self.rel = os.path.normpath(rel) - LOG.debug("regiondir is %r" % self.regiondir) - LOG.debug("rel is %r" % self.rel) + logging.debug("regiondir is %r" % self.regiondir) + logging.debug("rel is %r" % self.rel) # we want to get rid of /regions, if it exists if self.rel.endswith(os.path.normpath("/region")): @@ -261,10 +259,10 @@ class RegionSet(object): # this is the main world self.type = None else: - LOG.warning("Unkown region type in %r", regiondir) + logging.warning("Unkown region type in %r", regiondir) self.type = "__unknown" - LOG.debug("Scanning regions. Type is %r" % self.type) + logging.debug("Scanning regions. Type is %r" % self.type) # This is populated below. It is a mapping from (x,y) region coords to filename self.regionfiles = {} @@ -277,7 +275,7 @@ class RegionSet(object): self.regionfiles[(x,y)] = regionfile self.empty_chunk = [None,None] - LOG.debug("Done scanning regions") + logging.debug("Done scanning regions") # Re-initialize upon unpickling def __getstate__(self): @@ -351,22 +349,22 @@ class RegionSet(object): if tries > 0: # Flush the region cache to possibly read a new region file # header - LOG.debug("Encountered a corrupt chunk at %s,%s. Flushing cache and retrying", x, z) - #LOG.debug("Error was:", exc_info=1) + logging.debug("Encountered a corrupt chunk at %s,%s. Flushing cache and retrying", x, z) + #logging.debug("Error was:", exc_info=1) del self.regioncache[regionfile] time.sleep(0.5) continue else: if isinstance(e, nbt.CorruptRegionError): - LOG.warning("Tried several times to read chunk %d,%d. Its region (%d,%d) may be corrupt. Giving up.", + logging.warning("Tried several times to read chunk %d,%d. Its region (%d,%d) may be corrupt. Giving up.", x, z,x//32,z//32) elif isinstance(e, nbt.CorruptChunkError): - LOG.warning("Tried several times to read chunk %d,%d. It may be corrupt. Giving up.", + logging.warning("Tried several times to read chunk %d,%d. It may be corrupt. Giving up.", x, z) else: - LOG.warning("Tried several times to read chunk %d,%d. Unknown error. Giving up.", + logging.warning("Tried several times to read chunk %d,%d. Unknown error. Giving up.", x, z) - LOG.debug("Full traceback:", exc_info=1) + logging.debug("Full traceback:", exc_info=1) # Let this exception propagate out through the C code into # tileset.py, where it is caught and gracefully continues # with the next chunk @@ -456,7 +454,7 @@ class RegionSet(object): try: mcr = self._get_regionobj(regionfile) except nbt.CorruptRegionError: - LOG.warning("Found a corrupt region file at %s,%s. Skipping it.", regionx, regiony) + logging.warning("Found a corrupt region file at %s,%s. Skipping it.", regionx, regiony) continue for chunkx, chunky in mcr.get_chunks(): yield chunkx+32*regionx, chunky+32*regiony, mcr.get_chunk_timestamp(chunkx, chunky) @@ -474,7 +472,7 @@ class RegionSet(object): try: data = self._get_regionobj(regionfile) except nbt.CorruptRegionError: - LOG.warning("Ignoring request for chunk %s,%s; region %s,%s seems to be corrupt", + logging.warning("Ignoring request for chunk %s,%s; region %s,%s seems to be corrupt", x,z, x//32,z//32) return None if data.chunk_exists(x,z): @@ -495,7 +493,7 @@ class RegionSet(object): Returns (regionx, regiony, filename)""" - LOG.debug("regiondir is %s, has type %r", self.regiondir, self.type) + logging.debug("regiondir is %s, has type %r", self.regiondir, self.type) for f in os.listdir(self.regiondir): if re.match(r"^r\.-?\d+\.-?\d+\.mca$", f): @@ -503,7 +501,7 @@ class RegionSet(object): x = int(p[1]) y = int(p[2]) if abs(x) > 500000 or abs(y) > 500000: - LOG.warning("Holy shit what is up with region file %s !?" % f) + logging.warning("Holy shit what is up with region file %s !?" % f) yield (x, y, os.path.join(self.regiondir, f)) class RegionSetWrapper(object): @@ -676,7 +674,7 @@ class CachedRegionSet(RegionSetWrapper): except AttributeError: s += repr(obj) - LOG.debug("Initializing a cache with key '%s'", s) + logging.debug("Initializing a cache with key '%s'", s) s = hashlib.md5(s).hexdigest()