0

Merge branch 'logging' of git://github.com/alexjurkiewicz/Minecraft-Overviewer

This commit is contained in:
Andrew Brown
2010-09-30 22:50:23 -04:00
3 changed files with 44 additions and 27 deletions

17
gmap.py
View File

@@ -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():

View File

@@ -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

View File

@@ -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