1 # -*- coding: utf-8 -*-
4 ## This file is part of Indico
5 ## Copyright (C) 2002 - 2013 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
, \
41 from setuptools
import setup
, find_packages
, findall
45 from babel
.messages
import frontend
as babel
51 DEPENDENCY_URLS
= ["http://indico-software.org/wiki/Admin/Installation/IndicoExtras"]
53 DEVELOP_REQUIRES
= ['pojson>=0.4', 'termcolor']
55 if sys
.platform
== 'linux2':
61 '''Variable holder.'''
66 dbInstalledBySetupPy
= False
68 documentationDir
= None
69 configurationDir
= None
73 ### Methods required by setup() ##############################################
75 def _generateDataPaths(x
):
79 for (baseDstDir
, srcDir
) in x
:
80 for f
in findall(srcDir
):
81 dst_dir
= os
.path
.join(baseDstDir
,
82 os
.path
.relpath(os
.path
.dirname(f
), srcDir
))
83 if dst_dir
not in dataFilesDict
:
84 dataFilesDict
[dst_dir
] = []
85 dataFilesDict
[dst_dir
].append(f
)
88 for k
, v
in dataFilesDict
.items():
89 dataFiles
.append((k
, v
))
96 Returns a fully populated data_files ready to be fed to setup()
98 WARNING: when creating a bdist_egg we need to include files inside bin,
99 doc, config & htdocs into the egg therefore we cannot fetch indico.conf
100 values directly because they will not refer to the proper place. We
101 include those files in the egg's root folder.
104 # setup expects a list like this (('foo/bar/baz', 'wiki.py'),
105 # ('a/b/c', 'd.jpg'))
107 # What we do below is transform a list like this:
108 # (('foo', 'bar/baz/wiki.py'),
109 # ('a', 'b/c/d.jpg'))
111 # first into a dict and then into a pallatable form for setuptools.
113 # This re will be used to filter out etc/*.conf files and therefore not overwritting them
114 dataFiles
= _generateDataPaths((('bin', 'bin'),
120 def _getInstallRequires():
121 '''Returns external packages required by Indico
123 These are the ones needed for runtime.'''
125 base
= ['ZODB3==3.10.5', 'zope.index', 'zope.interface',
126 'pytz', 'lxml', 'cds-indico-extras', 'zc.queue',
127 'python-dateutil<2.0', 'pypdf', 'mako>=0.4.1', 'babel',
128 'icalendar>=3.2', 'pyatom', 'jsmin', 'cssmin', 'webassets', 'pojson>=0.4',
129 'requests', 'simplejson>=2.1.0', 'reportlab']
131 #for Python older than 2.7
132 if sys
.version_info
[0] <= 2 and sys
.version_info
[1] < 7:
133 base
.append('argparse')
139 '''Retrieves the version number from indico/MaKaC/__init__.py and returns it'''
141 from indico
.MaKaC
import __version__
144 print('Indico %s' % v
)
149 ### Commands ###########################################################
150 class sdist_indico(sdist
.sdist
):
151 user_options
= (sdist
.sdist
.user_options
+
152 [('version=', None, 'version to distribute')])
156 sdist
.sdist
.run(self
)
159 def _bdist_indico(dataFiles
):
160 class bdist_indico(bdist
.bdist
):
162 compileAllLanguages(self
)
163 bdist
.bdist
.run(self
)
165 bdist_indico
.dataFiles
= dataFiles
169 def _bdist_egg_indico(dataFiles
):
170 class bdist_egg_indico(bdist_egg
.bdist_egg
):
172 compileAllLanguages(self
)
173 bdist_egg
.bdist_egg
.run(self
)
175 bdist_egg_indico
.dataFiles
= dataFiles
176 return bdist_egg_indico
179 class develop_indico(develop
.develop
):
181 develop
.develop
.run(self
)
183 # create symlink to legacy MaKaC dir
184 # this is so that the ".egg-link" created by the "develop" command works
185 if sys
.platform
in ["linux2", "darwin"] and not os
.path
.exists('MaKaC'):
186 os
.symlink('indico/MaKaC', 'MaKaC')
189 class develop_config(develop_indico
):
190 description
= "prepares the current directory for Indico development"
191 user_options
= (develop
.develop
.user_options
+
192 [('www-uid=', None, "Set user for cache/log/db (typically apache user)"),
193 ('www-gid=', None, "Set group for cache/log/db (typically apache group)")])
199 # dependencies, links, etc...
200 develop_indico
.run(self
)
202 env
= pkg_resources
.Environment()
203 easy_install
.main(DEVELOP_REQUIRES
)
206 local
= 'etc/indico.conf'
207 if os
.path
.exists(local
):
208 print 'Upgrading existing etc/indico.conf..'
209 upgrade_indico_conf(local
, 'etc/indico.conf.sample')
211 print 'Creating new etc/indico.conf..'
212 shutil
.copy('etc/indico.conf.sample', local
)
214 for f
in [x
for x
in ('etc/zdctl.conf', 'etc/zodb.conf', 'etc/logging.conf') if not os
.path
.exists(x
)]:
215 shutil
.copy('%s.sample' % f
, f
)
217 print """\nIndico needs to store some information in the filesystem (database, cache, temporary files, logs...)
218 Please specify the directory where you'd like it to be placed.
219 (Note that putting it outside of your sourcecode tree is recommended)"""
220 prefixDirDefault
= os
.path
.dirname(os
.getcwd())
221 prefixDir
= raw_input('[%s]: ' % prefixDirDefault
).strip()
224 prefixDir
= prefixDirDefault
226 directories
= dict((d
, os
.path
.join(prefixDir
, d
)) for d
in
227 ['db', 'log', 'tmp', 'cache', 'archive'])
229 print 'Creating directories...',
230 for d
in directories
.values():
231 if not os
.path
.exists(d
):
235 directories
['htdocs'] = os
.path
.join(os
.getcwd(), 'indico', 'htdocs')
236 directories
['bin'] = os
.path
.join(os
.getcwd(), 'bin')
237 directories
['etc'] = os
.path
.join(os
.getcwd(), 'etc')
238 directories
['doc'] = os
.path
.join(os
.getcwd(), 'doc')
240 self
._update
_conf
_dir
_paths
(local
, directories
)
242 # avoid modifying the htdocs folder permissions (it brings problems with git)
243 directories
.pop('htdocs')
245 from MaKaC
.consoleScripts
.installBase
import _databaseText
, _findApacheUserGroup
, _checkDirPermissions
, \
246 _updateDbConfigFiles
, _updateMaKaCEggCache
250 sourcePath
= os
.getcwd()
252 # find the apache user/group
253 user
, group
= _findApacheUserGroup(self
.www_uid
, self
.www_gid
)
254 _checkDirPermissions(directories
, dbInstalledBySetupPy
=directories
['db'], accessuser
=user
, accessgroup
=group
)
256 _updateDbConfigFiles(directories
['db'], directories
['log'], os
.path
.join(sourcePath
, 'etc'),
257 directories
['tmp'], user
)
259 _updateMaKaCEggCache(os
.path
.join(os
.path
.dirname(__file__
), 'indico', 'MaKaC', '__init__.py'),
262 updateIndicoConfPathInsideMaKaCConfig(os
.path
.join(os
.path
.dirname(__file__
), ''),
263 'indico/MaKaC/common/MaKaCConfig.py')
264 compileAllLanguages(self
)
267 ''' % _databaseText('etc')
269 def _update_conf_dir_paths(self
, filePath
, dirs
):
270 fdata
= open(filePath
).read()
271 for dir in dirs
.items():
272 d
= dir[1].replace("\\", "/") # For Windows users
273 fdata
= re
.sub('\/opt\/indico\/%s' % dir[0], d
, fdata
)
274 open(filePath
, 'w').write(fdata
)
277 class test_indico(test
.test
):
279 Test command for Indico
282 description
= "Test Suite Framework"
283 user_options
= (test
.test
.user_options
+ [('specify=', None, "Use nosetests style (file.class:testcase)"),
284 ('coverage', None, "Output coverage report in html"),
285 ('unit', None, "Run only Unit tests"),
286 ('functional', None, "Run only Functional tests"),
287 ('pylint', None, "Run python source analysis"),
288 ('jsunit', None, "Run js unit tests"),
289 ('jslint', None, "Run js source analysis"),
290 ('jscoverage', None, "Output coverage report in html for js"),
291 ('jsspecify=', None, "Use js-test-driver style (TestCaseName.testName)"),
292 ('log=', None, "Log to console, using specified level"),
293 ('browser=', None, "Browser to use for functional tests"),
294 ('mode=', None, "Mode to use for functional tests"),
295 ('server-url=', None, "Server URL to use for functional tests"),
296 ('xml', None, "XML output"),
297 ('html', None, "Make an HTML report (when possible)"),
298 ('record', None, "Record tests (for --functional)"),
299 ('silent', None, "Don't output anything in the console, just generate the report"),
301 "Kill this script right after the tests finished without waiting for db shutdown.")])
323 def _wrap(self
, func
, *params
):
325 self
.res
= func(*params
)
326 self
.with_project_on_sys_path(wrapped
)
329 def finalize_options(self
):
332 allTests
= ['unit', 'functional']
334 for testType
in allTests
:
335 if getattr(self
, testType
):
336 testsToRun
.append(testType
)
338 if self
.jsspecify
and 'jsunit' not in testsToRun
:
339 testsToRun
.append('jsunit')
342 testsToRun
= allTests
343 self
.testsToRun
= testsToRun
347 if self
.distribution
.install_requires
:
348 self
.distribution
.fetch_build_eggs(self
.distribution
.install_requires
)
349 if self
.distribution
.tests_require
:
350 self
.distribution
.fetch_build_eggs(self
.distribution
.tests_require
)
352 from indico
.tests
import TestManager
354 options
= {'silent': self
.silent
,
355 'killself': self
.killself
,
357 'browser': self
.browser
,
359 'specify': self
.specify
,
360 'coverage': self
.coverage
,
361 'record': self
.record
,
362 'server_url': self
.server_url
,
366 # get only options that are active
367 options
= dict((k
, v
) for (k
, v
) in options
.iteritems() if v
)
369 manager
= TestManager()
370 result
= self
._wrap
(manager
.main
, self
.testsToRun
, options
)
374 def download(self
, url
, path
):
375 """Copy the contents of a file from a given URL
379 webFile
= urllib
.urlopen(url
)
380 localFile
= open(os
.path
.join(path
, url
.split('/')[-1]), 'w')
381 localFile
.write(webFile
.read())
385 def unzip(self
, zipPath
, inZipPath
, targetFile
):
386 """extract the needed file from zip and then delete the zip"""
389 zfobj
= zipfile
.ZipFile(zipPath
)
390 outfile
= open(targetFile
, 'wb')
391 outfile
.write(zfobj
.read(inZipPath
))
401 class egg_filename(Command
):
402 description
= "Get the file name of the generated egg"
406 def initialize_options(self
):
409 def finalize_options(self
):
410 ei_cmd
= self
.ei_cmd
= self
.get_finalized_command("egg_info")
411 self
.egg_info
= ei_cmd
.egg_info
413 basename
= pkg_resources
.Distribution(
414 None, None, ei_cmd
.egg_name
, ei_cmd
.egg_version
,
415 get_python_version(),
416 self
.distribution
.has_ext_modules() and pkg_utils
.get_build_platform
).egg_name()
424 if __name__
== '__main__':
425 # Always load source from the current folder
426 sys
.path
= [os
.path
.abspath('indico')] + sys
.path
428 #PWD_INDICO_CONF = 'etc/indico.conf'
429 #if not os.path.exists(PWD_INDICO_CONF):
430 # shutil.copy('etc/indico.conf.sample', PWD_INDICO_CONF)
432 from MaKaC
.consoleScripts
.installBase
import *
434 #Dirty trick: For running tests, we need to load all the modules and get rid of unnecessary outputs
435 tempLoggingDir
= None
436 if 'test' in sys
.argv
:
439 tempLoggingDir
= tempfile
.mkdtemp()
440 logging
.basicConfig(filename
=os
.path
.join(tempLoggingDir
, 'logging'),
442 setIndicoInstallMode(False)
444 setIndicoInstallMode(True)
447 x
.packageDir
= os
.path
.join(get_python_lib(), 'MaKaC')
450 x
.documentationDir
= 'doc'
451 x
.configurationDir
= 'etc'
452 x
.htdocsDir
= 'htdocs'
454 dataFiles
= _getDataFiles(x
)
456 foundPackages
= list('MaKaC.%s' % pkg
for pkg
in
457 find_packages(where
='indico/MaKaC'))
458 foundPackages
.append('MaKaC')
459 foundPackages
.append('htdocs')
461 # add our namespace package
462 foundPackages
+= list('indico.%s' % pkg
for pkg
in
463 find_packages(where
='indico',
464 exclude
=['htdocs*', 'MaKaC*']))
465 foundPackages
.append('indico')
467 cmdclass
= {'sdist': sdist_indico
,
468 'bdist': _bdist_indico(dataFiles
),
469 'bdist_egg': _bdist_egg_indico(dataFiles
),
470 'develop_config': develop_config
,
471 'develop': develop_indico
,
473 'egg_filename': egg_filename
477 for cmdname
in ['init_catalog', 'extract_messages', 'compile_catalog', 'update_catalog']:
478 cmdclass
['%s_js' % cmdname
] = getattr(babel
, cmdname
)
479 cmdclass
['compile_catalog_js'] = i18n
.generate_messages_js
483 version
=_versionInit(),
484 description
="Indico is a full-featured conference lifecycle management and meeting/lecture scheduling tool",
485 author
="Indico Team",
486 author_email
="indico-team@cern.ch",
487 url
="http://indico-software.org",
488 download_url
="http://indico-software.org/wiki/Releases/Indico0.99",
490 long_description
="Indico allows you to schedule conferences, from single talks to complex meetings with "
491 "sessions and contributions. It also includes an advanced user delegation mechanism, "
492 "allows paper reviewing, archival of conference information and electronic proceedings",
493 license
="http://www.gnu.org/licenses/gpl-3.0.txt",
497 indico_scheduler = indico.modules.scheduler.daemon_script:main
498 indico_initial_setup = MaKaC.consoleScripts.indicoInitialSetup:main
499 indico_ctl = MaKaC.consoleScripts.indicoCtl:main
500 indico_livesync = indico.ext.livesync.console:main
501 indico_shell = indico.util.shell:main
502 indico_admin = indico.util.admin:main
506 statistics = indico.ext.statistics
507 Collaboration = MaKaC.plugins.Collaboration
508 InstantMessaging = MaKaC.plugins.InstantMessaging
509 RoomBooking = MaKaC.plugins.RoomBooking
510 EPayment = MaKaC.plugins.EPayment
511 livesync = indico.ext.livesync
512 importer = indico.ext.importer
513 calendaring = indico.ext.calendaring
514 search = indico.ext.search
518 statistics.piwik = indico.ext.statistics.piwik
520 Collaboration.EVO = MaKaC.plugins.Collaboration.EVO
521 Collaboration.WebEx = MaKaC.plugins.Collaboration.WebEx
522 Collaboration.Vidyo = MaKaC.plugins.Collaboration.Vidyo
523 Collaboration.CERNMCU = MaKaC.plugins.Collaboration.CERNMCU
524 Collaboration.RecordingManager = MaKaC.plugins.Collaboration.RecordingManager
525 Collaboration.RecordingRequest = MaKaC.plugins.Collaboration.RecordingRequest
526 Collaboration.WebcastRequest = MaKaC.plugins.Collaboration.WebcastRequest
528 RoomBooking.CERN = MaKaC.plugins.RoomBooking.CERN
529 RoomBooking.default = MaKaC.plugins.RoomBooking.default
531 EPayment.payPal = MaKaC.plugins.EPayment.payPal
532 EPayment.worldPay = MaKaC.plugins.EPayment.worldPay
533 EPayment.yellowPay = MaKaC.plugins.EPayment.yellowPay
534 EPayment.skipjack = MaKaC.plugins.EPayment.skipjack
536 importer.invenio = indico.ext.importer.invenio
537 importer.dummy = indico.ext.importer.dummy
539 InstantMessaging.XMPP = MaKaC.plugins.InstantMessaging.XMPP
541 livesync.invenio = indico.ext.livesync.invenio
542 livesync.cern_search = indico.ext.livesync.cern_search
544 calendaring.outlook = indico.ext.calendaring.outlook
546 search.invenio = indico.ext.search.invenio
550 packages
=foundPackages
,
551 package_dir
={'indico': 'indico',
552 'htdocs': os
.path
.join('indico', 'htdocs'),
553 'MaKaC': os
.path
.join('indico', 'MaKaC')},
554 package_data
={'indico': ['*.*']},
555 include_package_data
=True,
556 namespace_packages
=['indico', 'indico.ext'],
557 install_requires
=_getInstallRequires(),
558 tests_require
=['nose', 'rednose', 'twill', 'selenium', 'figleaf'],
559 data_files
=dataFiles
,
560 dependency_links
=DEPENDENCY_URLS
563 #delete the temp folder used for logging
564 if 'test' in sys
.argv
:
565 shutil
.rmtree(tempLoggingDir
)