diff --git a/.gitignore b/.gitignore index 5871f26..1918894 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,8 @@ *.pyc -build +MANIFEST +build/ +dist/ +Minecraft_Overviewer.egg-info terrain.png cachedir* @@ -14,10 +17,13 @@ ImPlatform.h Imaging.h # various forms of compiled c_overviewer extensions -c_overviewer.so -c_overviewer.pyd -c_overviewer_d.pyd -c_overviewer.dylib +overviewer_core/c_overviewer.so +overviewer_core/c_overviewer.pyd +overviewer_core/c_overviewer_d.pyd +overviewer_core/c_overviewer.dylib + +# generated version file +overviewer_core/overviewer_version.py # Mac OS X noise .DS_Store diff --git a/CONTRIBUTORS.rst b/CONTRIBUTORS.rst index ae100b4..30c5ffe 100644 --- a/CONTRIBUTORS.rst +++ b/CONTRIBUTORS.rst @@ -4,7 +4,8 @@ Contributors This file contains a list of every person who has contributed code to Overviewer. It was created from the git commit log, and should include -everyone, but we may have missed a few. +everyone, but we may have missed a few and it is manually updated +now. If you feel like you've been left out, feel free to tell us! Not currently included (but hopefully soon) are countless testers and bug reporters that helped fixed the many bugs that have popped up in the course of @@ -40,14 +41,17 @@ feature. * arrai * Kyle Brantley + * Eric Carr * cbarber * Alex Cline + * Andrew Clunis * CounterPillow * Stephen Fluin * Benjamin Herr * Ryan Hitchman * Jenny * Michael Jensen + * Maciej MaƂecki * Ryan McCue * Morlok8k * Gregory Short diff --git a/MANIFEST.in b/MANIFEST.in new file mode 100644 index 0000000..fe84bcb --- /dev/null +++ b/MANIFEST.in @@ -0,0 +1,9 @@ +include COPYING.txt +include README.rst +include CONTRIBUTORS.rst +include overviewer.py +include sample.settings.py +recursive-include contrib/ *.py +recursive-include overviewer_core/*.py +recursive-include overviewer_core/src/ *.c *.h +recursive-include overviewer_core/data/ *.png *.js index.html style.css diff --git a/README.rst b/README.rst index 11f9f10..942e4cb 100644 --- a/README.rst +++ b/README.rst @@ -169,6 +169,10 @@ Options *Note*: Currently only the overviewer.dat file is deleted when you run with this option +--forcerender + Force re-rendering the entire map (or the given regionlist). This + is an easier way to completely re-render without deleting the map. + --regionlist=regionlist Use this option to specify manually a list of regions to consider for updating. Without this option, every chunk in every region is checked for diff --git a/blockcounter.py b/contrib/blockcounter.py similarity index 100% rename from blockcounter.py rename to contrib/blockcounter.py diff --git a/overviewer.py b/overviewer.py index c296c10..022e838 100755 --- a/overviewer.py +++ b/overviewer.py @@ -22,14 +22,13 @@ if not (sys.version_info[0] == 2 and sys.version_info[1] >= 6): import os import os.path -from configParser import ConfigOptionParser import re import subprocess import multiprocessing import time import logging -import util import platform +from overviewer_core import util logging.basicConfig(level=logging.INFO,format="%(asctime)s [%(levelname)s] %(message)s") @@ -37,10 +36,19 @@ this_dir = util.get_program_path() # make sure the c_overviewer extension is available try: - import c_overviewer + from overviewer_core 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"): + 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." + sys.exit(1) + + ## try to find the build extension - ext = os.path.join(this_dir, "c_overviewer.%s" % ("pyd" if platform.system() == "Windows" else "so")) + ext = os.path.join(this_dir, "overviewer_core", "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)" @@ -48,14 +56,17 @@ except ImportError: 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." + import traceback + traceback.print_exc() sys.exit(1) + 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(this_dir, "src", "overviewer.h")): - with open(os.path.join(this_dir, "src", "overviewer.h")) as f: + if os.path.exists(os.path.join(this_dir, "overviewer_core", "src", "overviewer.h")): + with open(os.path.join(this_dir, "overviewer_core", "src", "overviewer.h")) as f: lines = f.readlines() lines = filter(lambda x: x.startswith("#define OVERVIEWER_EXTENSION_VERSION"), lines) if lines: @@ -67,12 +78,10 @@ else: print "Please rebuild your c_overviewer module. It is out of date!" sys.exit(1) +from overviewer_core.configParser import ConfigOptionParser +from overviewer_core import optimizeimages, world, quadtree +from overviewer_core import googlemap, rendernode -import optimizeimages -import world -import quadtree -import googlemap -import rendernode helptext = """ %prog [OPTIONS] @@ -117,14 +126,14 @@ def main(): if options.version: - print "Minecraft-Overviewer" - print "Git version: %s" % util.findGitVersion() try: - import overviewer_version - if hasattr(sys, "frozen"): - print "py2exe version build on %s" % overviewer_version.BUILD_DATE - print "Build machine: %s %s" % (overviewer_version.BUILD_PLATFORM, overviewer_version.BUILD_OS) + import overviewer_core.overviewer_version as overviewer_version + print "Minecraft-Overviewer %s" % overviewer_version.VERSION + print "Git commit: %s" % overviewer_version.HASH + print "built on %s" % overviewer_version.BUILD_DATE + print "Build machine: %s %s" % (overviewer_version.BUILD_PLATFORM, overviewer_version.BUILD_OS) except: + print "version info not found" pass sys.exit(0) diff --git a/overviewer_core/__init__.py b/overviewer_core/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/chunk.py b/overviewer_core/chunk.py similarity index 100% rename from chunk.py rename to overviewer_core/chunk.py diff --git a/composite.py b/overviewer_core/composite.py similarity index 100% rename from composite.py rename to overviewer_core/composite.py diff --git a/configParser.py b/overviewer_core/configParser.py similarity index 97% rename from configParser.py rename to overviewer_core/configParser.py index 4213984..c6991ee 100644 --- a/configParser.py +++ b/overviewer_core/configParser.py @@ -81,6 +81,10 @@ class ConfigOptionParser(object): if os.path.exists(self.configFile): execfile(self.configFile, g, l) + elif options.config_file: + # file does not exist, but *was* specified on the command line + logging.error("Could not open %s." % self.configFile) + sys.exit(1) except NameError, ex: import traceback traceback.print_exc() diff --git a/textures/fire.png b/overviewer_core/data/textures/fire.png similarity index 100% rename from textures/fire.png rename to overviewer_core/data/textures/fire.png diff --git a/textures/lava.png b/overviewer_core/data/textures/lava.png similarity index 100% rename from textures/lava.png rename to overviewer_core/data/textures/lava.png diff --git a/textures/portal.png b/overviewer_core/data/textures/portal.png similarity index 100% rename from textures/portal.png rename to overviewer_core/data/textures/portal.png diff --git a/textures/water.png b/overviewer_core/data/textures/water.png similarity index 100% rename from textures/water.png rename to overviewer_core/data/textures/water.png diff --git a/web_assets/compass.png b/overviewer_core/data/web_assets/compass.png similarity index 100% rename from web_assets/compass.png rename to overviewer_core/data/web_assets/compass.png diff --git a/web_assets/control-bg-active.png b/overviewer_core/data/web_assets/control-bg-active.png similarity index 100% rename from web_assets/control-bg-active.png rename to overviewer_core/data/web_assets/control-bg-active.png diff --git a/web_assets/control-bg.png b/overviewer_core/data/web_assets/control-bg.png similarity index 100% rename from web_assets/control-bg.png rename to overviewer_core/data/web_assets/control-bg.png diff --git a/web_assets/index.html b/overviewer_core/data/web_assets/index.html similarity index 100% rename from web_assets/index.html rename to overviewer_core/data/web_assets/index.html diff --git a/web_assets/overviewer.css b/overviewer_core/data/web_assets/overviewer.css similarity index 78% rename from web_assets/overviewer.css rename to overviewer_core/data/web_assets/overviewer.css index f4bdd98..d875cdb 100644 --- a/web_assets/overviewer.css +++ b/overviewer_core/data/web_assets/overviewer.css @@ -100,3 +100,34 @@ body { background-color: #fff; /* fallback */ background-color: rgba(255,255,255,0.8); } + +#searchControl { + padding: 5px; + height: 20px; + font-family: Arial, sans-serif; +} + +#searchControl > input { + border: 2px solid #000; + font-size: 12pt; + width: 20em; + background-colour: #fff; +} + +div#searchDropDown { + border: 1px solid #000; + width: 17em; + font-size: 14pt; + background-color: #fff; + display: none; +} + +div.searchResultItem { + overflow: hidden; + text-overflow: ellipsis; +} + +div.searchResultItem img { + width: 24px; + height: 24px; +} diff --git a/web_assets/overviewer.js b/overviewer_core/data/web_assets/overviewer.js similarity index 92% rename from web_assets/overviewer.js rename to overviewer_core/data/web_assets/overviewer.js index ea87a19..a97341c 100644 --- a/web_assets/overviewer.js +++ b/overviewer_core/data/web_assets/overviewer.js @@ -58,6 +58,7 @@ var overviewer = { overviewer.util.initializeMarkers(); overviewer.util.initializeRegions(); overviewer.util.createMapControls(); + overviewer.util.createSearchBox(); }, /** * This adds some methods to these classes because Javascript is stupid @@ -96,6 +97,25 @@ var overviewer = { return div; }; }, + /** + * Quote an arbitrary string for use in a regex matcher. + * WTB parametized regexes, JavaScript... + * + * From http://kevin.vanzonneveld.net + * original by: booeyOH + * improved by: Ates Goral (http://magnetiq.com) + * improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) + * bugfixed by: Onno Marsman + * example 1: preg_quote("$40"); + * returns 1: '\$40' + * example 2: preg_quote("*RRRING* Hello?"); + * returns 2: '\*RRRING\* Hello\?' + * example 3: preg_quote("\\.+*?[^]$(){}=!<>|:"); + * returns 3: '\\\.\+\*\?\[\^\]\$\(\)\{\}\=\!\<\>\|\:' + */ + "pregQuote": function(str) { + return (str+'').replace(/([\\\.\+\*\?\[\^\]\$\(\)\{\}\=\!\<\>\|\:])/g, "\\$1"); + }, /** * Setup the varous mapTypes before we actually create the map. This used * to be a bunch of crap down at the bottom of functions.js @@ -317,6 +337,7 @@ var overviewer = { 'icon': iconURL, 'visible': false }); + item.marker = marker; overviewer.util.debug(label); overviewer.collections.markers[label].push(marker); if (item.type == 'sign') { @@ -339,6 +360,7 @@ var overviewer = { 'icon': iconURL, 'visible': false }); + item.marker = marker; if (overviewer.collections.markers['__others__']) { overviewer.collections.markers['__others__'].push(marker); } else { @@ -758,6 +780,61 @@ var overviewer = { itemDiv.appendChild(textNode); } }, + /** + * Create search box and dropdown in the top right google maps area. + */ + 'createSearchBox': function() { + var searchControl = document.createElement("div"); + searchControl.id = "searchControl"; + + var searchInput = document.createElement("input"); + searchInput.type = "text"; + + searchControl.appendChild(searchInput); + + var searchDropDown = document.createElement("div"); + searchDropDown.id = "searchDropDown"; + searchControl.appendChild(searchDropDown); + + $(searchInput).keyup(function(e) { + var newline_stripper = new RegExp("[\\r\\n]", "g") + if(searchInput.value.length !== 0) { + $(searchDropDown).fadeIn(); + + $(searchDropDown).empty(); + + overviewer.collections.markerDatas.forEach(function(marker_list) { + marker_list.forEach(function(sign) { + var regex = new RegExp(overviewer.util.pregQuote(searchInput.value), "mi"); + if(sign.msg.match(regex)) { + if(sign.marker !== undefined && sign.marker.getVisible()) { + var t = document.createElement("div"); + t.className = "searchResultItem"; + var i = document.createElement("img"); + i.src = sign.marker.getIcon(); + t.appendChild(i); + var s = document.createElement("span"); + + $(s).text(sign.msg.replace(newline_stripper, "")); + t.appendChild(s); + searchDropDown.appendChild(t); + $(t).click(function(e) { + $(searchDropDown).fadeOut(); + overviewer.map.setZoom(7); + overviewer.map.setCenter(sign.marker.getPosition()); + }); + + } + } + }); + }); + } else { + $(searchDropDown).fadeOut(); + } + }); + + overviewer.map.controls[google.maps.ControlPosition.TOP_RIGHT].push(searchControl); + }, /** * Create the pop-up infobox for when you click on a region, this can't * be done in-line because of stupid Javascript scoping problems with diff --git a/web_assets/overviewerConfig.js b/overviewer_core/data/web_assets/overviewerConfig.js similarity index 100% rename from web_assets/overviewerConfig.js rename to overviewer_core/data/web_assets/overviewerConfig.js diff --git a/web_assets/signpost-shadow.png b/overviewer_core/data/web_assets/signpost-shadow.png similarity index 100% rename from web_assets/signpost-shadow.png rename to overviewer_core/data/web_assets/signpost-shadow.png diff --git a/web_assets/signpost.png b/overviewer_core/data/web_assets/signpost.png similarity index 100% rename from web_assets/signpost.png rename to overviewer_core/data/web_assets/signpost.png diff --git a/web_assets/signpost_icon.png b/overviewer_core/data/web_assets/signpost_icon.png similarity index 100% rename from web_assets/signpost_icon.png rename to overviewer_core/data/web_assets/signpost_icon.png diff --git a/googlemap.py b/overviewer_core/googlemap.py similarity index 93% rename from googlemap.py rename to overviewer_core/googlemap.py index 48fede1..7d4dc7e 100644 --- a/googlemap.py +++ b/overviewer_core/googlemap.py @@ -24,6 +24,7 @@ import json import util from c_overviewer import get_render_mode_inheritance +import overviewer_version """ This module has routines related to generating a Google Maps-based @@ -98,7 +99,11 @@ class MapGen(object): 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) + 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) @@ -131,9 +136,9 @@ class MapGen(object): 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()) + 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) diff --git a/nbt.py b/overviewer_core/nbt.py similarity index 100% rename from nbt.py rename to overviewer_core/nbt.py diff --git a/optimizeimages.py b/overviewer_core/optimizeimages.py similarity index 100% rename from optimizeimages.py rename to overviewer_core/optimizeimages.py diff --git a/quadtree.py b/overviewer_core/quadtree.py similarity index 100% rename from quadtree.py rename to overviewer_core/quadtree.py diff --git a/rendernode.py b/overviewer_core/rendernode.py similarity index 100% rename from rendernode.py rename to overviewer_core/rendernode.py diff --git a/src/Draw.c b/overviewer_core/src/Draw.c similarity index 100% rename from src/Draw.c rename to overviewer_core/src/Draw.c diff --git a/src/composite.c b/overviewer_core/src/composite.c similarity index 100% rename from src/composite.c rename to overviewer_core/src/composite.c diff --git a/src/endian.c b/overviewer_core/src/endian.c similarity index 100% rename from src/endian.c rename to overviewer_core/src/endian.c diff --git a/src/iterate.c b/overviewer_core/src/iterate.c similarity index 99% rename from src/iterate.c rename to overviewer_core/src/iterate.c index 208e147..8adbf57 100644 --- a/src/iterate.c +++ b/overviewer_core/src/iterate.c @@ -32,13 +32,13 @@ PyObject *init_chunk_render(PyObject *self, PyObject *args) { Py_RETURN_NONE; } - textures = PyImport_ImportModule("textures"); + textures = PyImport_ImportModule("overviewer_core.textures"); /* ensure none of these pointers are NULL */ if ((!textures)) { return NULL; } - chunk_mod = PyImport_ImportModule("chunk"); + chunk_mod = PyImport_ImportModule("overviewer_core.chunk"); /* ensure none of these pointers are NULL */ if ((!chunk_mod)) { return NULL; diff --git a/src/main.c b/overviewer_core/src/main.c similarity index 100% rename from src/main.c rename to overviewer_core/src/main.c diff --git a/src/overviewer.h b/overviewer_core/src/overviewer.h similarity index 100% rename from src/overviewer.h rename to overviewer_core/src/overviewer.h diff --git a/src/rendermode-cave.c b/overviewer_core/src/rendermode-cave.c similarity index 100% rename from src/rendermode-cave.c rename to overviewer_core/src/rendermode-cave.c diff --git a/src/rendermode-lighting.c b/overviewer_core/src/rendermode-lighting.c similarity index 97% rename from src/rendermode-lighting.c rename to overviewer_core/src/rendermode-lighting.c index 2741cf0..fb55441 100644 --- a/src/rendermode-lighting.c +++ b/overviewer_core/src/rendermode-lighting.c @@ -88,6 +88,14 @@ estimate_blocklevel(RenderModeLighting *self, RenderState *state, for (dx = -1; dx <= 1; dx += 2) { for (dy = -1; dy <= 1; dy += 2) { for (dz = -1; dz <= 1; dz += 2) { + + /* skip if block is out of range */ + if (x+dx < 0 || x+dx >= 16 || + y+dy < 0 || y+dy >= 16 || + z+dz < 0 || z+dz >= 128) { + continue; + } + coeff = estimate_blocklevel(self, state, x+dx, y+dy, z+dz, &auth); local_block = getArrayByte3D(blocks, x+dx, y+dy, z+dz); /* only add if the block is transparent, this seems to look better than diff --git a/src/rendermode-mineral.c b/overviewer_core/src/rendermode-mineral.c similarity index 100% rename from src/rendermode-mineral.c rename to overviewer_core/src/rendermode-mineral.c diff --git a/src/rendermode-night.c b/overviewer_core/src/rendermode-night.c similarity index 100% rename from src/rendermode-night.c rename to overviewer_core/src/rendermode-night.c diff --git a/src/rendermode-normal.c b/overviewer_core/src/rendermode-normal.c similarity index 100% rename from src/rendermode-normal.c rename to overviewer_core/src/rendermode-normal.c diff --git a/src/rendermode-overlay.c b/overviewer_core/src/rendermode-overlay.c similarity index 100% rename from src/rendermode-overlay.c rename to overviewer_core/src/rendermode-overlay.c diff --git a/src/rendermode-spawn.c b/overviewer_core/src/rendermode-spawn.c similarity index 100% rename from src/rendermode-spawn.c rename to overviewer_core/src/rendermode-spawn.c diff --git a/src/rendermodes.c b/overviewer_core/src/rendermodes.c similarity index 100% rename from src/rendermodes.c rename to overviewer_core/src/rendermodes.c diff --git a/src/rendermodes.h b/overviewer_core/src/rendermodes.h similarity index 100% rename from src/rendermodes.h rename to overviewer_core/src/rendermodes.h diff --git a/textures.py b/overviewer_core/textures.py similarity index 99% rename from textures.py rename to overviewer_core/textures.py index 5e2db3b..f1da1b2 100644 --- a/textures.py +++ b/overviewer_core/textures.py @@ -14,6 +14,7 @@ # with the Overviewer. If not, see . import sys +import imp import os import os.path import zipfile @@ -32,8 +33,8 @@ def _find_file(filename, mode="rb"): This searches the following locations in this order: * the textures_path given in the config file (if present) - * The program dir (same dir as this file) - * The program dir / textures + * The program dir (same dir as overviewer.py) + * The overviewer_core textures dir * On Darwin, in /Applications/Minecraft * Inside minecraft.jar, which is looked for at these locations @@ -53,9 +54,14 @@ def _find_file(filename, mode="rb"): if os.path.exists(path): return open(path, mode) - path = os.path.join(programdir, "textures", filename) + path = os.path.join(programdir, "overviewer_core", "data", "textures", filename) if os.path.exists(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 = os.path.join(programdir, "textures", filename) + if os.path.exists(path): + return open(path, mode) if sys.platform == "darwin": path = os.path.join("/Applications/Minecraft", filename) diff --git a/util.py b/overviewer_core/util.py similarity index 68% rename from util.py rename to overviewer_core/util.py index 7a0323d..2bd15b5 100644 --- a/util.py +++ b/overviewer_core/util.py @@ -21,19 +21,22 @@ import imp import os import os.path import sys +from subprocess import Popen, PIPE def get_program_path(): if hasattr(sys, "frozen") or imp.is_frozen("__main__"): return os.path.dirname(sys.executable) else: try: - return os.path.dirname(__file__) + # normally, we're in ./overviewer_core/util.py + # we want ./ + return os.path.dirname(os.path.dirname(__file__)) except NameError: return os.path.dirname(sys.argv[0]) - -def findGitVersion(): +# does not require git, very likely to work everywhere +def findGitHash(): this_dir = get_program_path() if os.path.exists(os.path.join(this_dir,".git")): with open(os.path.join(this_dir,".git","HEAD")) as f: @@ -46,6 +49,24 @@ def findGitVersion(): else: return data else: + try: + import overviewer_version + return overviewer_version.HASH + except: + return "unknown" + +def findGitVersion(): + try: + p = Popen(['git', 'describe', '--tags'], stdout=PIPE, stderr=PIPE) + p.stderr.close() + line = p.stdout.readlines()[0] + if line.startswith('release-'): + line = line.split('-', 1)[1] + # turn 0.1.2-50-somehash into 0.1.2-50 + # and 0.1.3 into 0.1.3 + line = '-'.join(line.split('-', 2)[:2]) + return line.strip() + except: try: import overviewer_version return overviewer_version.VERSION diff --git a/world.py b/overviewer_core/world.py similarity index 100% rename from world.py rename to overviewer_core/world.py diff --git a/setup.py b/setup.py old mode 100644 new mode 100755 index 08498ce..04d5c42 --- a/setup.py +++ b/setup.py @@ -1,25 +1,78 @@ -from distutils.core import setup, Extension +#!/usr/bin/env python + +from distutils.core import setup +from distutils.extension import Extension from distutils.command.build import build from distutils.command.clean import clean from distutils.command.build_ext import build_ext +from distutils.command.sdist import sdist from distutils.dir_util import remove_tree +from distutils.sysconfig import get_python_inc from distutils import log -import os, os.path +import sys, os, os.path import glob import platform import time +import overviewer_core.util as util try: import py2exe except ImportError: py2exe = None +try: + import py2app + from setuptools.extension import Extension +except ImportError: + py2app = None + # now, setup the keyword arguments for setup -# (because we don't know until runtime if py2exe is available) +# (because we don't know until runtime if py2exe/py2app is available) setup_kwargs = {} -setup_kwargs['options'] = {} setup_kwargs['ext_modules'] = [] setup_kwargs['cmdclass'] = {} +setup_kwargs['options'] = {} + +# +# metadata +# + +# Utility function to read the README file. +# Used for the long_description. It's nice, because now 1) we have a top level +# README file and 2) it's easier to type in the README file than to put a raw +# string in below ... +def read(fname): + return open(os.path.join(os.path.dirname(__file__), fname)).read() + +setup_kwargs['name'] = 'Minecraft-Overviewer' +setup_kwargs['version'] = util.findGitVersion() +setup_kwargs['description'] = 'Generates large resolution images of a Minecraft map.' +setup_kwargs['url'] = 'http://overviewer.org/' +setup_kwargs['author'] = 'Andrew Brown' +setup_kwargs['author_email'] = 'brownan@gmail.com' +setup_kwargs['license'] = 'GNU General Public License v3' +setup_kwargs['long_description'] = read('README.rst') + +# top-level files that should be included as documentation +doc_files = ['COPYING.txt', 'README.rst', 'CONTRIBUTORS.rst', 'sample.settings.py'] + +# helper to create a 'data_files'-type sequence recursively for a given dir +def recursive_data_files(src, dest=None): + if dest is None: + dest = src + + ret = [] + for dirpath, dirnames, filenames in os.walk(src): + current_dest = os.path.relpath(dirpath, src) + if current_dest == '.': + current_dest = dest + else: + current_dest = os.path.join(dest, current_dest) + + current_sources = map(lambda p: os.path.join(dirpath, p), filenames) + + ret.append((current_dest, current_sources)) + return ret # # py2exe options @@ -27,9 +80,9 @@ setup_kwargs['cmdclass'] = {} if py2exe is not None: setup_kwargs['console'] = ['overviewer.py'] - setup_kwargs['data_files'] = [('textures', ['textures/lava.png', 'textures/water.png', 'textures/fire.png', 'textures/portal.png']), - ('', ['COPYING.txt', 'README.rst']), - ('web_assets', glob.glob('web_assets/*'))] + setup_kwargs['data_files'] = [('', doc_files)] + setup_kwargs['data_files'] += recursive_data_files('overviewer_core/data/textures', 'textures') + setup_kwargs['data_files'] += recursive_data_files('overviewer_core/data/web_assets', 'web_assets') setup_kwargs['zipfile'] = None if platform.system() == 'Windows' and '64bit' in platform.architecture(): b = 3 @@ -37,6 +90,28 @@ if py2exe is not None: b = 1 setup_kwargs['options']['py2exe'] = {'bundle_files' : b, 'excludes': 'Tkinter'} +# +# py2app options +# + +if py2app is not None: + setup_kwargs['app'] = ['overviewer.py'] + setup_kwargs['options']['py2app'] = {'argv_emulation' : False} + setup_kwargs['setup_requires'] = ['py2app'] + +# +# script, package, and data +# + +setup_kwargs['packages'] = ['overviewer_core'] +setup_kwargs['scripts'] = ['overviewer.py'] +setup_kwargs['package_data'] = {'overviewer_core': + ['data/textures/*', + 'data/web_assets/*']} +if py2exe is None: + setup_kwargs['data_files'] = [('share/doc/minecraft-overviewer', doc_files)] + + # # c_overviewer extension # @@ -52,25 +127,31 @@ except AttributeError: try: pil_include = os.environ['PIL_INCLUDE_DIR'].split(os.pathsep) except: - pil_include = [] + pil_include = [ os.path.join(get_python_inc(plat_specific=1), 'Imaging') ] + if not os.path.exists(pil_include[0]): + pil_include = [ ] + # used to figure out what files to compile render_modes = ['normal', 'overlay', 'lighting', 'night', 'spawn', 'cave', 'mineral'] -c_overviewer_files = ['src/main.c', 'src/composite.c', 'src/iterate.c', 'src/endian.c', 'src/rendermodes.c'] -c_overviewer_files += map(lambda mode: 'src/rendermode-%s.c' % (mode,), render_modes) -c_overviewer_files += ['src/Draw.c'] -c_overviewer_includes = ['src/overviewer.h', 'src/rendermodes.h'] +c_overviewer_files = ['main.c', 'composite.c', 'iterate.c', 'endian.c', 'rendermodes.c'] +c_overviewer_files += map(lambda mode: 'rendermode-%s.c' % (mode,), render_modes) +c_overviewer_files += ['Draw.c'] +c_overviewer_includes = ['overviewer.h', 'rendermodes.h'] + +c_overviewer_files = map(lambda s: 'overviewer_core/src/'+s, c_overviewer_files) +c_overviewer_includes = map(lambda s: 'overviewer_core/src/'+s, c_overviewer_includes) + +setup_kwargs['ext_modules'].append(Extension('overviewer_core.c_overviewer', c_overviewer_files, include_dirs=['.', numpy_include] + pil_include, depends=c_overviewer_includes, extra_link_args=[])) -setup_kwargs['ext_modules'].append(Extension('c_overviewer', c_overviewer_files, include_dirs=['.', numpy_include] + pil_include, depends=c_overviewer_includes, extra_link_args=[])) # tell build_ext to build the extension in-place # (NOT in build/) setup_kwargs['options']['build_ext'] = {'inplace' : 1} -# tell the build command to only run build_ext -build.sub_commands = [('build_ext', None)] # custom clean command to remove in-place extension +# and the version file class CustomClean(clean): def run(self): # do the normal cleanup @@ -79,7 +160,7 @@ class CustomClean(clean): # try to remove '_composite.{so,pyd,...}' extension, # regardless of the current system's extension name convention build_ext = self.get_finalized_command('build_ext') - pretty_fname = build_ext.get_ext_filename('c_overviewer') + pretty_fname = build_ext.get_ext_filename('overviewer_core.c_overviewer') fname = pretty_fname if os.path.exists(fname): try: @@ -92,8 +173,52 @@ class CustomClean(clean): else: log.debug("'%s' does not exist -- can't clean it", pretty_fname) + + versionpath = os.path.join("overviewer_core", "overviewer_version.py") + try: + if not self.dry_run: + os.remove(versionpath) + log.info("removing '%s'", versionpath) + except OSError: + log.warn("'%s' could not be cleaned -- permission denied", versionpath) -class CustomBuild(build_ext): + # now try to purge all *.pyc files + for root, dirs, files in os.walk(os.path.join(os.path.dirname(__file__), ".")): + for f in files: + if f.endswith(".pyc"): + if self.dry_run: + log.warn("Would remove %s", os.path.join(root,f)) + else: + os.remove(os.path.join(root, f)) + +def generate_version_py(): + try: + outstr = "" + outstr += "VERSION=%r\n" % util.findGitVersion() + outstr += "HASH=%r\n" % util.findGitHash() + outstr += "BUILD_DATE=%r\n" % time.asctime() + outstr += "BUILD_PLATFORM=%r\n" % platform.processor() + outstr += "BUILD_OS=%r\n" % platform.platform() + f = open("overviewer_core/overviewer_version.py", "w") + f.write(outstr) + f.close() + except: + print "WARNING: failed to build overview_version file" + +class CustomSDist(sdist): + def run(self): + # generate the version file + generate_version_py() + sdist.run(self) + +class CustomBuild(build): + def run(self): + # generate the version file + generate_version_py() + build.run(self) + print "\nBuild Complete" + +class CustomBuildExt(build_ext): def build_extensions(self): c = self.compiler.compiler_type if c == "msvc": @@ -101,32 +226,18 @@ class CustomBuild(build_ext): for e in self.extensions: e.extra_link_args.append("/MANIFEST") + # build in place, and in the build/ tree + self.inplace = False + build_ext.build_extensions(self) + self.inplace = True build_ext.build_extensions(self) -if py2exe is not None: -# define a subclass of py2exe to build our version file on the fly - class CustomPy2exe(py2exe.build_exe.py2exe): - def run(self): - try: - import util - f = open("overviewer_version.py", "w") - f.write("VERSION=%r\n" % util.findGitVersion()) - f.write("BUILD_DATE=%r\n" % time.asctime()) - f.write("BUILD_PLATFORM=%r\n" % platform.processor()) - f.write("BUILD_OS=%r\n" % platform.platform()) - f.close() - setup_kwargs['data_files'].append(('.', ['overviewer_version.py'])) - except: - print "WARNING: failed to build overview_version file" - py2exe.build_exe.py2exe.run(self) - setup_kwargs['cmdclass']['py2exe'] = CustomPy2exe - setup_kwargs['cmdclass']['clean'] = CustomClean -setup_kwargs['cmdclass']['build_ext'] = CustomBuild +setup_kwargs['cmdclass']['sdist'] = CustomSDist +setup_kwargs['cmdclass']['build'] = CustomBuild +setup_kwargs['cmdclass']['build_ext'] = CustomBuildExt ### setup(**setup_kwargs) - -print "\nBuild Complete"