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', 'webassets', 'jsmin', 'cssmin', 'pojson>=0.4']
128 #for Python older than 2.7
129 if sys
.version_info
[0] <= 2 and sys
.version_info
[1] < 7:
130 base
.append('argparse')
136 '''Retrieves the version number from indico/MaKaC/__init__.py and returns it'''
138 from indico
.MaKaC
import __version__
141 print('Indico %s' % v
)
146 ### Commands ###########################################################
147 class sdist_indico(sdist
.sdist
):
148 user_options
= sdist
.sdist
.user_options
+ \
149 [('version=', None, 'version to distribute')]
153 sdist
.sdist
.run(self
)
156 def _bdist_indico(dataFiles
):
157 class bdist_indico(bdist
.bdist
):
159 compileAllLanguages(self
)
160 bdist
.bdist
.run(self
)
162 bdist_indico
.dataFiles
= dataFiles
166 def _bdist_egg_indico(dataFiles
):
167 class bdist_egg_indico(bdist_egg
.bdist_egg
):
169 compileAllLanguages(self
)
170 bdist_egg
.bdist_egg
.run(self
)
172 bdist_egg_indico
.dataFiles
= dataFiles
173 return bdist_egg_indico
176 class develop_indico(develop
.develop
):
178 develop
.develop
.run(self
)
180 # create symlink to legacy MaKaC dir
181 # this is so that the ".egg-link" created by the "develop" command works
182 if sys
.platform
in ["linux2", "darwin"] and not os
.path
.exists('MaKaC'):
183 os
.symlink('indico/MaKaC','MaKaC')
186 class develop_config(develop_indico
):
187 description
= "prepares the current directory for Indico development"
188 user_options
= develop
.develop
.user_options
+ [('www-uid=', None, "Set user for cache/log/db (typically apache user)"),
189 ('www-gid=', None, "Set group for cache/log/db (typically apache group)")]
195 # dependencies, links, etc...
196 develop_indico
.run(self
)
198 env
= pkg_resources
.Environment()
199 easy_install
.main(DEVELOP_REQUIRES
)
202 local
= 'etc/indico.conf'
203 if os
.path
.exists(local
):
204 print 'Upgrading existing etc/indico.conf..'
205 upgrade_indico_conf(local
, 'etc/indico.conf.sample')
207 print 'Creating new etc/indico.conf..'
208 shutil
.copy('etc/indico.conf.sample', local
)
210 for f
in [x
for x
in ('etc/zdctl.conf', 'etc/zodb.conf', 'etc/logging.conf') if not os
.path
.exists(x
)]:
211 shutil
.copy('%s.sample' % f
, f
)
213 print """\nIndico needs to store some information in the filesystem (database, cache, temporary files, logs...)
214 Please specify the directory where you'd like it to be placed.
215 (Note that putting it outside of your sourcecode tree is recommended)"""
216 prefixDirDefault
= os
.path
.dirname(os
.getcwd())
217 prefixDir
= raw_input('[%s]: ' % prefixDirDefault
).strip()
220 prefixDir
= prefixDirDefault
222 directories
= dict((d
, os
.path
.join(prefixDir
, d
)) for d
in
223 ['db', 'log', 'tmp', 'cache', 'archive'])
225 print 'Creating directories...',
226 for d
in directories
.values():
227 if not os
.path
.exists(d
):
231 directories
['htdocs'] = os
.path
.join(os
.getcwd(), 'indico', 'htdocs')
232 directories
['bin'] = os
.path
.join(os
.getcwd(), 'bin')
233 directories
['etc'] = os
.path
.join(os
.getcwd(), 'etc')
234 directories
['doc'] = os
.path
.join(os
.getcwd(), 'doc')
236 self
._update
_conf
_dir
_paths
(local
, directories
)
238 directories
.pop('htdocs') #avoid modifying the htdocs folder permissions (it brings problems with git)
240 from MaKaC
.consoleScripts
.installBase
import _databaseText
, _findApacheUserGroup
, _checkDirPermissions
, _updateDbConfigFiles
, _updateMaKaCEggCache
244 sourcePath
= os
.getcwd()
246 # find the apache user/group
247 user
, group
= _findApacheUserGroup(self
.www_uid
, self
.www_gid
)
248 _checkDirPermissions(directories
, dbInstalledBySetupPy
=directories
['db'], accessuser
=user
, accessgroup
=group
)
250 _updateDbConfigFiles(directories
['db'], directories
['log'], os
.path
.join(sourcePath
, 'etc'), directories
['tmp'], user
)
252 _updateMaKaCEggCache(os
.path
.join(os
.path
.dirname(__file__
), 'indico', 'MaKaC', '__init__.py'), directories
['tmp'])
254 updateIndicoConfPathInsideMaKaCConfig(os
.path
.join(os
.path
.dirname(__file__
), ''), 'indico/MaKaC/common/MaKaCConfig.py')
255 compileAllLanguages(self
)
258 ''' % _databaseText('etc')
260 def _update_conf_dir_paths(self
, filePath
, dirs
):
261 fdata
= open(filePath
).read()
262 for dir in dirs
.items():
263 d
= dir[1].replace("\\","/") # For Windows users
264 fdata
= re
.sub('\/opt\/indico\/%s'%dir[0], d
, fdata
)
265 open(filePath
, 'w').write(fdata
)
267 class test_indico(test
.test
):
269 Test command for Indico
272 description
= "Test Suite Framework"
273 user_options
= test
.test
.user_options
+ [('specify=', None, "Use nosetests style (file.class:testcase)"),
274 ('coverage', None, "Output coverage report in html"),
275 ('unit', None, "Run only Unit tests"),
276 ('functional', None, "Run only Functional tests"),
277 ('pylint', None, "Run python source analysis"),
278 ('jsunit', None, "Run js unit tests"),
279 ('jslint', None, "Run js source analysis"),
280 ('jscoverage', None, "Output coverage report in html for js"),
281 ('jsspecify=', None, "Use js-test-driver style (TestCaseName.testName)"),
282 ('log=', None, "Log to console, using specified level"),
283 ('browser=', None, "Browser to use for functional tests"),
284 ('mode=', None, "Mode to use for functional tests"),
285 ('server-url=', None, "Server URL to use for functional tests"),
286 ('xml', None, "XML output"),
287 ('html', None, "Make an HTML report (when possible)"),
288 ('record', None, "Record tests (for --functional)"),
289 ('silent', None, "Don't output anything in the console, just generate the report"),
290 ('killself', None, "Kill this script right after the tests finished without waiting for db shutdown.")]
312 def _wrap(self
, func
, *params
):
314 self
.res
= func(*params
)
315 self
.with_project_on_sys_path(wrapped
)
318 def finalize_options(self
):
321 allTests
= ['unit', 'functional']
323 for testType
in allTests
:
324 if getattr(self
, testType
):
325 testsToRun
.append(testType
)
327 if self
.jsspecify
and 'jsunit' not in testsToRun
:
328 testsToRun
.append('jsunit')
331 testsToRun
= allTests
332 self
.testsToRun
= testsToRun
336 if self
.distribution
.install_requires
:
337 self
.distribution
.fetch_build_eggs(self
.distribution
.install_requires
)
338 if self
.distribution
.tests_require
:
339 self
.distribution
.fetch_build_eggs(self
.distribution
.tests_require
)
341 from indico
.tests
import TestManager
343 options
= {'silent': self
.silent
,
344 'killself': self
.killself
,
346 'browser': self
.browser
,
348 'specify': self
.specify
,
349 'coverage': self
.coverage
,
350 'record': self
.record
,
351 'server_url': self
.server_url
,
355 # get only options that are active
356 options
= dict((k
,v
) for (k
,v
) in options
.iteritems() if v
)
358 manager
= TestManager()
359 result
= self
._wrap
(manager
.main
, self
.testsToRun
, options
)
363 def download(self
, url
, path
):
364 """Copy the contents of a file from a given URL
368 webFile
= urllib
.urlopen(url
)
369 localFile
= open(os
.path
.join(path
, url
.split('/')[-1]), 'w')
370 localFile
.write(webFile
.read())
374 def unzip(self
, zipPath
, inZipPath
, targetFile
):
375 """extract the needed file from zip and then delete the zip"""
378 zfobj
= zipfile
.ZipFile(zipPath
)
379 outfile
= open(targetFile
, 'wb')
380 outfile
.write(zfobj
.read(inZipPath
))
390 class egg_filename(Command
):
391 description
= "Get the file name of the generated egg"
395 def initialize_options(self
):
398 def finalize_options(self
):
399 ei_cmd
= self
.ei_cmd
= self
.get_finalized_command("egg_info")
400 self
.egg_info
= ei_cmd
.egg_info
402 basename
= pkg_resources
.Distribution(
403 None, None, ei_cmd
.egg_name
, ei_cmd
.egg_version
,
404 get_python_version(),
405 self
.distribution
.has_ext_modules() and pkg_utils
.get_build_platform
415 if __name__
== '__main__':
416 # Always load source from the current folder
417 sys
.path
= [os
.path
.abspath('indico')] + sys
.path
419 #PWD_INDICO_CONF = 'etc/indico.conf'
420 #if not os.path.exists(PWD_INDICO_CONF):
421 # shutil.copy('etc/indico.conf.sample', PWD_INDICO_CONF)
423 from MaKaC
.consoleScripts
.installBase
import *
426 #Dirty trick: For running tests, we need to load all the modules and get rid of unnecessary outputs
427 tempLoggingDir
= None
428 if 'test' in sys
.argv
:
431 tempLoggingDir
= tempfile
.mkdtemp()
432 logging
.basicConfig(filename
=os
.path
.join(tempLoggingDir
, 'logging'),
434 setIndicoInstallMode(False)
436 setIndicoInstallMode(True)
439 x
.packageDir
= os
.path
.join(get_python_lib(), 'MaKaC')
443 x
.documentationDir
= 'doc'
444 x
.configurationDir
= 'etc'
445 x
.htdocsDir
= 'htdocs'
447 dataFiles
= _getDataFiles(x
)
449 foundPackages
= list('MaKaC.%s' % pkg
for pkg
in
450 find_packages(where
= 'indico/MaKaC'))
451 foundPackages
.append('MaKaC')
452 foundPackages
.append('htdocs')
454 # add our namespace package
455 foundPackages
+= list('indico.%s' % pkg
for pkg
in
456 find_packages(where
= 'indico',
457 exclude
= ['htdocs*', 'MaKaC*']))
458 foundPackages
.append('indico')
460 cmdclass
= {'sdist': sdist_indico
,
461 'bdist': _bdist_indico(dataFiles
),
462 'bdist_egg': _bdist_egg_indico(dataFiles
),
463 'develop_config': develop_config
,
464 'develop': develop_indico
,
466 'egg_filename': egg_filename
470 for cmdname
in ['init_catalog', 'extract_messages', 'compile_catalog', 'update_catalog']:
471 cmdclass
['%s_js' % cmdname
] = getattr(babel
, cmdname
)
472 cmdclass
['compile_catalog_js'] = i18n
.generate_messages_js
474 setup(name
= "indico",
476 version
= _versionInit(),
477 description
= "Indico is a full-featured conference lifecycle management and meeting/lecture scheduling tool",
478 author
= "Indico Team",
479 author_email
= "indico-team@cern.ch",
480 url
= "http://indico-software.org",
481 download_url
= "http://indico-software.org/wiki/Releases/Indico0.98-rc1",
483 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",
484 license
= "http://www.gnu.org/licenses/gpl-2.0.txt",
488 indico_scheduler = indico.modules.scheduler.daemon_script:main
489 indico_initial_setup = MaKaC.consoleScripts.indicoInitialSetup:main
490 indico_ctl = MaKaC.consoleScripts.indicoCtl:main
491 indico_livesync = indico.ext.livesync.console:main
492 indico_shell = indico.util.shell:main
496 statistics = indico.ext.statistics
497 Collaboration = MaKaC.plugins.Collaboration
498 InstantMessaging = MaKaC.plugins.InstantMessaging
499 RoomBooking = MaKaC.plugins.RoomBooking
500 EPayment = MaKaC.plugins.EPayment
501 livesync = indico.ext.livesync
502 importer = indico.ext.importer
506 statistics.piwik = indico.ext.statistics.piwik
508 Collaboration.EVO = MaKaC.plugins.Collaboration.EVO
509 Collaboration.Vidyo = MaKaC.plugins.Collaboration.Vidyo
510 Collaboration.CERNMCU = MaKaC.plugins.Collaboration.CERNMCU
511 Collaboration.RecordingManager = MaKaC.plugins.Collaboration.RecordingManager
512 Collaboration.RecordingRequest = MaKaC.plugins.Collaboration.RecordingRequest
513 Collaboration.WebcastRequest = MaKaC.plugins.Collaboration.WebcastRequest
515 RoomBooking.CERN = MaKaC.plugins.RoomBooking.CERN
516 RoomBooking.default = MaKaC.plugins.RoomBooking.default
518 EPayment.payPal = MaKaC.plugins.EPayment.payPal
519 EPayment.worldPay = MaKaC.plugins.EPayment.worldPay
520 EPayment.yellowPay = MaKaC.plugins.EPayment.yellowPay
521 EPayment.skipjack = MaKaC.plugins.EPayment.skipjack
523 importer.invenio = indico.ext.importer.invenio
524 importer.dummy = indico.ext.importer.dummy
526 InstantMessaging.XMPP = MaKaC.plugins.InstantMessaging.XMPP
528 livesync.invenio = indico.ext.livesync.invenio
529 livesync.cern_search = indico.ext.livesync.cern_search
533 packages
= foundPackages
,
534 package_dir
= { 'indico': 'indico',
535 'htdocs': os
.path
.join('indico', 'htdocs'),
536 'MaKaC' : os
.path
.join('indico', 'MaKaC')},
537 package_data
= {'indico': ['*.*']},
538 include_package_data
=True,
539 namespace_packages
= ['indico', 'indico.ext'],
540 install_requires
= _getInstallRequires(),
541 tests_require
= ['nose', 'rednose', 'twill', 'selenium', 'figleaf'],
542 data_files
= dataFiles
,
543 dependency_links
= DEPENDENCY_URLS
546 #delete the temp folder used for logging
547 if 'test' in sys
.argv
:
548 shutil
.rmtree(tempLoggingDir
)