0

overviewer: code style and consistency fixes

A good sprinkling of PEP8 fixes. We're also getting rid of some
odd manual linebreaks in the output messages, and making sure to
end sentences with a period where appropriate. Help messages have
also been made more consistent, e.g. "Tries" -> "Try" and so forth.
This commit is contained in:
Nicolas F
2019-03-06 14:27:04 +01:00
parent 4ffa0be456
commit ef66efd140

View File

@@ -47,6 +47,7 @@ helptext = """
%prog [--rendermodes=...] [options] <World> <Output Dir>
%prog --config=<config file> [options]"""
def main():
# bootstrap the logger with defaults
logger.configure()
@@ -66,57 +67,65 @@ def main():
except NotImplementedError:
cpus = 1
#avail_rendermodes = c_overviewer.get_render_modes()
avail_north_dirs = ['lower-left', 'upper-left', 'upper-right', 'lower-right', 'auto']
# Parse for basic options
parser = OptionParser(usage=helptext, add_help_option=False)
parser.add_option("-h", "--help", dest="help", action="store_true",
help="show this help message and exit")
parser.add_option("-c", "--config", dest="config", action="store", help="Specify the config file to use.")
help="Show this help message and exit.")
parser.add_option("-c", "--config", dest="config", action="store",
help="Specify the config file to use.")
parser.add_option("-p", "--processes", dest="procs", action="store", type="int",
help="The number of local worker processes to spawn. Defaults to the number of CPU cores your computer has")
help="The number of local worker processes to spawn. Defaults to the number "
"of CPU cores your computer has.")
parser.add_option("--pid", dest="pid", action="store", help="Specify the pid file to use.")
# Options that only apply to the config-less render usage
parser.add_option("--rendermodes", dest="rendermodes", action="store",
help="If you're not using a config file, specify which rendermodes to render with this option. This is a comma-separated list.")
help="If you're not using a config file, specify which rendermodes to "
"render with this option. This is a comma-separated list.")
# Useful one-time render modifiers:
parser.add_option("--forcerender", dest="forcerender", action="store_true",
help="Force re-rendering the entire map.")
help="Force re-render the entire map.")
parser.add_option("--check-tiles", dest="checktiles", action="store_true",
help="Check each tile on disk and re-render old tiles")
help="Check each tile on disk and re-render old tiles.")
parser.add_option("--no-tile-checks", dest="notilechecks", action="store_true",
help="Only render tiles that come from chunks that have changed since the last render (the default)")
help="Only render tiles that come from chunks that have changed since the "
"last render (the default).")
# Useful one-time debugging options:
parser.add_option("--check-terrain", dest="check_terrain", action="store_true",
help="Tries to locate the texture files. Useful for debugging texture problems.")
help="Try to locate the texture files. Useful for debugging texture"
" problems.")
parser.add_option("-V", "--version", dest="version",
help="Displays version information and then exits", action="store_true")
help="Display version information and then exits.", action="store_true")
parser.add_option("--check-version", dest="checkversion",
help="Fetchs information about the latest version of Overviewer", action="store_true")
help="Fetch information about the latest version of Overviewer.",
action="store_true")
parser.add_option("--update-web-assets", dest='update_web_assets', action="store_true",
help="Update web assets. Will *not* render tiles or update overviewerConfig.js")
help="Update web assets. Will *not* render tiles or update "
"overviewerConfig.js.")
# Log level options:
parser.add_option("-q", "--quiet", dest="quiet", action="count", default=0,
help="Print less output. You can specify this option multiple times.")
help="Print less output. You can specify this option multiple times.")
parser.add_option("-v", "--verbose", dest="verbose", action="count", default=0,
help="Print more output. You can specify this option multiple times.")
help="Print more output. You can specify this option multiple times.")
parser.add_option("--simple-output", dest="simple", action="store_true", default=False,
help="Use a simple output format, with no colors or progress bars")
help="Use a simple output format, with no colors or progress bars.")
# create a group for "plugin exes" (the concept of a plugin exe is only loosly defined at this point)
# create a group for "plugin exes"
# (the concept of a plugin exe is only loosely defined at this point)
exegroup = OptionGroup(parser, "Other Scripts",
"These scripts may accept different arguments than the ones listed above")
"These scripts may accept different arguments than the ones "
"listed above")
exegroup.add_option("--genpoi", dest="genpoi", action="store_true",
help="Runs the genPOI script")
help="Run the genPOI script.")
exegroup.add_option("--skip-scan", dest="skipscan", action="store_true",
help="When running GenPOI, don't scan for entities")
help="When running GenPOI, don't scan for entities.")
exegroup.add_option("--skip-players", dest="skipplayers", action="store_true",
help="When running GenPOI, don't get player data")
help="When running GenPOI, don't scan player data.")
parser.add_option_group(exegroup)
@@ -126,7 +135,6 @@ def main():
if options.genpoi:
# remove the "--genpoi" option from sys.argv before running genPI
sys.argv.remove("--genpoi")
#sys.path.append(".")
g = __import__("overviewer_core.aux_files", {}, {}, ["genPOI"])
g.genPOI.main()
return 0
@@ -135,9 +143,8 @@ def main():
return 0
# re-configure the logger now that we've processed the command line options
logger.configure(logging.INFO + 10*options.quiet - 10*options.verbose,
verbose=options.verbose > 0,
simple=options.simple)
logger.configure(logging.INFO + 10 * options.quiet - 10 * options.verbose,
verbose=options.verbose > 0, simple=options.simple)
##########################################################################
# This section of main() runs in response to any one-time options we have,
@@ -149,8 +156,9 @@ def main():
import overviewer_core.overviewer_version as overviewer_version
print("built on %s" % overviewer_version.BUILD_DATE)
if options.verbose > 0:
print("Build machine: %s %s" % (overviewer_version.BUILD_PLATFORM, overviewer_version.BUILD_OS))
print("Read version information from %r"% overviewer_version.__file__)
print("Build machine: %s %s" % (overviewer_version.BUILD_PLATFORM,
overviewer_version.BUILD_OS))
print("Read version information from %r" % overviewer_version.__file__)
except ImportError:
print("(build info not found)")
if options.verbose > 0:
@@ -164,31 +172,32 @@ def main():
try:
import urllib
import json
latest_ver = json.loads(urllib.urlopen("http://overviewer.org/download.json").read())['src']
print("Latest version of Minecraft Overviewer %s (%s)" % (latest_ver['version'], latest_ver['commit'][:7]))
print("See http://overviewer.org/downloads for more information")
latest_ver = json.loads(urllib.urlopen("http://overviewer.org/download.json")
.read())['src']
print("Latest version of Minecraft Overviewer %s (%s)" % (latest_ver['version'],
latest_ver['commit'][:7]))
print("See https://overviewer.org/downloads for more information.")
except Exception:
print("Failed to fetch latest version info.")
if options.verbose > 0:
import traceback
traceback.print_exc()
else:
print("Re-run with --verbose for more details")
print("Re-run with --verbose for more details.")
return 1
return 0
if options.pid:
if os.path.exists(options.pid):
try:
with open(options.pid, 'r') as fpid:
pid = int(fpid.read())
if util.pid_exists(pid):
print("Already running (pid exists) - exiting..")
print("Overviewer is already running (pid exists) - exiting.")
return 0
except (IOError, ValueError):
pass
with open(options.pid,"w") as f:
with open(options.pid, "w") as f:
f.write(str(os.getpid()))
# if --check-terrain was specified, but we have NO config file, then we cannot
# operate on a custom texture path. we do terrain checking with a custom texture
@@ -225,7 +234,8 @@ def main():
else:
# more helpful message for users who know what they're doing
logging.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
@@ -236,13 +246,14 @@ def main():
# given, and vice versa
if options.config and args:
print()
print("If you specify --config, you need to specify the world to render as well as")
print("the destination in the config file, not on the command line.")
print("If you specify --config, you need to specify the world to render as well as "
"the destination in the config file, not on the command line.")
print("Put something like this in your config file:")
print("worlds['myworld'] = %r" % args[0])
print("outputdir = %r" % (args[1] if len(args) > 1 else "/path/to/output"))
print()
logging.error("Cannot specify both --config AND a world + output directory on the command line.")
logging.error("You cannot specify both --config AND a world + output directory on the "
"command line.")
parser.print_help()
return 1
@@ -255,10 +266,12 @@ def main():
# properly escape it attempt to detect this case
for start in range(len(args)):
if not os.path.exists(args[start]):
for end in range(start+1, len(args)+1):
for end in range(start + 1, len(args) + 1):
if os.path.exists(" ".join(args[start:end])):
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]))
logging.warning(
"It looks like you meant to specify \"%s\" as your world dir or your "
"output dir but you forgot to put quotes around the directory, since "
"it contains spaces." % " ".join(args[start:end]))
return 1
logging.error("Too many command line arguments")
parser.print_help()
@@ -280,21 +293,22 @@ dir but you forgot to put quotes around the directory, since it contains spaces.
rendermodes = ['lighting']
if options.rendermodes:
rendermodes = options.rendermodes.replace("-","_").split(",")
rendermodes = options.rendermodes.replace("-", "_").split(",")
# Now for some good defaults
renders = util.OrderedDict()
for rm in rendermodes:
renders["world-" + rm] = {
"world": "world",
"title": "Overviewer Render (%s)" % rm,
"rendermode": rm,
}
"world": "world",
"title": "Overviewer Render (%s)" % rm,
"rendermode": rm,
}
mw_parser.set_config_item("renders", renders)
else:
if options.rendermodes:
logging.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
@@ -316,16 +330,17 @@ 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:
logging.exception("An error was encountered with your configuration. See the info below.")
else: # no need to print scary traceback! just
logging.exception("An error was encountered with your configuration. "
"See the information below.")
else: # no need to print scary traceback!
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
if options.check_terrain: # we are already in the "if configfile" branch
logging.info("Looking for a few common texture files...")
for render_name, render in config['renders'].iteritems():
logging.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"])
@@ -340,40 +355,42 @@ dir but you forgot to put quotes around the directory, since it contains spaces.
############################################################
# Final validation steps and creation of the destination directory
logging.info("Welcome to Minecraft Overviewer!")
logging.debug("Current log level: {0}".format(logging.getLogger().level))
logging.debug("Current log level: {0}.".format(logging.getLogger().level))
# Override some render configdict options depending on one-time command line
# modifiers
if (
bool(options.forcerender) +
bool(options.checktiles) +
bool(options.notilechecks)
) > 1:
logging.error("You cannot specify more than one of --forcerender, "+
"--check-tiles, and --no-tile-checks. These options conflict.")
bool(options.forcerender) +
bool(options.checktiles) +
bool(options.notilechecks)
) > 1:
logging.error("You cannot specify more than one of --forcerender, "
"--check-tiles, and --no-tile-checks. These options conflict.")
parser.print_help()
return 1
def set_renderchecks(checkname, num):
for name, render in config['renders'].iteritems():
if render.get('renderchecks', 0) == 3:
logging.warning(checkname + " ignoring render " + repr(name) + " since it's marked as \"don't render\".")
logging.warning(checkname + " ignoring render " + repr(name) + " since it's "
"marked as \"don't render\".")
else:
render['renderchecks'] = num
if options.forcerender:
logging.info("Forcerender mode activated. ALL tiles will be rendered")
logging.info("Forcerender mode activated. ALL tiles will be rendered.")
set_renderchecks("forcerender", 2)
elif options.checktiles:
logging.info("Checking all tiles for updates manually.")
set_renderchecks("checktiles", 1)
elif options.notilechecks:
logging.info("Disabling all tile mtime checks. Only rendering tiles "+
"that need updating since last render")
logging.info("Disabling all tile mtime checks. Only rendering tiles "
"that need updating since last render.")
set_renderchecks("notilechecks", 0)
if not config['renders']:
logging.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. Check the "
"documentation at http://docs.overviewer.org if you're having trouble.")
return 1
#####################
@@ -384,8 +401,8 @@ dir but you forgot to put quotes around the directory, since it contains spaces.
try:
worldpath = config['worlds'][render['world']]
except KeyError:
logging.error("Render %s's world is '%s', but I could not find a corresponding entry in the worlds dictionary.",
rname, render['world'])
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']
render['world'] = worldpath
@@ -401,8 +418,8 @@ dir but you forgot to put quotes around the directory, since it contains spaces.
try:
renderLink = config['renders'][x]
except KeyError:
logging.error("Render %s's overlay is '%s', but I could not find a corresponding entry in the renders dictionary.",
rname, x)
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:
logging.error("Render %s's overlay contains itself.", rname)
@@ -426,10 +443,10 @@ dir but you forgot to put quotes around the directory, since it contains spaces.
# create our asset manager... ASSMAN
assetMrg = assetmanager.AssetManager(destdir, config.get('customwebassets', None))
# If we've been asked to update web assets, do that and then exit
# If we've been asked to update web assets, do that and then exit
if options.update_web_assets:
assetMrg.output_noconfig()
logging.info("Web assets have been updated")
logging.info("Web assets have been updated.")
return 0
# The changelist support.
@@ -439,7 +456,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")
logging.debug("Opening changelist %s (%s)", out, out.fileno())
logging.debug("Opening changelist %s (%s).", out, out.fileno())
changelists[path] = out
else:
out = changelists[path]
@@ -468,7 +485,7 @@ dir but you forgot to put quotes around the directory, since it contains spaces.
try:
w = world.World(render['world'])
except CorruptNBTError, e:
logging.error("Failed to open world %r", render['world'])
logging.error("Failed to open world %r.", render['world'])
raise e
except world.UnsupportedVersion, e:
for ln in str(e).split('\n'):
@@ -484,19 +501,21 @@ dir but you forgot to put quotes around the directory, since it contains spaces.
tex = textures.Textures(**texopts)
logging.info("Generating textures...")
tex.generate()
logging.debug("Finished generating textures")
logging.debug("Finished generating textures.")
texcache[texopts_key] = tex
else:
tex = texcache[texopts_key]
try:
logging.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:
logging.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:
logging.warn("Sorry, you requested dimension '%s' for %s, but I couldn't find it", render['dimension'][0], render_name)
if rset is None: # indicates no such dimension was found
logging.warn("Sorry, you requested dimension '%s' for %s, but I couldn't find it.",
render['dimension'][0], render_name)
continue
#################
@@ -532,23 +551,22 @@ dir but you forgot to put quotes around the directory, since it contains spaces.
tileset_dir = os.path.abspath(os.path.join(destdir, render_name))
# only pass to the TileSet the options it really cares about
render['name'] = render_name # perhaps a hack. This is stored here for the asset manager
render['name'] = render_name # perhaps a hack. This is stored here for the asset manager
tileSetOpts = util.dict_subset(render, [
"name", "imgformat", "renderchecks", "rerenderprob", "bgcolor", "defaultzoom",
"imgquality", "imglossless", "optimizeimg", "rendermode", "worldname_orig", "title",
"dimension", "changelist", "showspawn", "overlay", "base", "poititle", "maxzoom",
"showlocationmarker", "minzoom"])
tileSetOpts.update({"spawn": w.find_true_spawn()}) # TODO find a better way to do this
tileSetOpts.update({"spawn": w.find_true_spawn()}) # TODO find a better way to do this
for rset in rsets:
tset = tileset.TileSet(w, rset, assetMrg, tex, tileSetOpts, tileset_dir)
tilesets.append(tset)
# If none of the requested dimenstions exist, tilesets will be empty
if not tilesets:
logging.error("There are no tilesets to render! There's nothing to do, so exiting.")
logging.error("There are no tilesets to render! There's nothing to do, so exiting.")
return 1
# Do tileset preprocessing here, before we start dispatching jobs
logging.info("Preprocessing...")
for ts in tilesets:
@@ -569,7 +587,7 @@ dir but you forgot to put quotes around the directory, since it contains spaces.
assetMrg.finalize(tilesets)
for out in changelists.itervalues():
logging.debug("Closing %s (%s)", out, out.fileno())
logging.debug("Closing %s (%s).", out, out.fileno())
out.close()
if config['processes'] == 1:
@@ -579,16 +597,17 @@ dir but you forgot to put quotes around the directory, since it contains spaces.
if options.pid:
os.remove(options.pid)
logging.info("Your render has been written to '%s', open index.html to view it" % destdir)
logging.info("Your render has been written to '%s', open index.html to view it." % destdir)
return 0
def list_worlds():
"Prints out a brief summary of saves found in the default directory"
print
worlds = world.get_worlds()
if not worlds:
print('No world saves found in the usual place')
print('No world saves found in the usual place.')
return
print("Detected saves:")
@@ -597,7 +616,7 @@ def list_worlds():
formatString = "%-" + str(worldNameLen) + "s | %-8s | %-16s | %s "
print(formatString % ("World", "Playtime", "Modified", "Path"))
print(formatString % ("-"*worldNameLen, "-"*8, '-'*16, '-'*4))
print(formatString % ("-" * worldNameLen, "-" * 8, '-' * 16, '-' * 4))
for name, info in sorted(worlds.iteritems()):
if isinstance(name, basestring) and name.startswith("World") and len(name) == 6:
try:
@@ -608,8 +627,7 @@ def list_worlds():
except ValueError:
pass
if info['LastPlayed'] > 0:
timestamp = time.strftime("%Y-%m-%d %H:%M",
time.localtime(info['LastPlayed'] / 1000))
timestamp = time.strftime("%Y-%m-%d %H:%M", time.localtime(info['LastPlayed'] / 1000))
else:
timestamp = ""
if info['Time'] > 0:
@@ -623,8 +641,9 @@ def list_worlds():
if found_corrupt:
print("")
print("An error has been detected in one or more of your worlds (see the above table).")
print("This is usually due to a corrupt level.dat file. Corrupt worlds need to be")
print("repaired before Overviewer can render them.")
print("This is usually due to a corrupt level.dat file. Corrupt worlds need to be "
"repaired before Overviewer can render them.")
if __name__ == "__main__":
multiprocessing.freeze_support()