1 | #!/usr/bin/python |
---|
2 | # -*- coding: utf8 -*- |
---|
3 | """ |
---|
4 | Build script for pyromaths. |
---|
5 | |
---|
6 | This script is internally based on setuptools, with platform-specific extensions |
---|
7 | for special tasks (py2app, py2exe, innosetup). |
---|
8 | It builds different types of packages (source, binary, self-contained) on |
---|
9 | several platforms. Packages should be functional, although further optimization |
---|
10 | may be operated by other scripts (see: pkg/README). |
---|
11 | |
---|
12 | Python source and bynary eggs (all platforms): |
---|
13 | $ python setup.py [sdist|bdist|bdist_egg] [options...] |
---|
14 | |
---|
15 | RPM package (UNIX/Linux): |
---|
16 | $ ./setup.py bdist_rpm [options...] |
---|
17 | |
---|
18 | Self-contained application (Mac OS X): |
---|
19 | $ python setup.py py2app [options...] |
---|
20 | |
---|
21 | Self-contained application (Windows): |
---|
22 | $ python setup.py py2exe [options...] |
---|
23 | $ python setup.py innosetup [options...] |
---|
24 | |
---|
25 | Help and options: |
---|
26 | $ python setup.py --help |
---|
27 | $ python setup.py --help-commands |
---|
28 | |
---|
29 | Created on 13 avr. 2013 |
---|
30 | @author: Olivier Cornu <o.cornu@gmail.com> |
---|
31 | |
---|
32 | """ |
---|
33 | import os |
---|
34 | import sys |
---|
35 | import codecs |
---|
36 | from glob import glob, has_magic |
---|
37 | from os.path import dirname, normpath, join, abspath, realpath |
---|
38 | |
---|
39 | from setuptools import setup, find_packages |
---|
40 | |
---|
41 | import gettext |
---|
42 | locale_dir = join(dirname(__file__), 'locale/') |
---|
43 | locale_dir = realpath(locale_dir) |
---|
44 | |
---|
45 | gettext.install('pyromaths', localedir=locale_dir, unicode=1) |
---|
46 | |
---|
47 | py2exe, innosetup = None, None |
---|
48 | try: |
---|
49 | import py2exe |
---|
50 | import innosetup |
---|
51 | except ImportError: |
---|
52 | pass |
---|
53 | |
---|
54 | # Import pyromaths VERSION from source |
---|
55 | _path = normpath(join(abspath(dirname(__file__)), "./src")) |
---|
56 | sys.path[0] = realpath(_path) |
---|
57 | #sys.path.append('src') |
---|
58 | from pyromaths.Values import VERSION |
---|
59 | print "Version ", VERSION |
---|
60 | |
---|
61 | def _unix_opt(): |
---|
62 | '''UNIX/Linux: generate Python eggs and RPM packages.''' |
---|
63 | return dict( |
---|
64 | platforms = ['unix'], |
---|
65 | scripts = ['pyromaths'], |
---|
66 | data_files = [ |
---|
67 | ('share/applications', ['data/linux/pyromaths.desktop']), |
---|
68 | ('share/man/man1', ['data/linux/pyromaths.1']), |
---|
69 | ('share/pixmaps/', ['data/images/pyromaths.png']), |
---|
70 | ('share/pyromaths/images', ['data/images/pyromaths-banniere.png', |
---|
71 | 'data/images/whatsthis.png']), |
---|
72 | ('share/pyromaths/templates', glob('data/templates/*.tex')), |
---|
73 | ('share/locale/es/LC_MESSAGES', ['data/locale/es/LC_MESSAGES/pyromaths.mo']), |
---|
74 | ('share/locale/ca_ES@valencia/LC_MESSAGES', ['data/locale/ca_ES@valencia/LC_MESSAGES/pyromaths.mo']) |
---|
75 | # ('share/pyromaths/packages', glob('data/packages/*')) |
---|
76 | ] + \ |
---|
77 | find_data_files('data/ex','share/pyromaths/ex/',['*/img/*/*.png']), |
---|
78 | install_requires = ["lxml>=2.2.2"], |
---|
79 | ) |
---|
80 | |
---|
81 | def _mac_opt(): |
---|
82 | '''MacOS: py2app helps generate a self-contained app.''' |
---|
83 | plist = dict(CFBundleIdentifier = "org.pyromaths.pyromaths", |
---|
84 | CFBundleName = "Pyromaths", |
---|
85 | CFBundleDisplayName = "Pyromaths", |
---|
86 | CFBundleVersion = VERSION, |
---|
87 | CFBundleShortVersionString = VERSION, |
---|
88 | NSHumanReadableCopyright = u"© Jérôme Ortais", |
---|
89 | CFBundleDevelopmentRegion = "French", |
---|
90 | CFBundleIconFile = "pyromaths", |
---|
91 | CFBundleExecutable = "pyromaths", |
---|
92 | CFBundlePackageType = "APPL", |
---|
93 | CFBundleSignature = "PYTS", |
---|
94 | ) |
---|
95 | # Unused Qt libraries/frameworks |
---|
96 | qt_unused = ['QtDBus', 'QtDeclarative', 'QtDesigner', 'QtHelp', |
---|
97 | 'QtMultimedia', 'QtNetwork', 'QtOpenGL', 'QtScript', |
---|
98 | 'QtScriptTools', 'QtSql', 'QtSvg', 'QtTest', 'QtWebKit', |
---|
99 | 'QtXml', 'QtXmlPatterns', 'phonon'] |
---|
100 | lib_dynload_unused = ['_AE', '_codecs_cn', '_codecs_hk', '_codecs_2022', |
---|
101 | '_codecs_iso2022', '_codecs_jp', '_codecs_kr', |
---|
102 | '_codecs_tw', '_Evt', '_File', '_hashlib', '_heapq', |
---|
103 | '_locale', '_multibytecodec', '_Res','_ssl', 'array', |
---|
104 | 'bz2', 'cPickle', 'datetime', 'gestalt', 'MacOS', |
---|
105 | 'pyexpat', 'rurce', 'strop', 'unicodedata'] |
---|
106 | site_packages_unused = ['_osx_support', '_builtinSuites', 'Carbon', |
---|
107 | 'distutils', 'Finder', 'StdSuites','xml', |
---|
108 | 'getopt', 'repr', '_strptime','gettext', 'sets', |
---|
109 | '_threading_local','base64', 'locale', |
---|
110 | 'sre', 'bdb', 'optparse.', 'ssl', 'calendar', 'pdb', |
---|
111 | 'stringprep', 'cmd', 'pkg_resources', 'copy', |
---|
112 | 'platform', 'threading', 'dummy_thread', 'plistlib', |
---|
113 | 'quopri', 'doctest', 'ntpath', 'OpenSSL', |
---|
114 | 'os2emxpath', 'PyQt4.uic'] |
---|
115 | excludes = lib_dynload_unused + site_packages_unused + ['PyQt4.%s' % f for f in qt_unused] |
---|
116 | # py2app |
---|
117 | py2app = dict(plist = plist, |
---|
118 | iconfile = 'data/images/pyromaths.icns', |
---|
119 | includes = ['gzip'], |
---|
120 | packages = ['pyromaths.ex'], |
---|
121 | excludes = excludes, |
---|
122 | argv_emulation = True, |
---|
123 | ) |
---|
124 | return dict( |
---|
125 | app = ['src/pyromaths.py'], |
---|
126 | data_files = [ |
---|
127 | ( 'data', ['data/qtmac_fr.qm']), |
---|
128 | ( 'data/images', ['data/images/pyromaths.png', |
---|
129 | 'data/images/whatsthis.png']), |
---|
130 | ('data/templates', glob('data/templates/*.tex')), |
---|
131 | # ('data/packages', glob('data/packages/*')), |
---|
132 | ] + find_data_files('data/ex','data/ex/',['*/img/*.png']), |
---|
133 | setup_requires = ['py2app>=0.7.3', 'lxml>=2.2.2'], |
---|
134 | options = {'py2app': py2app}, |
---|
135 | ) |
---|
136 | |
---|
137 | def _win_opt(): |
---|
138 | '''M$ Win: py2exe helps generate a self-contained app.''' |
---|
139 | # import py2exe, innosetup |
---|
140 | inno_script = ''' |
---|
141 | [Setup] |
---|
142 | Compression = lzma/max |
---|
143 | OutputBaseFilename = pyromaths-%s-win32 |
---|
144 | [Languages] |
---|
145 | Name: "french"; MessagesFile: "compiler:Languages\French.isl" |
---|
146 | [Tasks] |
---|
147 | Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked |
---|
148 | [Icons] |
---|
149 | Name: "{commondesktop}\Pyromaths"; Filename: "{app}\pyromaths.exe" |
---|
150 | ''' % VERSION |
---|
151 | return dict( |
---|
152 | platforms = ['windows'], |
---|
153 | data_files=[ |
---|
154 | ('data/images', ['data/images/pyromaths.ico', |
---|
155 | 'data/images/pyromaths.png', 'data/images/pyromaths-banniere.png', |
---|
156 | 'data/images/whatsthis.png'] |
---|
157 | ), |
---|
158 | (r'data/templates', glob(r'data/templates/*.tex')), |
---|
159 | # (r'data/packages', glob(r'data/packages/*')), |
---|
160 | ] + find_data_files('data/ex','data/ex/',['*/img/*.png']), |
---|
161 | zipfile = None, |
---|
162 | windows = [dict(script="pyromaths", |
---|
163 | icon_resources=[(1, 'data/images/pyromaths.ico')], |
---|
164 | ) |
---|
165 | ], |
---|
166 | setup_requires = ['py2exe'], |
---|
167 | options = dict(py2exe=dict(compressed = True, |
---|
168 | optimize = 2, |
---|
169 | bundle_files = 3, |
---|
170 | packages = ['pyromaths.ex', ], |
---|
171 | includes = ['sip', 'gzip', ], |
---|
172 | dll_excludes = ['msvcr90.dll', 'msvcp90.dll'], |
---|
173 | ), |
---|
174 | innosetup=dict(inno_script=inno_script, |
---|
175 | bundle_vcr = False, |
---|
176 | ) |
---|
177 | ) |
---|
178 | ) |
---|
179 | |
---|
180 | def find_data_files(source,target,patterns): |
---|
181 | if has_magic(source) or has_magic(target): |
---|
182 | raise ValueError("Magic not allowed in src, target") |
---|
183 | ret = {} |
---|
184 | for pattern in patterns: |
---|
185 | pattern = os.path.join(source,pattern) |
---|
186 | for filename in glob(pattern): |
---|
187 | if os.path.isfile(filename): |
---|
188 | targetpath = os.path.join(target, os.path.relpath(filename, source)) |
---|
189 | path = os.path.dirname(targetpath) |
---|
190 | ret.setdefault(path,[]).append(filename) |
---|
191 | return sorted(ret.items()) |
---|
192 | |
---|
193 | # Set platform-specific options |
---|
194 | if "py2app" in sys.argv: |
---|
195 | options = _mac_opt() |
---|
196 | elif sys.platform == 'win32': |
---|
197 | options = _win_opt() |
---|
198 | else: |
---|
199 | options = _unix_opt() |
---|
200 | |
---|
201 | # Long description is copied from README file |
---|
202 | if innosetup: |
---|
203 | # innosetup fails with generated multiline long description |
---|
204 | README = "Create maths exercises in LaTeX and PDF format" |
---|
205 | else: |
---|
206 | with codecs.open('README', encoding='utf-8', mode='r') as file: |
---|
207 | README = file.read() |
---|
208 | |
---|
209 | setup( |
---|
210 | # project metadata |
---|
211 | name = "pyromaths", |
---|
212 | version = VERSION, |
---|
213 | description = "Create maths exercises in LaTeX and PDF format", |
---|
214 | long_description = README, |
---|
215 | license = "GPL", |
---|
216 | url = "http://www.pyromaths.org", |
---|
217 | download_url = "http://www.pyromaths.org/telecharger/", |
---|
218 | author = u"Jérôme Ortais", |
---|
219 | author_email = "jerome.ortais@pyromaths.org", |
---|
220 | # python packages |
---|
221 | packages = find_packages('src'), |
---|
222 | package_dir = {'': 'src'}, |
---|
223 | # dependencies |
---|
224 | provides = ["pyromaths"], |
---|
225 | # platform-specific options |
---|
226 | **options |
---|
227 | ) |
---|
228 | |
---|
229 | # Post-processing |
---|
230 | if "py2app" in sys.argv: |
---|
231 | # py2app/setenv hack: replace executable with one appending several LaTeX |
---|
232 | # distributions locations to the path. |
---|
233 | mactex = "/Library/TeX/texbin:/usr/texbin:/usr/local/bin" |
---|
234 | macports = "/opt/local/bin:/opt/local/sbin" |
---|
235 | fink = "/sw/bin" |
---|
236 | path = "%s:%s:%s" % (mactex, macports, fink) |
---|
237 | f = open('dist/Pyromaths.app/Contents/MacOS/setenv.sh', 'w') |
---|
238 | f.write('''#!/bin/sh |
---|
239 | PWD=$(dirname "$0"); /usr/bin/env PATH="$PATH:%s" $PWD/pyromaths''' % path) |
---|
240 | os.system("chmod +x dist/Pyromaths.app/Contents/MacOS/setenv.sh") |
---|
241 | os.system("sed -i '' '23s/pyromaths/setenv.sh/' dist/Pyromaths.app/Contents/Info.plist") |
---|