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