Launchpad automatic translations update.
[odoo/odoo.git] / setup.py
1 #!/usr/bin/env python
2 # -*- coding: utf-8 -*-
3 ##############################################################################
4 #    
5 #    OpenERP, Open Source Management Solution
6 #    Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>).
7 #
8 #    This program is free software: you can redistribute it and/or modify
9 #    it under the terms of the GNU Affero General Public License as
10 #    published by the Free Software Foundation, either version 3 of the
11 #    License, or (at your option) any later version.
12 #
13 #    This program is distributed in the hope that it will be useful,
14 #    but WITHOUT ANY WARRANTY; without even the implied warranty of
15 #    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 #    GNU Affero General Public License for more details.
17 #
18 #    You should have received a copy of the GNU Affero General Public License
19 #    along with this program.  If not, see <http://www.gnu.org/licenses/>.     
20 #
21 ##############################################################################
22
23 # setup from TinERP
24 #   taken from straw http://www.nongnu.org/straw/index.html
25 #   taken from gnomolicious http://www.nongnu.org/gnomolicious/
26 #   adapted by Nicolas Évrard <nicoe@altern.org>
27 #
28
29 import imp
30 import sys
31 import os
32 import glob
33
34 from distutils.core import setup, Command
35 from distutils.command.install import install
36
37 has_py2exe = False
38 if os.name == 'nt':
39     import py2exe
40     has_py2exe = True
41
42 sys.path.append(os.path.join(os.path.abspath(os.path.dirname(__file__)), "bin"))
43
44 opj = os.path.join
45
46 execfile(opj('bin', 'release.py'))
47
48 if sys.argv[1] == 'bdist_rpm':
49     version = version.split('-')[0]
50
51 # get python short version
52 py_short_version = '%s.%s' % sys.version_info[:2]
53
54 required_modules = [
55     ('psycopg2', 'PostgreSQL module'),
56     ('xml', 'XML Tools for python'),
57     ('libxml2', 'libxml2 python bindings'),
58     ('libxslt', 'libxslt python bindings'),
59     ('reportlab', 'reportlab module'),
60     ('pychart', 'pychart module'),
61     ('pydot', 'pydot module'),
62 ]
63
64 def check_modules():
65     ok = True
66     for modname, desc in required_modules:
67         try:
68             exec('import %s' % modname)
69         except ImportError:
70             ok = False
71             print 'Error: python module %s (%s) is required' % (modname, desc)
72
73     if not ok:
74         sys.exit(1)
75
76 def _find_addons():
77     for (dp, dn, names) in os.walk(opj('bin', 'addons')):
78         if '__terp__.py' in names:
79             modname = os.path.basename(dp)
80             yield (modname, dp)
81     #look for extra modules
82     try:
83         empath = os.getenv('EXTRA_MODULES_PATH','../addons/')
84         f = open(opj(empath,'server_modules.list'),'r')
85         # print 'Getting modules from:' , opj(empath,'server_modules.list')
86         mods = f.readlines()
87         for mname in mods:
88             mname = mname.strip()
89             if not mname:
90                 continue
91             if os.path.exists(opj(empath,mname,'__terp__.py')):
92                 yield ( mname, opj(empath,mname) )
93             else:
94                 print "Module %s specified, but no valid path." % mname
95     except:
96         pass
97
98 __found_addons = None
99
100 # Cache the results of _find_addons() and return them
101 def find_addons(found_addons = None):
102     if not found_addons:
103         found_addons = _find_addons()
104     return found_addons
105
106 def data_files():
107     '''Build list of data files to be installed'''
108     files = []
109     if os.name == 'nt':
110         os.chdir('bin')
111         for (dp,dn,names) in os.walk('addons'):
112             files.append((dp, map(lambda x: opj('bin', dp, x), names)))
113         os.chdir('..')
114         for (dp,dn,names) in os.walk('doc'):
115             files.append((dp, map(lambda x: opj(dp, x), names)))
116         files.append(('.', [opj('bin', 'import_xml.rng'),
117                             opj('bin', 'server.pkey'),
118                             opj('bin', 'server.cert')]))
119     else:
120         man_directory = opj('share', 'man')
121         files.append((opj(man_directory, 'man1'), ['man/openerp-server.1']))
122         files.append((opj(man_directory, 'man5'), ['man/openerp_serverrc.5']))
123
124         doc_directory = opj('share', 'doc', 'openerp-server-%s' % version)
125         files.append((doc_directory, [f for f in glob.glob('doc/*') if os.path.isfile(f)]))
126         files.append((opj(doc_directory, 'migrate', '3.3.0-3.4.0'), [f for f in glob.glob('doc/migrate/3.3.0-3.4.0/*') if os.path.isfile(f)]))
127         files.append((opj(doc_directory, 'migrate', '3.4.0-4.0.0'), [f for f in glob.glob('doc/migrate/3.4.0-4.0.0/*') if os.path.isfile(f)]))
128
129         openerp_site_packages = opj('lib', 'python%s' % py_short_version, 'site-packages', 'openerp-server')
130
131         files.append((openerp_site_packages, [opj('bin', 'import_xml.rng'),
132                                               opj('bin', 'server.pkey'),
133                                               opj('bin', 'server.cert')]))
134
135         if sys.version_info[0:2] == (2,5):
136             files.append((openerp_site_packages, [ opj('python25-compat','BaseHTTPServer.py'),
137                                                    opj('python25-compat','SimpleXMLRPCServer.py'),
138                                                    opj('python25-compat','SocketServer.py')]))
139
140         for (addonname, add_path) in find_addons():
141             addon_path = opj('lib', 'python%s' % py_short_version, 'site-packages', 'openerp-server','addons', addonname)
142             pathfiles = []
143             for root, dirs, innerfiles in os.walk(add_path):
144                 innerfiles = filter(lambda fil: os.path.splitext(fil)[1] not in ('.pyc', '.pyd', '.pyo'), innerfiles)
145                 if innerfiles:
146                     res = os.path.normpath(opj(addon_path, root.replace(opj(add_path), '.')))
147                     pathfiles.extend(((res, map(lambda fil: opj(root, fil), innerfiles)),))
148             files.extend(pathfiles)
149
150     # for tup in files:
151     #    print "Files:", tup[0], tup[1]
152     return files
153
154 if not os.getenv('NO_CHECK_MODULES',False) :
155     check_modules()
156
157 f = file('openerp-server','w')
158 start_script = """#!/bin/sh\necho "OpenERP Setup - The content of this file is generated at the install stage\n" """
159 f.write(start_script)
160 f.close()
161
162 def find_package_dirs():
163     res = {}
164     for (mod, path) in find_addons():
165         res ['openerp-server.addons.'+ mod ] = path
166     res ['openerp-server'] = 'bin'
167     return res
168
169 class openerp_server_install(install):
170     def run(self):
171         # create startup script
172         start_script = "#!/bin/sh\ncd %s\nexec %s ./openerp-server.py $@\n" % (opj(self.install_libbase, "openerp-server"), sys.executable)
173         # write script
174         f = open('openerp-server', 'w')
175         f.write(start_script)
176         f.close()
177         install.run(self)
178
179 options = {
180     "py2exe": {
181         "compressed": 1,
182         "optimize": 2,
183         "dist_dir": 'dist',
184         "packages": ["lxml", "lxml.builder", "lxml._elementpath", "lxml.etree",
185                      "lxml.objectify", "decimal", "xml", "xml.dom", "xml.xpath",
186                      "encodings","mx.DateTime","wizard","pychart","PIL", "pyparsing",
187                      "pydot","asyncore","asynchat", "reportlab", "vobject",
188                      "HTMLParser", "select"],
189         "excludes" : ["Tkconstants","Tkinter","tcl"],
190     }
191 }
192
193 setup(name             = name,
194       version          = version,
195       description      = description,
196       long_description = long_desc,
197       url              = url,
198       author           = author,
199       author_email     = author_email,
200       classifiers      = filter(None, classifiers.split("\n")),
201       license          = license,
202       data_files       = data_files(),
203       cmdclass         = {
204             'install' : openerp_server_install,
205       },
206       scripts          = ['openerp-server'],
207       packages         = ['openerp-server',
208                           'openerp-server.addons',
209                           'openerp-server.ir',
210                           'openerp-server.osv',
211                           'openerp-server.service',
212                           'openerp-server.tools',
213                           'openerp-server.report',
214                           'openerp-server.report.printscreen',
215                           'openerp-server.report.pyPdf',
216                           'openerp-server.report.render',
217                           'openerp-server.report.render.rml2pdf',
218                           'openerp-server.report.render.rml2html',
219                           'openerp-server.report.render.rml2txt',
220                           'openerp-server.report.render.html2html',
221                           'openerp-server.wizard',
222                           'openerp-server.report.render.odt2odt',
223                           'openerp-server.workflow'] + \
224                           list(map( lambda (a, p): 'openerp-server.addons.'+ a ,find_addons())),
225       package_dir      = find_package_dirs(),
226       console = [ { "script" : "bin\\openerp-server.py", "icon_resources" : [ (1,"pixmaps\\openerp-icon.ico") ] } ],
227       options = options,
228       )
229
230 if has_py2exe:
231   # Sometime between pytz-2008a and pytz-2008i common_timezones started to
232   # include only names of zones with a corresponding data file in zoneinfo.
233   # pytz installs the zoneinfo directory tree in the same directory
234   # as the pytz/__init__.py file. These data files are loaded using
235   # pkg_resources.resource_stream. py2exe does not copy this to library.zip so
236   # resource_stream can't find the files and common_timezones is empty when
237   # read in the py2exe executable.
238   # This manually copies zoneinfo into the zip. See also
239   # http://code.google.com/p/googletransitdatafeed/issues/detail?id=121
240   import pytz
241   import zipfile
242   # Make sure the layout of pytz hasn't changed
243   assert (pytz.__file__.endswith('__init__.pyc') or
244           pytz.__file__.endswith('__init__.py')), pytz.__file__
245   zoneinfo_dir = os.path.join(os.path.dirname(pytz.__file__), 'zoneinfo')
246   # '..\\Lib\\pytz\\__init__.py' -> '..\\Lib'
247   disk_basedir = os.path.dirname(os.path.dirname(pytz.__file__))
248   zipfile_path = os.path.join(options['py2exe']['dist_dir'], 'library.zip')
249   z = zipfile.ZipFile(zipfile_path, 'a')
250   for absdir, directories, filenames in os.walk(zoneinfo_dir):
251     assert absdir.startswith(disk_basedir), (absdir, disk_basedir)
252     zip_dir = absdir[len(disk_basedir):]
253     for f in filenames:
254       z.write(os.path.join(absdir, f), os.path.join(zip_dir, f))
255   z.close()
256