1 # -*- coding: utf-8 -*-
4 ## This file is part of Indico
5 ## Copyright (C) 2002 - 2012 European Organization for Nuclear Research (CERN)
7 ## Indico is free software: you can redistribute it and/or
8 ## modify it under the terms of the GNU General Public License as
9 ## published by the Free Software Foundation, either version 3 of the
10 ## License, or (at your option) any later version.
12 ## Indico is distributed in the hope that it will be useful, but
13 ## WITHOUT ANY WARRANTY; without even the implied warranty of
14 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 ## GNU General Public License for more details.
17 ## You should have received a copy of the GNU General Public License
18 ## along with Indico. If not, see <http://www.gnu.org/licenses/>.
20 # Autoinstalls setuptools if the user doesn't have them already
22 ez_setup
.use_setuptools()
32 from distutils
.sysconfig
import get_python_lib
, get_python_version
33 from distutils
.cmd
import Command
34 from distutils
.command
import bdist
35 from indico
.util
import i18n
39 from setuptools
.command
import develop
, install
, sdist
, bdist_egg
, easy_install
, test
40 from setuptools
import setup
, find_packages
, findall
44 from babel
.messages
import frontend
as babel
50 DEPENDENCY_URLS
= ["http://indico-software.org/wiki/Admin/Installation/IndicoExtras",
51 "https://github.com/collective/icalendar/tarball/6f899869d462a23d0ebd3f54fb237e8670242bc4#egg=icalendar-3.0"]
53 DEVELOP_REQUIRES
= ['pojson>=0.4', 'termcolor']
55 if sys
.platform
== 'linux2':
61 '''Variable holder.'''
66 dbInstalledBySetupPy
= False
68 documentationDir
= None
69 configurationDir
= None
72 ### Methods required by setup() ##############################################
74 def _generateDataPaths(x
):
78 for (baseDstDir
, srcDir
) in x
:
79 for f
in findall(srcDir
):
80 dst_dir
= os
.path
.join(baseDstDir
,
81 os
.path
.relpath(os
.path
.dirname(f
), srcDir
))
82 if dst_dir
not in dataFilesDict
:
83 dataFilesDict
[dst_dir
] = []
84 dataFilesDict
[dst_dir
].append(f
)
87 for k
, v
in dataFilesDict
.items():
88 dataFiles
.append((k
, v
))
94 Returns a fully populated data_files ready to be fed to setup()
96 WARNING: when creating a bdist_egg we need to include files inside bin,
97 doc, config & htdocs into the egg therefore we cannot fetch indico.conf
98 values directly because they will not refer to the proper place. We
99 include those files in the egg's root folder.
102 # setup expects a list like this (('foo/bar/baz', 'wiki.py'),
103 # ('a/b/c', 'd.jpg'))
105 # What we do below is transform a list like this:
106 # (('foo', 'bar/baz/wiki.py'),
107 # ('a', 'b/c/d.jpg'))
109 # first into a dict and then into a pallatable form for setuptools.
111 # This re will be used to filter out etc/*.conf files and therefore not overwritting them
112 dataFiles
= _generateDataPaths((('bin', 'bin'),
118 def _getInstallRequires():
119 '''Returns external packages required by Indico
121 These are the ones needed for runtime.'''
123 base
= ['ZODB3>=3.8', 'pytz', 'zope.index', 'zope.interface',
124 'lxml', 'cds-indico-extras', 'zc.queue', 'python-dateutil<2.0',
125 'pypdf', 'mako>=0.4.1', 'babel', 'icalendar>=3.0', 'pyatom',
126 'simplejson', 'python-cjson', 'cssmin', 'webassets',
127 'pojson>=0.4', 'requests']
129 #for Python older than 2.7
130 if sys
.version_info
[0] <= 2 and sys
.version_info
[1] < 7:
131 base
.append('argparse')
137 '''Retrieves the version number from indico/MaKaC/__init__.py and returns it'''
139 from indico
.MaKaC
import __version__
142 print('Indico %s' % v
)
147 ### Commands ###########################################################
148 class sdist_indico(sdist
.sdist
):
149 user_options
= sdist
.sdist
.user_options
+ \
150 [('version=', None, 'version to distribute')]
154 sdist
.sdist
.run(self
)
157 def _bdist_indico(dataFiles
):
158 class bdist_indico(bdist
.bdist
):
160 compileAllLanguages(self
)
161 bdist
.bdist
.run(self
)
163 bdist_indico
.dataFiles
= dataFiles
167 def _bdist_egg_indico(dataFiles
):
168 class bdist_egg_indico(bdist_egg
.bdist_egg
):
170 compileAllLanguages(self
)
171 bdist_egg
.bdist_egg
.run(self
)
173 bdist_egg_indico
.dataFiles
= dataFiles
174 return bdist_egg_indico
177 class develop_indico(develop
.develop
):
179 develop
.develop
.run(self
)
181 # create symlink to legacy MaKaC dir
182 # this is so that the ".egg-link" created by the "develop" command works
183 if sys
.platform
in ["linux2", "darwin"] and not os
.path
.exists('MaKaC'):
184 os
.symlink('indico/MaKaC','MaKaC')
187 class develop_config(develop_indico
):
188 description
= "prepares the current directory for Indico development"
189 user_options
= develop
.develop
.user_options
+ [('www-uid=', None, "Set user for cache/log/db (typically apache user)"),
190 ('www-gid=', None, "Set group for cache/log/db (typically apache group)")]
196 # dependencies, links, etc...
197 develop_indico
.run(self
)
199 env
= pkg_resources
.Environment()
200 easy_install
.main(DEVELOP_REQUIRES
)
203 local
= 'etc/indico.conf'
204 if os
.path
.exists(local
):
205 print 'Upgrading existing etc/indico.conf..'
206 upgrade_indico_conf(local
, 'etc/indico.conf.sample')
208 print 'Creating new etc/indico.conf..'
209 shutil
.copy('etc/indico.conf.sample', local
)
211 for f
in [x
for x
in ('etc/zdctl.conf', 'etc/zodb.conf', 'etc/logging.conf') if not os
.path
.exists(x
)]:
212 shutil
.copy('%s.sample' % f
, f
)
214 print """\nIndico needs to store some information in the filesystem (database, cache, temporary files, logs...)
215 Please specify the directory where you'd like it to be placed.
216 (Note that putting it outside of your sourcecode tree is recommended)"""
217 prefixDirDefault
= os
.path
.dirname(os
.getcwd())
218 prefixDir
= raw_input('[%s]: ' % prefixDirDefault
).strip()
221 prefixDir
= prefixDirDefault
223 directories
= dict((d
, os
.path
.join(prefixDir
, d
)) for d
in
224 ['db', 'log', 'tmp', 'cache', 'archive'])
226 print 'Creating directories...',
227 for d
in directories
.values():
228 if not os
.path
.exists(d
):
232 directories
['htdocs'] = os
.path
.join(os
.getcwd(), 'indico', 'htdocs')
233 directories
['bin'] = os
.path
.join(os
.getcwd(), 'bin')
234 directories
['etc'] = os
.path
.join(os
.getcwd(), 'etc')
235 directories
['doc'] = os
.path
.join(os
.getcwd(), 'doc')
237 self
._update
_conf
_dir
_paths
(local
, directories
)
239 directories
.pop('htdocs') #avoid modifying the htdocs folder permissions (it brings problems with git)
241 from MaKaC
.consoleScripts
.installBase
import _databaseText
, _findApacheUserGroup
, _checkDirPermissions
, _updateDbConfigFiles
, _updateMaKaCEggCache
245 sourcePath
= os
.getcwd()
247 # find the apache user/group
248 user
, group
= _findApacheUserGroup(self
.www_uid
, self
.www_gid
)
249 _checkDirPermissions(directories
, dbInstalledBySetupPy
=directories
['db'], accessuser
=user
, accessgroup
=group
)
251 _updateDbConfigFiles(directories
['db'], directories
['log'], os
.path
.join(sourcePath
, 'etc'), directories
['tmp'], user
)
253 _updateMaKaCEggCache(os
.path
.join(os
.path
.dirname(__file__
), 'indico', 'MaKaC', '__init__.py'), directories
['tmp'])
255 updateIndicoConfPathInsideMaKaCConfig(os
.path
.join(os
.path
.dirname(__file__
), ''), 'indico/MaKaC/common/MaKaCConfig.py')
256 compileAllLanguages(self
)
259 ''' % _databaseText('etc')
261 def _update_conf_dir_paths(self
, filePath
, dirs
):
262 fdata
= open(filePath
).read()
263 for dir in dirs
.items():
264 d
= dir[1].replace("\\","/") # For Windows users
265 fdata
= re
.sub('\/opt\/indico\/%s'%dir[0], d
, fdata
)
266 open(filePath
, 'w').write(fdata
)
268 class test_indico(test
.test
):
270 Test command for Indico
273 description
= "Test Suite Framework"
274 user_options
= test
.test
.user_options
+ [('specify=', None, "Use nosetests style (file.class:testcase)"),
275 ('coverage', None, "Output coverage report in html"),
276 ('unit', None, "Run only Unit tests"),
277 ('functional', None, "Run only Functional tests"),
278 ('pylint', None, "Run python source analysis"),
279 ('jsunit', None, "Run js unit tests"),
280 ('jslint', None, "Run js source analysis"),
281 ('jscoverage', None, "Output coverage report in html for js"),
282 ('jsspecify=', None, "Use js-test-driver style (TestCaseName.testName)"),
283 ('log=', None, "Log to console, using specified level"),
284 ('browser=', None, "Browser to use for functional tests"),
285 ('mode=', None, "Mode to use for functional tests"),
286 ('server-url=', None, "Server URL to use for functional tests"),
287 ('xml', None, "XML output"),
288 ('html', None, "Make an HTML report (when possible)"),
289 ('record', None, "Record tests (for --functional)"),
290 ('silent', None, "Don't output anything in the console, just generate the report"),
291 ('killself', None, "Kill this script right after the tests finished without waiting for db shutdown.")]
313 def _wrap(self
, func
, *params
):
315 self
.res
= func(*params
)
316 self
.with_project_on_sys_path(wrapped
)
319 def finalize_options(self
):
322 allTests
= ['unit', 'functional']
324 for testType
in allTests
:
325 if getattr(self
, testType
):
326 testsToRun
.append(testType
)
328 if self
.jsspecify
and 'jsunit' not in testsToRun
:
329 testsToRun
.append('jsunit')
332 testsToRun
= allTests
333 self
.testsToRun
= testsToRun
337 if self
.distribution
.install_requires
:
338 self
.distribution
.fetch_build_eggs(self
.distribution
.install_requires
)
339 if self
.distribution
.tests_require
:
340 self
.distribution
.fetch_build_eggs(self
.distribution
.tests_require
)
342 from indico
.tests
import TestManager
344 options
= {'silent': self
.silent
,
345 'killself': self
.killself
,
347 'browser': self
.browser
,
349 'specify': self
.specify
,
350 'coverage': self
.coverage
,
351 'record': self
.record
,
352 'server_url': self
.server_url
,
356 # get only options that are active
357 options
= dict((k
,v
) for (k
,v
) in options
.iteritems() if v
)
359 manager
= TestManager()
360 result
= self
._wrap
(manager
.main
, self
.testsToRun
, options
)
364 def download(self
, url
, path
):
365 """Copy the contents of a file from a given URL
369 webFile
= urllib
.urlopen(url
)
370 localFile
= open(os
.path
.join(path
, url
.split('/')[-1]), 'w')
371 localFile
.write(webFile
.read())
375 def unzip(self
, zipPath
, inZipPath
, targetFile
):
376 """extract the needed file from zip and then delete the zip"""
379 zfobj
= zipfile
.ZipFile(zipPath
)
380 outfile
= open(targetFile
, 'wb')
381 outfile
.write(zfobj
.read(inZipPath
))
391 class egg_filename(Command
):
392 description
= "Get the file name of the generated egg"
396 def initialize_options(self
):
399 def finalize_options(self
):
400 ei_cmd
= self
.ei_cmd
= self
.get_finalized_command("egg_info")
401 self
.egg_info
= ei_cmd
.egg_info
403 basename
= pkg_resources
.Distribution(
404 None, None, ei_cmd
.egg_name
, ei_cmd
.egg_version
,
405 get_python_version(),
406 self
.distribution
.has_ext_modules() and pkg_utils
.get_build_platform
416 if __name__
== '__main__':
417 # Always load source from the current folder
418 sys
.path
= [os
.path
.abspath('indico')] + sys
.path
420 #PWD_INDICO_CONF = 'etc/indico.conf'
421 #if not os.path.exists(PWD_INDICO_CONF):
422 # shutil.copy('etc/indico.conf.sample', PWD_INDICO_CONF)
424 from MaKaC
.consoleScripts
.installBase
import *
427 #Dirty trick: For running tests, we need to load all the modules and get rid of unnecessary outputs
428 tempLoggingDir
= None
429 if 'test' in sys
.argv
:
432 tempLoggingDir
= tempfile
.mkdtemp()
433 logging
.basicConfig(filename
=os
.path
.join(tempLoggingDir
, 'logging'),
435 setIndicoInstallMode(False)
437 setIndicoInstallMode(True)
440 x
.packageDir
= os
.path
.join(get_python_lib(), 'MaKaC')
444 x
.documentationDir
= 'doc'
445 x
.configurationDir
= 'etc'
446 x
.htdocsDir
= 'htdocs'
448 dataFiles
= _getDataFiles(x
)
450 foundPackages
= list('MaKaC.%s' % pkg
for pkg
in
451 find_packages(where
= 'indico/MaKaC'))
452 foundPackages
.append('MaKaC')
453 foundPackages
.append('htdocs')
455 # add our namespace package
456 foundPackages
+= list('indico.%s' % pkg
for pkg
in
457 find_packages(where
= 'indico',
458 exclude
= ['htdocs*', 'MaKaC*']))
459 foundPackages
.append('indico')
461 cmdclass
= {'sdist': sdist_indico
,
462 'bdist': _bdist_indico(dataFiles
),
463 'bdist_egg': _bdist_egg_indico(dataFiles
),
464 'develop_config': develop_config
,
465 'develop': develop_indico
,
467 'egg_filename': egg_filename
471 for cmdname
in ['init_catalog', 'extract_messages', 'compile_catalog', 'update_catalog']:
472 cmdclass
['%s_js' % cmdname
] = getattr(babel
, cmdname
)
473 cmdclass
['compile_catalog_js'] = i18n
.generate_messages_js
475 setup(name
= "indico",
477 version
= _versionInit(),
478 description
= "Indico is a full-featured conference lifecycle management and meeting/lecture scheduling tool",
479 author
= "Indico Team",
480 author_email
= "indico-team@cern.ch",
481 url
= "http://indico-software.org",
482 download_url
= "http://indico-software.org/wiki/Releases/Indico0.98-rc1",
484 long_description
= "Indico allows you to schedule conferences, from single talks to complex meetings with sessions and contributions. It also includes an advanced user delegation mechanism, allows paper reviewing, archival of conference information and electronic proceedings",
485 license
= "http://www.gnu.org/licenses/gpl-2.0.txt",
489 indico_scheduler = indico.modules.scheduler.daemon_script:main
490 indico_initial_setup = MaKaC.consoleScripts.indicoInitialSetup:main
491 indico_ctl = MaKaC.consoleScripts.indicoCtl:main
492 indico_livesync = indico.ext.livesync.console:main
493 indico_shell = indico.util.shell:main
497 statistics = indico.ext.statistics
498 Collaboration = MaKaC.plugins.Collaboration
499 InstantMessaging = MaKaC.plugins.InstantMessaging
500 RoomBooking = MaKaC.plugins.RoomBooking
501 EPayment = MaKaC.plugins.EPayment
502 livesync = indico.ext.livesync
503 importer = indico.ext.importer
507 statistics.piwik = indico.ext.statistics.piwik
509 Collaboration.EVO = MaKaC.plugins.Collaboration.EVO
510 Collaboration.Vidyo = MaKaC.plugins.Collaboration.Vidyo
511 Collaboration.CERNMCU = MaKaC.plugins.Collaboration.CERNMCU
512 Collaboration.RecordingManager = MaKaC.plugins.Collaboration.RecordingManager
513 Collaboration.RecordingRequest = MaKaC.plugins.Collaboration.RecordingRequest
514 Collaboration.WebcastRequest = MaKaC.plugins.Collaboration.WebcastRequest
516 RoomBooking.CERN = MaKaC.plugins.RoomBooking.CERN
517 RoomBooking.default = MaKaC.plugins.RoomBooking.default
519 EPayment.payPal = MaKaC.plugins.EPayment.payPal
520 EPayment.worldPay = MaKaC.plugins.EPayment.worldPay
521 EPayment.yellowPay = MaKaC.plugins.EPayment.yellowPay
522 EPayment.skipjack = MaKaC.plugins.EPayment.skipjack
524 importer.invenio = indico.ext.importer.invenio
525 importer.dummy = indico.ext.importer.dummy
527 InstantMessaging.XMPP = MaKaC.plugins.InstantMessaging.XMPP
529 livesync.invenio = indico.ext.livesync.invenio
530 livesync.cern_search = indico.ext.livesync.cern_search
534 packages
= foundPackages
,
535 package_dir
= { 'indico': 'indico',
536 'htdocs': os
.path
.join('indico', 'htdocs'),
537 'MaKaC' : os
.path
.join('indico', 'MaKaC')},
538 package_data
= {'indico': ['*.*']},
539 include_package_data
=True,
540 namespace_packages
= ['indico', 'indico.ext'],
541 install_requires
= _getInstallRequires(),
542 tests_require
= ['nose', 'rednose', 'twill', 'selenium', 'figleaf'],
543 data_files
= dataFiles
,
544 dependency_links
= DEPENDENCY_URLS
547 #delete the temp folder used for logging
548 if 'test' in sys
.argv
:
549 shutil
.rmtree(tempLoggingDir
)