#!/usr/bin/env python # -*- coding: iso-8859-15 -*- # Glasnost # By: Odile Bénassy # Romain Chantereau # Nicolas Clapiès # Pierre-Antoine Dejace # Thierry Dulieu # Florent Monnier # Cédric Musso # Frédéric Péters # Benjamin Poussin # Emmanuel Raviart # Sébastien Régnier # Emmanuel Saracco # # 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()