360 lines
12 KiB
Python
Executable File
360 lines
12 KiB
Python
Executable File
#!/usr/bin/env python
|
|
# -*- coding: iso-8859-15 -*-
|
|
|
|
|
|
# Glasnost
|
|
# By: Odile Bénassy <obenassy@entrouvert.com>
|
|
# Romain Chantereau <rchantereau@entrouvert.com>
|
|
# Nicolas Clapiès <nclapies@easter-eggs.org>
|
|
# Pierre-Antoine Dejace <padejace@entrouvert.be>
|
|
# Thierry Dulieu <tdulieu@easter-eggs.com>
|
|
# Florent Monnier <monnier@codelutin.com>
|
|
# Cédric Musso <cmusso@easter-eggs.org>
|
|
# Frédéric Péters <fpeters@entrouvert.be>
|
|
# Benjamin Poussin <poussin@codelutin.com>
|
|
# Emmanuel Raviart <eraviart@entrouvert.com>
|
|
# Sébastien Régnier <regnier@codelutin.com>
|
|
# Emmanuel Saracco <esaracco@easter-eggs.com>
|
|
#
|
|
# Copyright (C) 2000, 2001 Easter-eggs & Emmanuel Raviart
|
|
# Copyright (C) 2002 Odile Bénassy, Code Lutin, Thierry Dulieu, Easter-eggs,
|
|
# Entr'ouvert, Frédéric Péters, Benjamin Poussin, Emmanuel Raviart,
|
|
# Emmanuel Saracco & Théridion
|
|
# Copyright (C) 2003 Odile Bénassy, Romain Chantereau, Nicolas Clapiès,
|
|
# Code Lutin, Pierre-Antoine Dejace, Thierry Dulieu, Easter-eggs,
|
|
# Entr'ouvert, Florent Monnier, Cédric Musso, Ouvaton, Frédéric Péters,
|
|
# Benjamin Poussin, Rodolphe Quiédeville, Emmanuel Raviart, Sébastien
|
|
# Régnier, Emmanuel Saracco, Théridion & Vecam
|
|
#
|
|
# This program is free software; you can redistribute it and/or
|
|
# modify it under the terms of the GNU General Public License
|
|
# as published by the Free Software Foundation; either version 2
|
|
# of the License, or (at your option) any later version.
|
|
#
|
|
# This program is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License
|
|
# along with this program; if not, write to the Free Software
|
|
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
|
|
|
|
__doc__ = """Glasnost Controller"""
|
|
|
|
__version__ = '$Revision$'[11:-2]
|
|
|
|
|
|
import __builtin__
|
|
import ConfigParser
|
|
import locale
|
|
import marshal
|
|
import os
|
|
import signal
|
|
import sys
|
|
import time
|
|
|
|
glasnostPythonDir = '/usr/local/lib/glasnost-devel' # changed on make install
|
|
sys.path.insert(0, glasnostPythonDir)
|
|
|
|
import glasnost
|
|
import glasnost.common.context as context
|
|
from glasnost.common.tools import *
|
|
import glasnost.common.tools_new as commonTools
|
|
|
|
verbose = 0
|
|
|
|
config = ConfigParser.ConfigParser()
|
|
config.readfp(open(commonTools.configDir + '/config'))
|
|
|
|
servers = ['Dispatcher',]
|
|
if 'Gateway' in config.sections():
|
|
servers += ['Gateway',]
|
|
if 'Cache' in config.sections():
|
|
servers += ['Cache',]
|
|
|
|
servers += [x for x in config.sections() if x.endswith('Server')]
|
|
|
|
def doStart():
|
|
if len(sys.argv) > 2 and sys.argv[2] == '--simulate':
|
|
print 'Would start Glasnost (%d servers):' % len(servers)
|
|
for server in servers:
|
|
print ' ', server
|
|
return
|
|
|
|
print 'Starting Glasnost (%d servers) ' % len(servers),
|
|
sys.stdout.flush()
|
|
for server in servers:
|
|
rc = doStartOne(server)
|
|
if rc == 0:
|
|
sys.stdout.write('.')
|
|
sys.stdout.flush()
|
|
else:
|
|
sys.stdout.write('F')
|
|
sys.stdout.flush()
|
|
if verbose:
|
|
logDir = config.get('Misc', 'LogFilesDir')
|
|
if not logDir:
|
|
continue
|
|
fileName = os.path.join(logDir, '%s.log' % server)
|
|
try:
|
|
fileInstance = open(fileName,'r')
|
|
except IOError:
|
|
continue
|
|
print ''.join(fileInstance.readlines()[-10:])
|
|
fileInstance.close()
|
|
print ' done.'
|
|
|
|
def doStartMissing():
|
|
for server in servers:
|
|
serverFileName = '%s/servers/%s/%s.py' % (
|
|
glasnostPythonDir, server, server)
|
|
processes = [int(x.split()[0]) for x in os.popen('ps ax').readlines() \
|
|
if x.endswith(serverFileName + '\n')]
|
|
if len(processes) == 0:
|
|
if verbose:
|
|
print 'Was missing:', server
|
|
doStartOne(server)
|
|
|
|
|
|
def doStartOne(server):
|
|
serverFileName = '%s/servers/%s/%s.py' % (
|
|
glasnostPythonDir, server, server)
|
|
L = [serverFileName]
|
|
return os.spawnvpe(os.P_WAIT, serverFileName, L, os.environ)
|
|
|
|
def doStop():
|
|
print 'Stopping Glasnost...',
|
|
sys.stdout.flush()
|
|
for server in servers:
|
|
doStopOne(server)
|
|
print 'done.'
|
|
|
|
def doStopOne(server):
|
|
serverFileName = '%s/servers/%s/%s.py' % (
|
|
glasnostPythonDir, server, server)
|
|
processes = [int(x.split()[0]) for x in os.popen('ps ax').readlines() \
|
|
if x.endswith(serverFileName + '\n')]
|
|
for process in processes:
|
|
os.kill(process, signal.SIGTERM)
|
|
|
|
def doRestartOne(server):
|
|
doStopOne(server)
|
|
time.sleep(1)
|
|
doStartOne(server)
|
|
|
|
def doLogRotate():
|
|
for server in servers:
|
|
serverFileName = '%s/servers/%s/%s.py' % (
|
|
glasnostPythonDir, server, server)
|
|
processes = [int(x.split()[0]) for x in os.popen('ps ax').readlines() \
|
|
if x.endswith(serverFileName + '\n')]
|
|
for process in processes:
|
|
os.kill(process, signal.SIGHUP)
|
|
|
|
|
|
def doMakeHelp(sourceDispatcher):
|
|
helpServers = ['articles', 'atoms', 'cards', 'pagenames',
|
|
'groups', 'rubrics', 'translations', 'uploadfiles']
|
|
for server in servers:
|
|
serverFileName = '%s/servers/%s/%s.py' % (
|
|
glasnostPythonDir, server, server)
|
|
L = [serverFileName, '-s', 'glasnost://%s' % sourceDispatcher,
|
|
'-d', 'glasnost://help', '-y', repr(helpServers)]
|
|
rc = os.spawnvpe(os.P_WAIT, serverFileName, L, os.environ)
|
|
|
|
|
|
def doMakeSystem(sourceDispatcher):
|
|
systemServers = ['articles', 'atoms', 'cards', 'pagenames',
|
|
'groups', 'rubrics', 'translations', 'uploadfiles']
|
|
for server in servers:
|
|
serverFileName = '%s/servers/%s/%s.py' % (
|
|
glasnostPythonDir, server, server)
|
|
L = [serverFileName, '-s', 'glasnost://%s' % sourceDispatcher,
|
|
'-d', 'glasnost://system', '-y', repr(systemServers)]
|
|
rc = os.spawnvpe(os.P_WAIT, serverFileName, L, os.environ)
|
|
|
|
|
|
def doExport(sourceDispatcher):
|
|
for server in servers:
|
|
serverFileName = '%s/servers/%s/%s.py' % (
|
|
glasnostPythonDir, server, server)
|
|
cmdLine = '%s -s glasnost://%s -x "%s"' % (
|
|
serverFileName, sourceDispatcher, os.getcwd())
|
|
rc = os.system(cmdLine)
|
|
|
|
|
|
def doImport(destDispatcher):
|
|
for server in servers:
|
|
serverFileName = '%s/servers/%s/%s.py' % (
|
|
glasnostPythonDir, server, server)
|
|
cmdLine = '%s -i "%s" -d %s' % (
|
|
serverFileName, os.getcwd(), destDispatcher)
|
|
rc = os.system(cmdLine)
|
|
|
|
def doConvertIds(sourceDispatcher, destDispatcher):
|
|
for server in servers:
|
|
serverFileName = '%s/servers/%s/%s.py' % (
|
|
glasnostPythonDir, server, server)
|
|
L = [serverFileName, '-s', 'glasnost://%s' % sourceDispatcher, \
|
|
'-d','glasnost://%s' % destDispatcher]
|
|
rc = os.spawnvpe(os.P_WAIT, serverFileName, L, os.environ)
|
|
|
|
def doCompileTal(directory):
|
|
for lang in ['en', 'fr']:
|
|
print 'Compiling templates for %s ' % lang,
|
|
context.push(
|
|
readLanguages = [lang],
|
|
localeDirectoryPath = commonTools.getConfig(
|
|
'Misc', 'LocaleDir', '/usr/share/locale'),
|
|
)
|
|
try:
|
|
locale.setlocale(locale.LC_COLLATE, (lang, None))
|
|
except locale.Error:
|
|
if lang != 'en':
|
|
continue
|
|
translation = commonTools.translation(
|
|
['%s-web' % glasnost.applicationName,
|
|
'glasnost-lyon2003', 'glasnost-weblog', 'glasnost-metis'],
|
|
[lang] )
|
|
__builtin__.__dict__['_'] = translation.gettext
|
|
|
|
from glasnost.web.GlasnostTALGenerator import GlasnostTALGenerator
|
|
from TAL.HTMLTALParser import HTMLTALParser
|
|
failures = []
|
|
for root, dir, files in osWalk(directory):
|
|
for file in files:
|
|
if not file.endswith('.tal') and not file.endswith('.html'):
|
|
continue
|
|
file = os.path.join(root, file)
|
|
p = HTMLTALParser(gen = GlasnostTALGenerator(xml=0))
|
|
try:
|
|
p.parseFile(file)
|
|
except faults.StringNotAvailableThroughGettext:
|
|
failures.append(file)
|
|
sys.stdout.write('-')
|
|
sys.stdout.flush()
|
|
continue
|
|
except:
|
|
failures.append(file)
|
|
sys.stdout.write('F')
|
|
sys.stdout.flush()
|
|
continue
|
|
code = p.getCode()
|
|
marshal.dump(code, open('%sc.%s' % (file, lang), 'w'))
|
|
sys.stdout.write('.')
|
|
sys.stdout.flush()
|
|
print ''
|
|
if verbose and failures:
|
|
print 'Failures:\n ' + '\n '.join(failures)
|
|
|
|
def doCleanTal(directory):
|
|
for lang in ['en', 'fr']:
|
|
for root, dir, files in osWalk(directory):
|
|
files = [os.path.join(root, x) for x in files if \
|
|
x.endswith('.htmlc.%s' % lang) or \
|
|
x.endswith('.talc.%s' % lang) ]
|
|
for file in files:
|
|
os.remove(file)
|
|
|
|
def doUsage():
|
|
print """usage: %s [-v] (start|stop|make-help|make-system|export|import|convert-ids)""" % \
|
|
sys.argv[0]
|
|
print """
|
|
start start Glasnost servers
|
|
stop stop Glasnost servers
|
|
make-help $1 create glasnost://help from glasnost://$1
|
|
make-system $1 create glasnost://system from glasnost://$1
|
|
export $1 export glasnost://$1
|
|
import $1 import glasnost://$1
|
|
convert-ids $1 $2 convert ids from glasnost://$1 to glasnost://$2
|
|
compile-tal $1 compile TAL templates in directory $1 (and its leafs)
|
|
clean-tal $1 remove compiled TAL templates from directory $1
|
|
start-one $1 start Glasnost server named $1
|
|
stop-one $1 stop Glasnost server named $1
|
|
restart-one $1 restart Glasnost server named $1
|
|
start-missing start Glasnost servers defined but not running
|
|
logrotate send a signal to servers so that they reopen log files
|
|
|
|
-v verbose mode (if applicable)
|
|
"""
|
|
sys.exit(0)
|
|
|
|
if hasattr(os, 'walk'):
|
|
osWalk = os.walk
|
|
else:
|
|
# Python < 2.3.
|
|
# Directly copied from Python2.3 os.walk function, but without yield.
|
|
|
|
def osWalk(top, topdown=1, onerror=None):
|
|
"""Directory tree generator."""
|
|
|
|
paths = []
|
|
|
|
from os.path import join, isdir, islink
|
|
|
|
try:
|
|
names = os.listdir(top)
|
|
except os.error, err:
|
|
if onerror is not None:
|
|
onerror(err)
|
|
return
|
|
|
|
dirs, nondirs = [], []
|
|
for name in names:
|
|
if isdir(join(top, name)):
|
|
dirs.append(name)
|
|
else:
|
|
nondirs.append(name)
|
|
|
|
if topdown:
|
|
paths.append((top, dirs, nondirs))
|
|
for name in dirs:
|
|
path = join(top, name)
|
|
if not islink(path):
|
|
for x in osWalk(path, topdown, onerror):
|
|
paths.append(x)
|
|
if not topdown:
|
|
paths.append((top, dirs, nondirs))
|
|
return paths
|
|
|
|
|
|
if len(sys.argv) > 1 and sys.argv[1] == '-v':
|
|
verbose = 1
|
|
sys.argv = sys.argv[1:]
|
|
|
|
if len(sys.argv) == 1:
|
|
doUsage()
|
|
elif sys.argv[1] == 'start':
|
|
doStart()
|
|
elif sys.argv[1] == 'stop':
|
|
doStop()
|
|
elif sys.argv[1] == 'start-one':
|
|
doStartOne(sys.argv[2])
|
|
elif sys.argv[1] == 'stop-one':
|
|
doStopOne(sys.argv[2])
|
|
elif sys.argv[1] == 'restart-one':
|
|
doRestartOne(sys.argv[2])
|
|
elif sys.argv[1] == 'make-help':
|
|
doMakeHelp(sys.argv[2])
|
|
elif sys.argv[1] == 'make-system':
|
|
doMakeSystem(sys.argv[2])
|
|
elif sys.argv[1] == 'export':
|
|
doExport(sys.argv[2])
|
|
elif sys.argv[1] == 'import':
|
|
doImport(sys.argv[2])
|
|
elif sys.argv[1] == 'convert-ids':
|
|
doConvertIds(sys.argv[2], sys.argv[3])
|
|
elif sys.argv[1] == 'compile-tal':
|
|
doCompileTal(sys.argv[2])
|
|
elif sys.argv[1] == 'clean-tal':
|
|
doCleanTal(sys.argv[2])
|
|
elif sys.argv[1] == 'logrotate':
|
|
doLogRotate()
|
|
elif sys.argv[1] == 'start-missing':
|
|
doStartMissing()
|
|
else:
|
|
doUsage()
|
|
|