From 5f2acf9fe658403a3277956d5d04ace2ddfdec95 Mon Sep 17 00:00:00 2001 From: gimick Date: Sun, 1 Aug 2010 23:51:33 +0100 Subject: [PATCH] py2exe: get pytz working; make script more restartable; update walkthrough --- .../windows/py2exeWalkthroughPython26.txt | 28 ++++++++- pyfpdb/py2exe_setup.py | 57 +++++++++++-------- 2 files changed, 60 insertions(+), 25 deletions(-) diff --git a/packaging/windows/py2exeWalkthroughPython26.txt b/packaging/windows/py2exeWalkthroughPython26.txt index e379cdae..b2221bc1 100644 --- a/packaging/windows/py2exeWalkthroughPython26.txt +++ b/packaging/windows/py2exeWalkthroughPython26.txt @@ -30,15 +30,41 @@ py2exe 0.6.9 ... http://sourceforge.net/projects/py2exe/files/py2exe/0.6.9/py2ex psycopg2 ... http://www.stickpeople.com/projects/python/win-psycopg/psycopg2-2.2.1.win32-py2.6-pg8.4.3-release.exe (Note: stickpeople is the offical repository, not a community build) + 1.2/ MySQL MySQL-python-1.2.3.win32-py2.6-fpdb0.20.exe ... http://www.mediafire.com/file/iodnnnznmj1/MySQL-python-1.2.3.win32-py2.6-fpdb0.20.exe -This is an intaller built from source by gimick. There are no official mysql-python2.6 build for windows. +This is an intaller built from source by gimick. There are no official mysql-python2.6 builds for windows. Community builds are also available from some developers. see www.codegood.com for example. +1.3/ pytz fixup to work in an executable package + +pytz needs runtime access to timezone definition files. pytz is hard-coded to search in the directory from which the pytz .py modules are being run. +In a py2exe package, this directory is actually a library.zip container file, so windows cannot find the timezone definitions, and will crash the app. + +We need to make a one-line change to pytz to search in the current working directory (which is not a container), and not the application directory. +The py2exe script copies the timezone datafiles into the package folder pyfpdb/zoneinfo. + +Thanks to Jeff Peck gmail.com> on the py2exe mailing list for documenting this problem and solution. + +1.3.1/ Navigate to C:\Python26\Lib\site-packages\pytz +1.3.2/ Edit __init__.py +1.3.3/ At line 55 replace the following line(s): + + filename = os.path.join(os.path.dirname(__file__), + 'zoneinfo', *name_parts) + +with this line: + + filename = os.path.join(os.getcwd(), 'zoneinfo', *name_parts) + +1.3.4/ Save and exit + + + Step 2 Setup GTK ----------------- diff --git a/pyfpdb/py2exe_setup.py b/pyfpdb/py2exe_setup.py index 1be0b437..42d22e21 100644 --- a/pyfpdb/py2exe_setup.py +++ b/pyfpdb/py2exe_setup.py @@ -72,6 +72,14 @@ Py2exe script for fpdb. import os import sys + +# get out now if parameter not passed +try: + sys.argv[1] <> "" +except: + print "A parameter is required, quitting now" + quit() + from distutils.core import setup import py2exe import glob @@ -82,7 +90,6 @@ from datetime import date origIsSystemDLL = py2exe.build_exe.isSystemDLL def isSystemDLL(pathname): - #VisC++ runtime msvcp71.dll removed; py2.6 needs msvcp90.dll which will not be distributed. #dwmapi appears to be vista-specific file, not XP if os.path.basename(pathname).lower() in ("dwmapi.dll"): return 0 @@ -97,7 +104,7 @@ def remove_tree(top): # could delete all your disk files. # sc: Nicked this from somewhere, added the if statement to try # make it a bit safer - if top in ('build','dist','gfx') and os.path.basename(os.getcwd()) == 'pyfpdb': + if top in ('build','dist','pyfpdb',dist_dirname) and os.path.basename(os.getcwd()) == 'pyfpdb': #print "removing directory '"+top+"' ..." for root, dirs, files in os.walk(top, topdown=False): for name in files: @@ -114,12 +121,6 @@ def test_and_remove(top): print "Unexpected file '"+top+"' found. Exiting." exit() -# remove build and dist dirs if they exist -test_and_remove('dist') -test_and_remove('build') -#test_and_remove('gfx') - - today = date.today().strftime('%Y%m%d') print "\n" + r"Output will be created in \pyfpdb\ and \fpdb_"+today+'\\' #print "Enter value for XXX (any length): ", # the comma means no newline @@ -128,7 +129,13 @@ dist_dirname = r'fpdb-' + today + '-exe' dist_dir = r'..\fpdb-' + today + '-exe' print -test_and_remove(dist_dir) +# remove build and dist dirs if they exist +test_and_remove('dist') +test_and_remove('build') +test_and_remove('pyfpdb') + +test_and_remove(dist_dirname) + setup( name = 'fpdb', @@ -142,7 +149,7 @@ setup( options = {'py2exe': { 'packages' : ['encodings', 'matplotlib'], - 'includes' : ['gio', 'cairo', 'pango', 'pangocairo', 'atk', 'gobject' + 'includes' : ['gio', 'cairo', 'pango', 'pangocairo', 'atk', 'gobject' ,'matplotlib.numerix.random_array' ,'AbsoluteToFpdb', 'BetfairToFpdb' ,'CarbonToFpdb', 'EverleafToFpdb' @@ -151,8 +158,8 @@ setup( ,'UltimateBetToFpdb', 'Win2dayToFpdb' ], 'excludes' : ['_tkagg', '_agg2', 'cocoaagg', 'fltkagg'], # surely we need this? '_gtkagg' - 'dll_excludes': ['libglade-2.0-0.dll', 'libgdk-win32-2.0-0.dll' - ,'libgobject-2.0-0.dll', 'msvcr90.dll', 'MSVCP90.dll', 'MSVCR90.dll','msvcr90.dll'], + 'dll_excludes': ['libglade-2.0-0.dll', 'libgdk-win32-2.0-0.dll', 'libgobject-2.0-0.dll' + , 'msvcr90.dll', 'MSVCP90.dll', 'MSVCR90.dll','msvcr90.dll'], # these are vis c / c++ runtimes, and must not be redistributed } }, @@ -166,25 +173,28 @@ setup( ] + matplotlib.get_py2exe_datafiles() ) - +# rename completed output package as pyfpdb os.rename('dist', 'pyfpdb') -# these instructions no longer needed: -#print '\n' + 'If py2exe was successful add the \\etc \\lib and \\share dirs ' -#print 'from your gtk dir to \\%s\\pyfpdb\\\n' % dist_dirname -#print 'Also copy libgobject-2.0-0.dll and libgdk-win32-2.0-0.dll from \\bin' -#print 'into there' +# pull pytz zoneinfo into pyfpdb package folder +src_dir = r'c:\python26\Lib\site-packages\pytz\zoneinfo' +src_dir = src_dir.replace('\\', '\\\\') +dest_dir = os.path.join(r'pyfpdb', 'zoneinfo') +shutil.copytree( src_dir, dest_dir ) +# shunt pyfpdb package over to the distribution folder dest = os.path.join(dist_dirname, 'pyfpdb') -#print "try renaming pyfpdb to", dest +# print "try renaming pyfpdb to", dest dest = dest.replace('\\', '\\\\') -#print "dest is now", dest +# print "dest is now", dest os.rename( 'pyfpdb', dest ) +# prompt for gtk location -print "Enter directory name for GTK (e.g. c:\code\gtk_2.14.7-20090119)\n: ", # the comma means no newline -gtk_dir = sys.stdin.readline().rstrip() - +gtk_dir = "" +while not os.path.exists(gtk_dir): + print "Enter directory name for GTK (e.g. c:\code\gtk_2.14.7-20090119)\n: ", # the comma means no newline + gtk_dir = sys.stdin.readline().rstrip() print "\ncopying files and dirs from ", gtk_dir, "to", dest.replace('\\\\', '\\'), "..." src = os.path.join(gtk_dir, 'bin', 'libgdk-win32-2.0-0.dll') @@ -195,7 +205,6 @@ src = os.path.join(gtk_dir, 'bin', 'libgobject-2.0-0.dll') src = src.replace('\\', '\\\\') shutil.copy( src, dest ) - src_dir = os.path.join(gtk_dir, 'etc') src_dir = src_dir.replace('\\', '\\\\') dest_dir = os.path.join(dest, 'etc')