Merge branch 'logging' of git://github.com/alexjurkiewicz/Minecraft-Overviewer
This commit is contained in:
17
gmap.py
17
gmap.py
@@ -26,6 +26,9 @@ from optparse import OptionParser
|
||||
import re
|
||||
import multiprocessing
|
||||
import time
|
||||
import logging
|
||||
|
||||
logging.basicConfig(level=logging.INFO,format="%(asctime)s [%(levelname)s] %(message)s")
|
||||
|
||||
import world
|
||||
import quadtree
|
||||
@@ -46,6 +49,8 @@ def main():
|
||||
parser.add_option("--cachedir", dest="cachedir", help="Sets the directory where the Overviewer will save chunk images, which is an intermediate step before the tiles are generated. You must use the same directory each time to gain any benefit from the cache. If not set, this defaults to your world directory.")
|
||||
parser.add_option("--chunklist", dest="chunklist", help="A file containing, on each line, a path to a chunkfile to update. Instead of scanning the world directory for chunks, it will just use this list. Normal caching rules still apply.")
|
||||
parser.add_option("--imgformat", dest="imgformat", help="The image output format to use. Currently supported: png(default), jpg. NOTE: png will always be used as the intermediate image format.")
|
||||
parser.add_option("-q", "--quiet", dest="quiet", action="count", default=0, 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.")
|
||||
|
||||
options, args = parser.parse_args()
|
||||
|
||||
@@ -93,6 +98,14 @@ def main():
|
||||
else:
|
||||
imgformat = 'png'
|
||||
|
||||
logging.getLogger().setLevel(
|
||||
logging.getLogger().level + 10*options.quiet)
|
||||
logging.getLogger().setLevel(
|
||||
logging.getLogger().level - 10*options.verbose)
|
||||
|
||||
logging.info("Welcome to Minecraft Overviewer!")
|
||||
logging.debug("Current log level: {0}".format(logging.getLogger().level))
|
||||
|
||||
# First generate the world's chunk images
|
||||
w = world.WorldRenderer(worlddir, cachedir, chunklist=chunklist)
|
||||
w.go(options.procs)
|
||||
@@ -110,7 +123,7 @@ def delete_all(worlddir, tiledir):
|
||||
for f in filenames:
|
||||
if matcher.match(f):
|
||||
filepath = os.path.join(dirpath, f)
|
||||
print "Deleting {0}".format(filepath)
|
||||
logging.info("Deleting {0}".format(filepath))
|
||||
os.unlink(filepath)
|
||||
|
||||
# Now delete all /hash/ files in the tile dir.
|
||||
@@ -119,7 +132,7 @@ def delete_all(worlddir, tiledir):
|
||||
for f in filenames:
|
||||
if f.endswith(".hash"):
|
||||
filepath = os.path.join(dirpath, f)
|
||||
print "Deleting {0}".format(filepath)
|
||||
logging.info("Deleting {0}".format(filepath))
|
||||
os.unlink(filepath)
|
||||
|
||||
def list_worlds():
|
||||
|
||||
36
quadtree.py
36
quadtree.py
@@ -23,6 +23,7 @@ import re
|
||||
import shutil
|
||||
import collections
|
||||
import json
|
||||
import logging
|
||||
|
||||
from PIL import Image
|
||||
|
||||
@@ -45,7 +46,7 @@ def catch_keyboardinterrupt(func):
|
||||
try:
|
||||
return func(*args, **kwargs)
|
||||
except KeyboardInterrupt:
|
||||
print "Ctrl-C caught!"
|
||||
logging.error("Ctrl-C caught!")
|
||||
raise Exception("Exiting")
|
||||
except:
|
||||
import traceback
|
||||
@@ -111,8 +112,8 @@ class QuadtreeGen(object):
|
||||
else:
|
||||
if not complete % 1000 == 0:
|
||||
return
|
||||
print "{0}/{1} tiles complete on level {2}/{3}".format(
|
||||
complete, total, level, self.p)
|
||||
logging.info("{0}/{1} tiles complete on level {2}/{3}".format(
|
||||
complete, total, level, self.p))
|
||||
|
||||
def write_html(self, zoomlevel, imgformat):
|
||||
"""Writes out index.html"""
|
||||
@@ -258,12 +259,12 @@ class QuadtreeGen(object):
|
||||
curdepth = self._get_cur_depth()
|
||||
if curdepth != -1:
|
||||
if self.p > curdepth:
|
||||
print "Your map seemes to have expanded beyond its previous bounds."
|
||||
print "Doing some tile re-arrangements... just a sec..."
|
||||
logging.warning("Your map seemes to have expanded beyond its previous bounds.")
|
||||
logging.warning( "Doing some tile re-arrangements... just a sec...")
|
||||
for _ in xrange(self.p-curdepth):
|
||||
self._increase_depth()
|
||||
elif self.p < curdepth:
|
||||
print "Your map seems to have shrunk. Re-arranging tiles, just a sec..."
|
||||
logging.warning("Your map seems to have shrunk. Re-arranging tiles, just a sec...")
|
||||
for _ in xrange(curdepth - self.p):
|
||||
self._decrease_depth()
|
||||
|
||||
@@ -279,11 +280,11 @@ class QuadtreeGen(object):
|
||||
results = collections.deque()
|
||||
complete = 0
|
||||
total = 4**self.p
|
||||
print "Rendering highest zoom level of tiles now."
|
||||
print "There are {0} tiles to render".format(total)
|
||||
print "There are {0} total levels to render".format(self.p)
|
||||
print "Don't worry, each level has only 25% as many tiles as the last."
|
||||
print "The others will go faster"
|
||||
logging.info("Rendering highest zoom level of tiles now.")
|
||||
logging.info("There are {0} tiles to render".format(total))
|
||||
logging.info("There are {0} total levels to render".format(self.p))
|
||||
logging.info("Don't worry, each level has only 25% as many tiles as the last.")
|
||||
logging.info("The others will go faster")
|
||||
for result in self._apply_render_worldtiles(pool):
|
||||
results.append(result)
|
||||
if len(results) > 10000:
|
||||
@@ -308,7 +309,7 @@ class QuadtreeGen(object):
|
||||
assert len(results) == 0
|
||||
complete = 0
|
||||
total = 4**zoom
|
||||
print "Starting level", level
|
||||
logging.info("Starting level {0}".format(level))
|
||||
for result in self._apply_render_inntertile(pool, zoom):
|
||||
results.append(result)
|
||||
if len(results) > 10000:
|
||||
@@ -324,7 +325,7 @@ class QuadtreeGen(object):
|
||||
|
||||
self.print_statusline(complete, total, level, True)
|
||||
|
||||
print "Done"
|
||||
logging.info("Done")
|
||||
|
||||
pool.close()
|
||||
pool.join()
|
||||
@@ -561,8 +562,7 @@ def render_worldtile(chunks, colstart, colend, rowstart, rowend, path, imgformat
|
||||
# corrupting it), then this could error.
|
||||
# Since we have no easy way of determining how this chunk was
|
||||
# generated, we need to just ignore it.
|
||||
print "Error opening file", chunkfile
|
||||
print "(Error was {0})".format(e)
|
||||
logging.warning("Could not open chunk '{0}' ({1})".format(chunkfile,e))
|
||||
try:
|
||||
# Remove the file so that the next run will re-generate it.
|
||||
os.unlink(chunkfile)
|
||||
@@ -571,12 +571,12 @@ def render_worldtile(chunks, colstart, colend, rowstart, rowend, path, imgformat
|
||||
# Ignore if file doesn't exist, another task could have already
|
||||
# removed it.
|
||||
if e.errno != errno.ENOENT:
|
||||
print "Could not remove the corrupt chunk!"
|
||||
logging.warning("Could not remove chunk '{0}'!".format(chunkfile))
|
||||
raise
|
||||
else:
|
||||
print "Removed the corrupt file"
|
||||
logging.warning("Removed the corrupt file")
|
||||
|
||||
print "You will need to re-run the Overviewer to fix this chunk"
|
||||
logging.warning("You will need to re-run the Overviewer to fix this chunk")
|
||||
continue
|
||||
|
||||
xpos = -192 + (col-colstart)*192
|
||||
|
||||
18
world.py
18
world.py
@@ -18,6 +18,7 @@ import os
|
||||
import os.path
|
||||
import multiprocessing
|
||||
import sys
|
||||
import logging
|
||||
|
||||
import numpy
|
||||
|
||||
@@ -170,8 +171,9 @@ class WorldRenderer(object):
|
||||
def go(self, procs):
|
||||
"""Starts the render. This returns when it is finished"""
|
||||
|
||||
print "Scanning chunks"
|
||||
logging.info("Scanning chunks")
|
||||
raw_chunks = self._find_chunkfiles()
|
||||
logging.debug("Done scanning chunks")
|
||||
|
||||
# Translate chunks to our diagonal coordinate system
|
||||
mincol, maxcol, minrow, maxrow, chunks = _convert_coords(raw_chunks)
|
||||
@@ -205,9 +207,11 @@ class WorldRenderer(object):
|
||||
p = f.split(".")
|
||||
all_chunks.append((base36decode(p[1]), base36decode(p[2]),
|
||||
os.path.join(dirpath, f)))
|
||||
logging.debug((base36decode(p[1]), base36decode(p[2]),
|
||||
os.path.join(dirpath, f)))
|
||||
|
||||
if not all_chunks:
|
||||
print "Error: No chunks found!"
|
||||
logging.error("Error: No chunks found!")
|
||||
sys.exit(1)
|
||||
return all_chunks
|
||||
|
||||
@@ -228,7 +232,7 @@ class WorldRenderer(object):
|
||||
results = {}
|
||||
if processes == 1:
|
||||
# Skip the multiprocessing stuff
|
||||
print "Rendering chunks synchronously since you requested 1 process"
|
||||
logging.debug("Rendering chunks synchronously since you requested 1 process")
|
||||
for i, (col, row, chunkfile) in enumerate(chunks):
|
||||
if inclusion_set and (col, row) not in inclusion_set:
|
||||
# Skip rendering, just find where the existing image is
|
||||
@@ -242,9 +246,9 @@ class WorldRenderer(object):
|
||||
results[(col, row)] = result
|
||||
if i > 0:
|
||||
if 1000 % i == 0 or i % 1000 == 0:
|
||||
print "{0}/{1} chunks rendered".format(i, len(chunks))
|
||||
logging.info("{0}/{1} chunks rendered".format(i, len(chunks)))
|
||||
else:
|
||||
print "Rendering chunks in {0} processes".format(processes)
|
||||
logging.debug("Rendering chunks in {0} processes".format(processes))
|
||||
pool = multiprocessing.Pool(processes=processes)
|
||||
asyncresults = []
|
||||
for col, row, chunkfile in chunks:
|
||||
@@ -267,10 +271,10 @@ class WorldRenderer(object):
|
||||
results[(col, row)] = result.get()
|
||||
if i > 0:
|
||||
if 1000 % i == 0 or i % 1000 == 0:
|
||||
print "{0}/{1} chunks rendered".format(i, len(asyncresults))
|
||||
logging.info("{0}/{1} chunks rendered".format(i, len(asyncresults)))
|
||||
|
||||
pool.join()
|
||||
print "Done!"
|
||||
logging.info("Done!")
|
||||
|
||||
return results
|
||||
|
||||
|
||||
Reference in New Issue
Block a user