def output_noconfig(self): # copy web assets into destdir: global_assets = os.path.join(util.get_program_path(), "overviewer_core", "data", "web_assets") if not os.path.isdir(global_assets): global_assets = os.path.join(util.get_program_path(), "web_assets") mirror_dir(global_assets, self.outputdir, capabilities=self.fs_caps) if self.custom_assets_dir: # Could have done something fancy here rather than just overwriting # the global files, but apparently this what we used to do pre-rewrite. mirror_dir(self.custom_assets_dir, self.outputdir, capabilities=self.fs_caps) # write a dummy baseMarkers.js if none exists if not os.path.exists(os.path.join(self.outputdir, "baseMarkers.js")): with open(os.path.join(self.outputdir, "baseMarkers.js"), "w") as f: f.write("// if you wants signs, please see genPOI.py\n") # create overviewer.js from the source js files js_src = os.path.join(util.get_program_path(), "overviewer_core", "data", "js_src") if not os.path.isdir(js_src): js_src = os.path.join(util.get_program_path(), "js_src") with FileReplacer(os.path.join(self.outputdir, "overviewer.js"), capabilities=self.fs_caps) as tmpfile: with open(tmpfile, "w") as fout: # first copy in js_src/overviewer.js with open(os.path.join(js_src, "overviewer.js"), 'r') as f: fout.write(f.read()) # now copy in the rest for js in os.listdir(js_src): if not js.endswith("overviewer.js") and js.endswith(".js"): with open(os.path.join(js_src, js)) as f: fout.write(f.read()) # Add time and version in index.html indexpath = os.path.join(self.outputdir, "index.html") index = codecs.open(indexpath, 'r', encoding='UTF-8').read() index = index.replace("{title}", "Minecraft Overviewer") index = index.replace("{google_api_key}", self.google_api_key) index = index.replace( "{time}", time.strftime("%a, %d %b %Y %H:%M:%S %Z", time.localtime()).decode(self.preferredencoding)) versionstr = "%s (%s)" % (util.findGitVersion(), util.findGitHash()[:7]) index = index.replace("{version}", versionstr) with FileReplacer(indexpath, capabilities=self.fs_caps) as indexpath: with codecs.open(indexpath, 'w', encoding='UTF-8') as output: output.write(index)
def write_html(self, skipjs=False): """Writes out config.js, marker.js, and region.js Copies web assets into the destdir""" zoomlevel = self.p imgformat = self.imgformat configpath = os.path.join(util.get_program_path(), "config.js") config = open(configpath, 'r').read() config = config.replace( "{maxzoom}", str(zoomlevel)) config = config.replace( "{imgformat}", str(imgformat)) with open(os.path.join(self.destdir, "config.js"), 'w') as output: output.write(config) # Write a blank image blank = Image.new("RGBA", (1,1)) tileDir = os.path.join(self.destdir, "tiles") if not os.path.exists(tileDir): os.mkdir(tileDir) blank.save(os.path.join(tileDir, "blank."+self.imgformat)) # copy web assets into destdir: for root, dirs, files in os.walk(os.path.join(util.get_program_path(), "web_assets")): for f in files: shutil.copy(os.path.join(root, f), self.destdir) if skipjs: return # since we will only discover PointsOfInterest in chunks that need to be # [re]rendered, POIs like signs in unchanged chunks will not be listed # in self.world.POI. To make sure we don't remove these from markers.js # we need to merge self.world.POI with the persistant data in world.PersistentData self.world.POI += filter(lambda x: x['type'] != 'spawn', self.world.persistentData['POI']) # write out the default marker table with open(os.path.join(self.destdir, "markers.js"), 'w') as output: output.write("var markerData=%s" % json.dumps(self.world.POI)) # save persistent data self.world.persistentData['POI'] = self.world.POI with open(self.world.pickleFile,"wb") as f: cPickle.dump(self.world.persistentData,f) # write out the default (empty, but documented) region table with open(os.path.join(self.destdir, "regions.js"), 'w') as output: output.write('var regionData=[\n') output.write(' // {"color": "#FFAA00", "opacity": 0.5, "closed": true, "path": [\n') output.write(' // {"x": 0, "y": 0, "z": 0},\n') output.write(' // {"x": 0, "y": 10, "z": 0},\n') output.write(' // {"x": 0, "y": 0, "z": 10}\n') output.write(' // ]},\n') output.write('];')
def output_noconfig(self): # copy web assets into destdir: # global_assets = os.path.join(util.get_program_path(), "overviewer_core", "data", "web_assets") # global_assets_js = os.path.join(util.get_program_path(), "overviewer_core", "data", "js") # global_assets_images = os.path.join(util.get_program_path(), "overviewer_core", "data", "images") # global_assets_css = os.path.join(util.get_program_path(), "overviewer_core", "data", "css") # if not os.path.isdir(global_assets_js): # global_assets_js = os.path.join(util.get_program_path(), "web_assets") # mirror_dir(global_assets_js, self.js_outputdir) # # if not os.path.isdir(global_assets_images): # global_assets_images = os.path.join(util.get_program_path(), "web_assets") # mirror_dir(global_assets_images, self.img_outputdir) # # if not os.path.isdir(global_assets_css): # global_assets_css = os.path.join(util.get_program_path(), "web_assets") # mirror_dir(global_assets_css, self.css_outputdir) # We have to let this one happen later on the index is needed # if not os.path.isdir(global_assets): # global_assets = os.path.join(util.get_program_path(), "web_assets") # mirror_dir(global_assets, self.outputdir) if self.custom_assets_dir: # Could have done something fancy here rather than just overwriting # the global files, but apparently this what we used to do pre-rewrite. mirror_dir(self.custom_assets_dir, self.outputdir) # write a dummy baseMarkers.js if none exists if not os.path.exists(os.path.join(self.js_outputdir, "baseMarkers.js")): with open(os.path.join(self.js_outputdir, "baseMarkers.js"), "w") as f: f.write("// if you wants signs, please see genPOI.py\n") # create overviewer.js from the source js files js_src = os.path.join(util.get_program_path(), "overviewer_core", "data", "js_src") if not os.path.isdir(js_src): js_src = os.path.join(util.get_program_path(), "js_src") with FileReplacer(os.path.join(self.js_outputdir, "overviewer.js")) as tmpfile: with open(tmpfile, "w") as fout: # first copy in js_src/overviewer.js with open(os.path.join(js_src, "overviewer.js"), "r") as f: fout.write(f.read()) # now copy in the rest for js in os.listdir(js_src): if not js.endswith("overviewer.js") and js.endswith(".js"): with open(os.path.join(js_src, js)) as f: fout.write(f.read())
def output_noconfig(self): # copy web assets into destdir: global_assets = os.path.join(util.get_program_path(), "overviewer_core", "data", "web_assets") if not os.path.isdir(global_assets): global_assets = os.path.join(util.get_program_path(), "web_assets") mirror_dir(global_assets, self.outputdir, capabilities=self.fs_caps) if self.custom_assets_dir: # Could have done something fancy here rather than just overwriting # the global files, but apparently this what we used to do pre-rewrite. mirror_dir(self.custom_assets_dir, self.outputdir, capabilities=self.fs_caps) # write a dummy baseMarkers.js if none exists if not os.path.exists(os.path.join(self.outputdir, "baseMarkers.js")): with open(os.path.join(self.outputdir, "baseMarkers.js"), "w") as f: f.write("// if you wants signs, please see genPOI.py\n") # create overviewer.js from the source js files js_src = os.path.join(util.get_program_path(), "overviewer_core", "data", "js_src") if not os.path.isdir(js_src): js_src = os.path.join(util.get_program_path(), "js_src") with FileReplacer(os.path.join(self.outputdir, "overviewer.js"), capabilities=self.fs_caps) as tmpfile: with open(tmpfile, "w") as fout: # first copy in js_src/overviewer.js with open(os.path.join(js_src, "overviewer.js"), "r") as f: fout.write(f.read()) # now copy in the rest for js in os.listdir(js_src): if not js.endswith("overviewer.js") and js.endswith(".js"): with open(os.path.join(js_src, js)) as f: fout.write(f.read()) # Add time and version in index.html indexpath = os.path.join(self.outputdir, "index.html") index = codecs.open(indexpath, "r", encoding="UTF-8").read() index = index.replace("{title}", "Minecraft Overviewer") index = index.replace( "{time}", time.strftime("%a, %d %b %Y %H:%M:%S %Z", time.localtime()).decode(self.preferredencoding) ) versionstr = "%s (%s)" % (util.findGitVersion(), util.findGitHash()[:7]) index = index.replace("{version}", versionstr) with FileReplacer(indexpath, capabilities=self.fs_caps) as indexpath: with codecs.open(indexpath, "w", encoding="UTF-8") as output: output.write(index)
def go(self, procs): """Writes out config.js, marker.js, and region.js Copies web assets into the destdir""" zoomlevel = self.p bgcolor = (int(self.bg_color[1:3], 16), int(self.bg_color[3:5], 16), int(self.bg_color[5:7], 16), 0) blank = Image.new("RGBA", (1, 1), bgcolor) # Write a blank image for quadtree in self.quadtrees: tileDir = os.path.join(self.destdir, quadtree.tiledir) if not os.path.exists(tileDir): os.mkdir(tileDir) blank.save(os.path.join(tileDir, "blank." + quadtree.imgformat)) # copy web assets into destdir: mirror_dir(os.path.join(util.get_program_path(), "web_assets"), self.destdir) # do the same with the local copy, if we have it if self.web_assets_path: mirror_dir(self.web_assets_path, self.destdir) # replace the config js stuff config = open(os.path.join(self.destdir, "overviewerConfig.js"), "r").read() config = config.replace("{minzoom}", str(0)) config = config.replace("{maxzoom}", str(zoomlevel)) config = config.replace("{spawn_coords}", json.dumps(list(self.world.spawn))) # config = config.replace("{bg_color}", self.bg_color) # create generated map type data, from given quadtrees maptypedata = map( lambda q: { "label": q.rendermode.capitalize(), "path": q.tiledir, "bg_color": self.bg_color, "overlay": "overlay" in get_render_mode_inheritance(q.rendermode), "imgformat": q.imgformat, }, self.quadtrees, ) config = config.replace("{maptypedata}", json.dumps(maptypedata)) with open(os.path.join(self.destdir, "overviewerConfig.js"), "w") as output: output.write(config) # Add time and version in index.html indexpath = os.path.join(self.destdir, "index.html") index = open(indexpath, "r").read() index = index.replace("{time}", str(strftime("%a, %d %b %Y %H:%M:%S %Z", localtime()))) index = index.replace("{version}", util.findGitVersion()) with open(os.path.join(self.destdir, "index.html"), "w") as output: output.write(index) if self.skipjs: if self.web_assets_hook: self.web_assets_hook(self) return
def _find_file(filename, mode="rb"): """Searches for the given file and returns an open handle to it. This searches the following locations in this order: * The program dir (same dir as this file) * On Darwin, in /Applications/Minecraft * Inside minecraft.jar, which is looked for at these locations * On Windows, at %APPDATA%/.minecraft/bin/minecraft.jar * On Darwin, at $HOME/Library/Application Support/minecraft/bin/minecraft.jar * at $HOME/.minecraft/bin/minecraft.jar * The current working directory * The program dir / textures """ programdir = util.get_program_path() path = os.path.join(programdir, filename) if os.path.exists(path): return open(path, mode) if sys.platform == "darwin": path = os.path.join("/Applications/Minecraft", filename) if os.path.exists(path): return open(path, mode) # Find minecraft.jar. jarpaths = [] if "APPDATA" in os.environ: jarpaths.append(os.path.join(os.environ["APPDATA"], ".minecraft", "bin", "minecraft.jar")) if "HOME" in os.environ: jarpaths.append( os.path.join(os.environ["HOME"], "Library", "Application Support", "minecraft", "bin", "minecraft.jar") ) jarpaths.append(os.path.join(os.environ["HOME"], ".minecraft", "bin", "minecraft.jar")) jarpaths.append(programdir) jarpaths.append(os.getcwd()) for jarpath in jarpaths: if os.path.exists(jarpath): try: jar = zipfile.ZipFile(jarpath) return jar.open(filename) except (KeyError, IOError): pass path = filename if os.path.exists(path): return open(path, mode) path = os.path.join(programdir, "textures", filename) if os.path.exists(path): return open(path, mode) raise IOError( "Could not find the file {0}. Is Minecraft installed? If so, I couldn't find the minecraft.jar file.".format( filename ) )
def check_c_overviewer(): """Check to make sure c_overviewer works and is up-to-date. Prints out a helpful error and returns 1 if something's wrong, returns 0 otherwise. """ root_dir = util.get_program_path() # make sure the c_overviewer extension is available try: import c_overviewer except ImportError: if os.environ.get("OVERVIEWER_DEBUG_IMPORT") == "1": traceback.print_exc() ## if this is a frozen windows package, the following error messages about ## building the c_overviewer extension are not appropriate if hasattr(sys, "frozen") and platform.system() == 'Windows': print "Something has gone wrong importing the c_overviewer extension. Please" print "make sure the 2008 and 2010 redistributable packages from Microsoft" print "are installed." return 1 ## try to find the build extension ext = os.path.join(root_dir, "overviewer_core", "c_overviewer.%s" % ("pyd" if platform.system() == "Windows" else "so")) if os.path.exists(ext): traceback.print_exc() print "" print "Something has gone wrong importing the c_overviewer extension. Please" print "make sure it is up-to-date (clean and rebuild)" return 1 print "You need to compile the c_overviewer module to run Minecraft Overviewer." print "Run `python setup.py build`, or see the README for details." return 1 # # make sure it's up-to-date # if hasattr(sys, "frozen"): pass # we don't bother with a compat test since it should always be in sync elif "extension_version" in dir(c_overviewer): # check to make sure the binary matches the headers if os.path.exists(os.path.join(root_dir, "overviewer_core", "src", "overviewer.h")): with open(os.path.join(root_dir, "overviewer_core", "src", "overviewer.h")) as f: lines = f.readlines() lines = filter(lambda x: x.startswith("#define OVERVIEWER_EXTENSION_VERSION"), lines) if lines: l = lines[0] if int(l.split()[2].strip()) != c_overviewer.extension_version(): print "Please rebuild your c_overviewer module. It is out of date!" return 1 else: print "Please rebuild your c_overviewer module. It is out of date!" return 1 # all good! return 0
def write_html(self, skipjs=False): """Writes out index.html, marker.js, and region.js""" zoomlevel = self.p imgformat = self.imgformat templatepath = os.path.join(util.get_program_path(), "template.html") html = open(templatepath, 'r').read() html = html.replace( "{maxzoom}", str(zoomlevel)) html = html.replace( "{imgformat}", str(imgformat)) html = html.replace( "{lastUpdated}", strftime("%a, %d %b %Y %H:%M:%S %Z")) with open(os.path.join(self.destdir, "index.html"), 'w') as output: output.write(html) # Write a blank image blank = Image.new("RGBA", (1,1)) tileDir = os.path.join(self.destdir, "tiles") if not os.path.exists(tileDir): os.mkdir(tileDir) blank.save(os.path.join(tileDir, "blank."+self.imgformat)) if skipjs: return # write out the default marker table with open(os.path.join(self.destdir, "markers.js"), 'w') as output: output.write("var markerData=%s" % json.dumps(self.world.POI)) # write out the default (empty, but documented) region table with open(os.path.join(self.destdir, "regions.js"), 'w') as output: output.write('var regionData=[\n') output.write(' // {"color": "#FFAA00", "opacity": 0.5, "closed": true, "path": [\n') output.write(' // {"x": 0, "y": 0, "z": 0},\n') output.write(' // {"x": 0, "y": 10, "z": 0},\n') output.write(' // {"x": 0, "y": 0, "z": 10}\n') output.write(' // ]},\n') output.write('];')
def write_html(self, zoomlevel, imgformat): """Writes out index.html""" templatepath = os.path.join(util.get_program_path(), "template.html") html = open(templatepath, 'r').read() html = html.replace( "{maxzoom}", str(zoomlevel)) html = html.replace( "{imgformat}", str(imgformat)) with open(os.path.join(self.destdir, "index.html"), 'w') as output: output.write(html) with open(os.path.join(self.destdir, "markers.js"), 'w') as output: output.write("var markerData=%s" % json.dumps(self.world.POI)) # Write a blank image blank = Image.new("RGBA", (1,1)) tileDir = os.path.join(self.destdir, "tiles") if not os.path.exists(tileDir): os.mkdir(tileDir) blank.save(os.path.join(tileDir, "blank."+self.imgformat))
sys.exit(1) import os import os.path from configParser import ConfigOptionParser import re import subprocess import multiprocessing import time import logging import util import platform logging.basicConfig(level=logging.INFO, format="%(asctime)s [%(levelname)s] %(message)s") this_dir = util.get_program_path() # make sure the c_overviewer extension is available try: import c_overviewer except ImportError: ## try to find the build extension ext = os.path.join(this_dir, "c_overviewer.%s" % ("pyd" if platform.system() == "Windows" else "so")) if os.path.exists(ext): print "Something has gone wrong importing the c_overviewer extension. Please" print "make sure it is up-to-date (clean and rebuild)" sys.exit(1) print "You need to compile the c_overviewer module to run Minecraft Overviewer." print "Run `python setup.py build`, or see the README for details." sys.exit(1)
def go(self, procs): """Writes out config.js, marker.js, and region.js Copies web assets into the destdir""" zoomlevel = self.p bgcolor = (int(self.bg_color[1:3], 16), int(self.bg_color[3:5], 16), int(self.bg_color[5:7], 16), 0) blank = Image.new("RGBA", (1, 1), bgcolor) # Write a blank image for quadtree in self.quadtrees: tileDir = os.path.join(self.destdir, quadtree.tiledir) if not os.path.exists(tileDir): os.mkdir(tileDir) blank.save(os.path.join(tileDir, "blank." + quadtree.imgformat)) # copy web assets into destdir: global_assets = os.path.join(util.get_program_path(), "overviewer_core", "data", "web_assets") if not os.path.isdir(global_assets): global_assets = os.path.join(util.get_program_path(), "web_assets") mirror_dir(global_assets, self.destdir) # do the same with the local copy, if we have it if self.web_assets_path: mirror_dir(self.web_assets_path, self.destdir) # replace the config js stuff config = codecs.open(os.path.join(self.destdir, 'overviewerConfig.js'), 'r', encoding='UTF-8').read() config = config.replace("{minzoom}", str(0)) config = config.replace("{maxzoom}", str(zoomlevel)) config = config.replace("{zoomlevels}", str(zoomlevel)) config = config.replace("{north_direction}", self.north_direction) config = config.replace("{spawn_coords}", json.dumps(list(self.world.spawn))) #config = config.replace("{bg_color}", self.bg_color) # helper function to get a label for the given rendermode def get_render_mode_label(rendermode): info = get_render_mode_info(rendermode) if 'label' in info: return info['label'] return rendermode.capitalize() # create generated map type data, from given quadtrees maptypedata = map( lambda q: { 'label': get_render_mode_label(q.rendermode), 'shortname': q.rendermode, 'path': q.tiledir, 'bg_color': self.bg_color, 'overlay': 'overlay' in get_render_mode_inheritance( q.rendermode), 'imgformat': q.imgformat }, self.quadtrees) config = config.replace("{maptypedata}", json.dumps(maptypedata)) with codecs.open(os.path.join(self.destdir, "overviewerConfig.js"), 'w', encoding='UTF-8') as output: output.write(config) # Add time and version in index.html indexpath = os.path.join(self.destdir, "index.html") index = codecs.open(indexpath, 'r', encoding='UTF-8').read() index = index.replace( "{title}", "%s Map - Minecraft Overviewer" % self.world.name) index = index.replace( "{time}", strftime("%a, %d %b %Y %H:%M:%S %Z", localtime()).decode(locale.getpreferredencoding())) versionstr = "%s (%s)" % (overviewer_version.VERSION, overviewer_version.HASH[:7]) index = index.replace("{version}", versionstr) with codecs.open(os.path.join(self.destdir, "index.html"), 'w', encoding='UTF-8') as output: output.write(index) if self.skipjs: if self.web_assets_hook: self.web_assets_hook(self) return
def _output_assets(self, tilesets, initial): if not initial: get_data = lambda tileset: tileset.get_persistent_data() else: get_data = lambda tileset: tileset.get_initial_data() # dictionary to hold the overviewerConfig.js settings that we will dumps dump = dict() dump['CONST'] = dict(tileSize=384) dump['CONST']['image'] = { 'defaultMarker': 'signpost.png', 'signMarker': 'signpost_icon.png', 'compass': '******', 'spawnMarker': 'http://google-maps-icons.googlecode.com/files/home.png', 'queryMarker': 'http://google-maps-icons.googlecode.com/files/regroup.png' } dump['CONST']['mapDivId'] = 'mcmap' dump['CONST']['regionStrokeWeight'] = 2 dump['CONST']['UPPERLEFT'] = world.UPPER_LEFT dump['CONST']['UPPERRIGHT'] = world.UPPER_RIGHT dump['CONST']['LOWERLEFT'] = world.LOWER_LEFT dump['CONST']['LOWERRIGHT'] = world.LOWER_RIGHT # based on the tilesets we have, group them by worlds worlds = [] for tileset in tilesets: full_name = get_data(tileset)['world'] if full_name not in worlds: worlds.append(full_name) dump['worlds'] = worlds dump['map'] = dict() dump['map']['debug'] = True dump['map']['cacheTag'] = str(int(time.time())) dump['map']['north_direction'] = 'lower-left' # only temporary dump['map']['center'] = [-314, 67, 94] dump['map']['controls'] = { 'pan': True, 'zoom': True, 'spawn': True, 'compass': True, 'mapType': True, 'overlays': True, 'coordsBox': True, 'searchBox': True } dump['tilesets'] = [] for tileset in tilesets: dump['tilesets'].append(get_data(tileset)) # write a blank image blank = Image.new("RGBA", (1, 1), tileset.options.get('bgcolor')) blank.save( os.path.join(self.outputdir, tileset.options.get('name'), "blank." + tileset.options.get('imgformat'))) # copy web assets into destdir: global_assets = os.path.join(util.get_program_path(), "overviewer_core", "data", "web_assets") if not os.path.isdir(global_assets): global_assets = os.path.join(util.get_program_path(), "web_assets") mirror_dir(global_assets, self.outputdir) # write a dummy baseMarkers.js if none exists if not os.path.exists(os.path.join(self.outputdir, "baseMarkers.js")): with open(os.path.join(self.outputdir, "baseMarkers.js"), "w") as f: f.write("// if you wants signs, please see genPOI.py\n") # create overviewer.js from the source js files js_src = os.path.join(util.get_program_path(), "overviewer_core", "data", "js_src") if not os.path.isdir(js_src): js_src = os.path.join(util.get_program_path(), "js_src") with FileReplacer(os.path.join(self.outputdir, "overviewer.js")) as tmpfile: with open(tmpfile, "w") as fout: # first copy in js_src/overviewer.js with open(os.path.join(js_src, "overviewer.js"), 'r') as f: fout.write(f.read()) # now copy in the rest for js in os.listdir(js_src): if not js.endswith("overviewer.js") and js.endswith(".js"): with open(os.path.join(js_src, js)) as f: fout.write(f.read()) # write out config jsondump = json.dumps(dump, indent=4) with FileReplacer(os.path.join(self.outputdir, "overviewerConfig.js")) as tmpfile: with codecs.open(tmpfile, 'w', encoding='UTF-8') as f: f.write("var overviewerConfig = " + jsondump + ";\n") # Add time and version in index.html indexpath = os.path.join(self.outputdir, "index.html") index = codecs.open(indexpath, 'r', encoding='UTF-8').read() index = index.replace("{title}", "Minecraft Overviewer") index = index.replace( "{time}", time.strftime("%a, %d %b %Y %H:%M:%S %Z", time.localtime()).decode( locale.getpreferredencoding())) versionstr = "%s (%s)" % (util.findGitVersion(), util.findGitHash()[:7]) index = index.replace("{version}", versionstr) with FileReplacer(indexpath) as indexpath: with codecs.open(indexpath, 'w', encoding='UTF-8') as output: output.write(index)
def go(self, procs): """Writes out config.js, marker.js, and region.js Copies web assets into the destdir""" zoomlevel = self.p bgcolor = (int(self.bg_color[1:3], 16), int(self.bg_color[3:5], 16), int(self.bg_color[5:7], 16), 0) blank = Image.new("RGBA", (1, 1), bgcolor) # Write a blank image for quadtree in self.quadtrees: tileDir = os.path.join(self.destdir, quadtree.tiledir) if not os.path.exists(tileDir): os.mkdir(tileDir) blank.save(os.path.join(tileDir, "blank." + quadtree.imgformat)) # copy web assets into destdir: global_assets = os.path.join(util.get_program_path(), "overviewer_core", "data", "web_assets") if not os.path.isdir(global_assets): global_assets = os.path.join(util.get_program_path(), "web_assets") mirror_dir(global_assets, self.destdir) # do the same with the local copy, if we have it if self.web_assets_path: mirror_dir(self.web_assets_path, self.destdir) # replace the config js stuff config = codecs.open(os.path.join(self.destdir, "overviewerConfig.js"), "r", encoding="UTF-8").read() config = config.replace("{minzoom}", str(0)) config = config.replace("{maxzoom}", str(zoomlevel)) config = config.replace("{zoomlevels}", str(zoomlevel)) config = config.replace("{north_direction}", self.north_direction) config = config.replace("{spawn_coords}", json.dumps(list(self.world.spawn))) config = config.replace("{cache_tag}", str(int(time()))) # config = config.replace("{bg_color}", self.bg_color) # helper function to get a label for the given rendermode def get_render_mode_label(rendermode): info = get_render_mode_info(rendermode) if "label" in info: return info["label"] return rendermode.capitalize() # create generated map type data, from given quadtrees maptypedata = map( lambda q: { "label": get_render_mode_label(q.rendermode), "shortname": q.rendermode, "path": q.tiledir, "bg_color": self.bg_color, "overlay": "overlay" in get_render_mode_inheritance(q.rendermode), "imgformat": q.imgformat, }, self.quadtrees, ) config = config.replace("{maptypedata}", json.dumps(maptypedata)) with codecs.open(os.path.join(self.destdir, "overviewerConfig.js"), "w", encoding="UTF-8") as output: output.write(config) # Add time and version in index.html indexpath = os.path.join(self.destdir, "index.html") index = codecs.open(indexpath, "r", encoding="UTF-8").read() index = index.replace("{title}", "%s Map - Minecraft Overviewer" % self.world.name) index = index.replace( "{time}", strftime("%a, %d %b %Y %H:%M:%S %Z", localtime()).decode(locale.getpreferredencoding()) ) versionstr = "%s (%s)" % (overviewer_version.VERSION, overviewer_version.HASH[:7]) index = index.replace("{version}", versionstr) with codecs.open(os.path.join(self.destdir, "index.html"), "w", encoding="UTF-8") as output: output.write(index) if self.skipjs: if self.web_assets_hook: self.web_assets_hook(self) return
def _output_assets(self, tilesets, initial): if not initial: get_data = lambda tileset: tileset.get_persistent_data() else: get_data = lambda tileset: tileset.get_initial_data() # dictionary to hold the overviewerConfig.js settings that we will dumps dump = dict() dump['CONST'] = dict(tileSize=384) dump['CONST']['image'] = { 'defaultMarker': 'signpost.png', 'signMarker': 'signpost_icon.png', 'compass': '******', 'spawnMarker': 'http://google-maps-icons.googlecode.com/files/home.png', 'queryMarker': 'http://google-maps-icons.googlecode.com/files/regroup.png' } dump['CONST']['mapDivId'] = 'mcmap' dump['CONST']['regionStrokeWeight'] = 2 dump['CONST']['UPPERLEFT'] = world.UPPER_LEFT; dump['CONST']['UPPERRIGHT'] = world.UPPER_RIGHT; dump['CONST']['LOWERLEFT'] = world.LOWER_LEFT; dump['CONST']['LOWERRIGHT'] = world.LOWER_RIGHT; # based on the tilesets we have, group them by worlds worlds = [] for tileset in tilesets: full_name = get_data(tileset)['world'] if full_name not in worlds: worlds.append(full_name) dump['worlds'] = worlds dump['map'] = dict() dump['map']['debug'] = True dump['map']['cacheTag'] = str(int(time.time())) dump['map']['north_direction'] = 'lower-left' # only temporary dump['map']['center'] = [-314, 67, 94] dump['map']['controls'] = { 'pan': True, 'zoom': True, 'spawn': True, 'compass': True, 'mapType': True, 'overlays': True, 'coordsBox': True, 'searchBox': True } dump['tilesets'] = [] for tileset in tilesets: dump['tilesets'].append(get_data(tileset)) # write a blank image blank = Image.new("RGBA", (1,1), tileset.options.get('bgcolor')) blank.save(os.path.join(self.outputdir, tileset.options.get('name'), "blank." + tileset.options.get('imgformat'))) # copy web assets into destdir: global_assets = os.path.join(util.get_program_path(), "overviewer_core", "data", "web_assets") if not os.path.isdir(global_assets): global_assets = os.path.join(util.get_program_path(), "web_assets") mirror_dir(global_assets, self.outputdir) # write a dummy baseMarkers.js if none exists if not os.path.exists(os.path.join(self.outputdir, "baseMarkers.js")): with open(os.path.join(self.outputdir, "baseMarkers.js"), "w") as f: f.write("// if you wants signs, please see genPOI.py\n"); # create overviewer.js from the source js files js_src = os.path.join(util.get_program_path(), "overviewer_core", "data", "js_src") if not os.path.isdir(js_src): js_src = os.path.join(util.get_program_path(), "js_src") with FileReplacer(os.path.join(self.outputdir, "overviewer.js")) as tmpfile: with open(tmpfile, "w") as fout: # first copy in js_src/overviewer.js with open(os.path.join(js_src, "overviewer.js"), 'r') as f: fout.write(f.read()) # now copy in the rest for js in os.listdir(js_src): if not js.endswith("overviewer.js") and js.endswith(".js"): with open(os.path.join(js_src,js)) as f: fout.write(f.read()) # write out config jsondump = json.dumps(dump, indent=4) with FileReplacer(os.path.join(self.outputdir, "overviewerConfig.js")) as tmpfile: with codecs.open(tmpfile, 'w', encoding='UTF-8') as f: f.write("var overviewerConfig = " + jsondump + ";\n") # Add time and version in index.html indexpath = os.path.join(self.outputdir, "index.html") index = codecs.open(indexpath, 'r', encoding='UTF-8').read() index = index.replace("{title}", "Minecraft Overviewer") index = index.replace("{time}", time.strftime("%a, %d %b %Y %H:%M:%S %Z", time.localtime()).decode(locale.getpreferredencoding())) versionstr = "%s (%s)" % (util.findGitVersion(), util.findGitHash()[:7]) index = index.replace("{version}", versionstr) with FileReplacer(indexpath) as indexpath: with codecs.open(indexpath, 'w', encoding='UTF-8') as output: output.write(index)
def _find_file(filename, mode="rb"): """Searches for the given file and returns an open handle to it. This searches the following locations in this order: * The program dir (same dir as this file) * On Darwin, in /Applications/Minecraft * Inside minecraft.jar, which is looked for at these locations * On Windows, at %APPDATA%/.minecraft/bin/minecraft.jar * On Darwin, at $HOME/Library/Application Support/minecraft/bin/minecraft.jar * at $HOME/.minecraft/bin/minecraft.jar * The current working directory * The program dir / textures """ programdir = util.get_program_path() path = os.path.join(programdir, filename) if os.path.exists(path): return open(path, mode) if sys.platform == "darwin": path = os.path.join("/Applications/Minecraft", filename) if os.path.exists(path): return open(path, mode) # Find minecraft.jar. jarpaths = [] if "APPDATA" in os.environ: jarpaths.append( os.path.join(os.environ['APPDATA'], ".minecraft", "bin", "minecraft.jar")) if "HOME" in os.environ: jarpaths.append( os.path.join(os.environ['HOME'], "Library", "Application Support", "minecraft", "bin", "minecraft.jar")) jarpaths.append( os.path.join(os.environ['HOME'], ".minecraft", "bin", "minecraft.jar")) jarpaths.append(programdir) jarpaths.append(os.getcwd()) for jarpath in jarpaths: if os.path.exists(jarpath): try: jar = zipfile.ZipFile(jarpath) return jar.open(filename) except (KeyError, IOError): pass path = filename if os.path.exists(path): return open(path, mode) path = os.path.join(programdir, "textures", filename) if os.path.exists(path): return open(path, mode) raise IOError( "Could not find the file {0}. Is Minecraft installed? If so, I couldn't find the minecraft.jar file." .format(filename))
def write_html(self, worlddir=None, onlyindex=False): """Writes out index.html, and optionally maprefresh.js and regions.js""" zoomlevel = self.p imgformat = self.imgformat indexpath = os.path.join(util.get_program_path(), "template.html") ## read spawn info from level.dat data = nbt.load(os.path.join(worlddir, "level.dat"))[1] spawnX = data['Data']['SpawnX'] spawnY = data['Data']['SpawnY'] spawnZ = data['Data']['SpawnZ'] html = open(indexpath, 'r').read() html = html.replace("{defaultzoom}", str(zoomlevel / 2 + 1)) html = html.replace("{markerzoom}", str(zoomlevel / 2 + 3)) html = html.replace("{maxzoom}", str(zoomlevel)) html = html.replace("{imgformat}", str(imgformat)) html = html.replace("{mapcenter}", str(str(spawnX) + "," + str(spawnY) + "," + str(spawnZ))) html = html.replace("{statustext}", str("Last Updated: "+strftime("%a, %d %b %Y %H:%M:%S %Z"))) with open(os.path.join(self.destdir, "index.html"), 'w') as output: output.write(html) if onlyindex: return # Write a blank image blank = Image.new("RGBA", (1,1)) tileDir = os.path.join(self.destdir, "tiles") if not os.path.exists(tileDir): os.mkdir(tileDir) tileDir = os.path.join(tileDir, "unlit") #!TODO!add logic for allbranches if not os.path.exists(tileDir): os.mkdir(tileDir) blank.save(os.path.join(tileDir, "blank."+self.imgformat)) # copy web assets into destdir: for root, dirs, files in os.walk(os.path.join(util.get_program_path(), "web_assets")): for f in files: shutil.copy(os.path.join(root, f), self.destdir) # since we will only discover PointsOfInterest in chunks that need to be # [re]rendered, POIs like signs in unchanged chunks will not be listed # in self.world.POI. To make sure we don't remove these from markers.js # we need to merge self.world.POI with the persistant data in world.PersistentData self.world.POI += filter(lambda x: x['type'] != 'spawn', self.world.persistentData['POI']) # write out the default marker table with open(os.path.join(self.destdir, "markers.js"), 'w') as output: output.write("var markerData=%s" % json.dumps(self.world.POI)) # save persistent data self.world.persistentData['POI'] = self.world.POI with open(self.world.pickleFile,"wb") as f: cPickle.dump(self.world.persistentData,f) # write out the default (empty, but documented) region table with open(os.path.join(self.destdir, "regions.js"), 'w') as output: output.write('var regionData=[\n') output.write(' // {"color": "#FFAA00", "opacity": 0.5, "closed": true, "path": [\n') output.write(' // {"x": 0, "y": 0, "z": 0},\n') output.write(' // {"x": 0, "y": 10, "z": 0},\n') output.write(' // {"x": 0, "y": 0, "z": 10}\n') output.write(' // ]},\n') output.write('];')
def write_html(self, skipjs=False): """Writes out config.js, marker.js, and region.js Copies web assets into the destdir""" zoomlevel = self.p imgformat = self.imgformat configpath = os.path.join(util.get_program_path(), "config.js") config = open(configpath, 'r').read() config = config.replace("{maxzoom}", str(zoomlevel)) config = config.replace("{imgformat}", str(imgformat)) with open(os.path.join(self.destdir, "config.js"), 'w') as output: output.write(config) # Write a blank image blank = Image.new("RGBA", (1, 1)) tileDir = os.path.join(self.destdir, "tiles") if not os.path.exists(tileDir): os.mkdir(tileDir) blank.save(os.path.join(tileDir, "blank." + self.imgformat)) # copy web assets into destdir: mirror_dir(os.path.join(util.get_program_path(), "web_assets"), self.destdir) # Add time in index.html indexpath = os.path.join(self.destdir, "index.html") index = open(indexpath, 'r').read() index = index.replace( "{time}", str(strftime("%a, %d %b %Y %H:%M:%S +0000", gmtime()))) with open(os.path.join(self.destdir, "index.html"), 'w') as output: output.write(index) if skipjs: return # since we will only discover PointsOfInterest in chunks that need to be # [re]rendered, POIs like signs in unchanged chunks will not be listed # in self.world.POI. To make sure we don't remove these from markers.js # we need to merge self.world.POI with the persistant data in world.PersistentData self.world.POI += filter(lambda x: x['type'] != 'spawn', self.world.persistentData['POI']) # write out the default marker table with open(os.path.join(self.destdir, "markers.js"), 'w') as output: output.write("var markerData=%s" % json.dumps(self.world.POI)) # save persistent data self.world.persistentData['POI'] = self.world.POI with open(self.world.pickleFile, "wb") as f: cPickle.dump(self.world.persistentData, f) # write out the default (empty, but documented) region table with open(os.path.join(self.destdir, "regions.js"), 'w') as output: output.write('var regionData=[\n') output.write( ' // {"color": "#FFAA00", "opacity": 0.5, "closed": true, "path": [\n' ) output.write(' // {"x": 0, "y": 0, "z": 0},\n') output.write(' // {"x": 0, "y": 10, "z": 0},\n') output.write(' // {"x": 0, "y": 0, "z": 10}\n') output.write(' // ]},\n') output.write('];')
def go(self, procs): """Writes out config.js, marker.js, and region.js Copies web assets into the destdir""" zoomlevel = self.p bgcolor = (int(self.bg_color[1:3],16), int(self.bg_color[3:5],16), int(self.bg_color[5:7],16), 0) blank = Image.new("RGBA", (1,1), bgcolor) # Write a blank image for quadtree in self.quadtrees: tileDir = os.path.join(self.destdir, quadtree.tiledir) if not os.path.exists(tileDir): os.mkdir(tileDir) blank.save(os.path.join(tileDir, "blank."+quadtree.imgformat)) # copy web assets into destdir: global_assets = os.path.join(util.get_program_path(), "overviewer_core", "data", "web_assets") if not os.path.isdir(global_assets): global_assets = os.path.join(util.get_program_path(), "web_assets") mirror_dir(global_assets, self.destdir) # do the same with the local copy, if we have it if self.web_assets_path: mirror_dir(self.web_assets_path, self.destdir) # replace the config js stuff config = open(os.path.join(self.destdir, 'overviewerConfig.js'), 'r').read() config = config.replace( "{minzoom}", str(0)) config = config.replace( "{maxzoom}", str(zoomlevel)) config = config.replace( "{zoomlevels}", str(zoomlevel)) config = config.replace( "{north_direction}", self.north_direction) config = config.replace("{spawn_coords}", json.dumps(list(self.world.spawn))) #config = config.replace("{bg_color}", self.bg_color) # create generated map type data, from given quadtrees maptypedata = map(lambda q: {'label' : q.rendermode.capitalize(), 'path' : q.tiledir, 'bg_color': self.bg_color, 'overlay' : 'overlay' in get_render_mode_inheritance(q.rendermode), 'imgformat' : q.imgformat}, self.quadtrees) config = config.replace("{maptypedata}", json.dumps(maptypedata)) with open(os.path.join(self.destdir, "overviewerConfig.js"), 'w') as output: output.write(config) # Add time and version in index.html indexpath = os.path.join(self.destdir, "index.html") index = open(indexpath, 'r').read() index = index.replace("{time}", str(strftime("%a, %d %b %Y %H:%M:%S %Z", localtime()))) versionstr = "%s (%s)" % (overviewer_version.VERSION, overviewer_version.HASH[:7]) index = index.replace("{version}", versionstr) with open(os.path.join(self.destdir, "index.html"), 'w') as output: output.write(index) if self.skipjs: if self.web_assets_hook: self.web_assets_hook(self) return
def check_c_overviewer(): """Check to make sure c_overviewer works and is up-to-date. Prints out a helpful error and returns 1 if something's wrong, returns 0 otherwise. """ root_dir = util.get_program_path() # make sure the c_overviewer extension is available try: import c_overviewer except ImportError: ## if this is a frozen windows package, the following error messages about ## building the c_overviewer extension are not appropriate if hasattr(sys, "frozen") and platform.system() == 'Windows': print "Something has gone wrong importing the c_overviewer extension. Please" print "make sure the 2008 and 2010 redistributable packages from Microsoft" print "are installed." return 1 ## try to find the build extension ext = os.path.join( root_dir, "overviewer_core", "c_overviewer.%s" % ("pyd" if platform.system() == "Windows" else "so")) if os.path.exists(ext): traceback.print_exc() print "" print "Something has gone wrong importing the c_overviewer extension. Please" print "make sure it is up-to-date (clean and rebuild)" return 1 print "You need to compile the c_overviewer module to run Minecraft Overviewer." print "Run `python setup.py build`, or see the README for details." return 1 # # make sure it's up-to-date # if hasattr(sys, "frozen"): pass # we don't bother with a compat test since it should always be in sync elif "extension_version" in dir(c_overviewer): # check to make sure the binary matches the headers if os.path.exists( os.path.join(root_dir, "overviewer_core", "src", "overviewer.h")): with open( os.path.join(root_dir, "overviewer_core", "src", "overviewer.h")) as f: lines = f.readlines() lines = filter( lambda x: x.startswith( "#define OVERVIEWER_EXTENSION_VERSION"), lines) if lines: l = lines[0] if int(l.split() [2].strip()) != c_overviewer.extension_version(): print "Please rebuild your c_overviewer module. It is out of date!" return 1 else: print "Please rebuild your c_overviewer module. It is out of date!" return 1 # all good! return 0