0

Merge branch 'py-package'

Conflicts:
	setup.py
This commit is contained in:
Aaron Griffith
2011-07-10 18:05:25 -04:00
45 changed files with 198 additions and 71 deletions

16
.gitignore vendored
View File

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

9
MANIFEST.in Normal file
View File

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

View File

@@ -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,7 +36,7 @@ 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
@@ -49,7 +48,7 @@ except ImportError:
## 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)"
@@ -57,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:
@@ -76,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] <World # / Name / Path to World> <tiles dest dir>
@@ -124,14 +124,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)

View File

View File

Before

Width:  |  Height:  |  Size: 563 B

After

Width:  |  Height:  |  Size: 563 B

View File

Before

Width:  |  Height:  |  Size: 401 B

After

Width:  |  Height:  |  Size: 401 B

View File

Before

Width:  |  Height:  |  Size: 672 B

After

Width:  |  Height:  |  Size: 672 B

View File

Before

Width:  |  Height:  |  Size: 374 B

After

Width:  |  Height:  |  Size: 374 B

View File

Before

Width:  |  Height:  |  Size: 7.2 KiB

After

Width:  |  Height:  |  Size: 7.2 KiB

View File

Before

Width:  |  Height:  |  Size: 2.7 KiB

After

Width:  |  Height:  |  Size: 2.7 KiB

View File

Before

Width:  |  Height:  |  Size: 2.7 KiB

After

Width:  |  Height:  |  Size: 2.7 KiB

View File

Before

Width:  |  Height:  |  Size: 368 B

After

Width:  |  Height:  |  Size: 368 B

View File

Before

Width:  |  Height:  |  Size: 708 B

After

Width:  |  Height:  |  Size: 708 B

View File

Before

Width:  |  Height:  |  Size: 253 B

After

Width:  |  Height:  |  Size: 253 B

View File

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

View File

@@ -33,13 +33,13 @@ PyObject *init_chunk_render(PyObject *self, PyObject *args) {
return NULL;
}
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;

View File

@@ -14,6 +14,7 @@
# with the Overviewer. If not, see <http://www.gnu.org/licenses/>.
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)

View File

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

154
setup.py Normal file → Executable file
View File

@@ -1,26 +1,60 @@
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):
@@ -46,9 +80,9 @@ def recursive_data_files(src, dest=None):
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'])]
setup_kwargs['data_files'] += recursive_data_files('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
@@ -56,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
#
@@ -79,20 +135,23 @@ except:
# used to figure out what files to compile
render_modes = ['normal', 'overlay', 'lighting', 'night', 'spawn', 'cave']
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
@@ -101,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:
@@ -114,8 +173,43 @@ 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):
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":
@@ -123,32 +217,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"