""" This is the Main Controller. It starts the server, shows splash screen and cleans up afterwards. MainController is imported and run by the 'pycocuma' executable script. """ # Copyright (C) 2004 Henning Jacobs # # 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. # # $Id: MainController.py 142 2005-09-13 21:16:23Z henning $ import Preferences import broker from __version__ import __version__ from MainModel import MainModel CMDLINE_HELP = """\ PyCoCuMa: Pythonic Contact and Customer Management version %s Usage: pycocuma [options] [connection-string] connection-string addressbook filename / server url -h or --help show this help -c or --config location of configuration file (default: ~/.pycocuma) --noconf do not save configuration / preferences -t or --type connection type: xmlrpc or file (default: file) --finder open QuickFinder --import import from file/stdin (-) (e.g. vcard:/tmp/John.vcf) --export export to file or stdout (e.g. latex:-) Examples: pycocuma --type=xmlrpc http://localhost:8810 pycocuma --config=/tmp/pycocumatest.conf --type=file ./addressbook.vcf pycocuma --import=csv:myaddresses.csv See homepage: http://www.srcco.de/pycocuma/""" % __version__ class MainController: def __init__(self, nogui=False, nouserpref=False): # Don't create any GUI-windows (e.g. MainView): self.nogui = nogui # Start QuickFinder only: self.startquickfinder = False # Do not load nor save preferences to ~/.pycocuma: self.nouserpref = nouserpref # import from this file self.importfile = None # export to this file self.exportfile = None optlist, args, preffile = self.parseCommandLineOptions() # Load Preferences: if not nouserpref: Preferences.Load(preffile) self.applyCommandLineOptions(optlist, args) # importing and exporting disables the GUI: if self.importfile or self.exportfile: self.nogui = True # Display Splash-Screen: self.splash = None if not self.nogui: from SplashScreen import SplashScreen # The Tk-Root will be created by SplashScreen: self.splash = SplashScreen() self.splash.show() import locale locale.setlocale(locale.LC_ALL, '') self.model = MainModel() if not self.nogui: tkroot = None if self.splash: tkroot = self.splash.tkroot if self.startquickfinder: from QuickFinder import QuickFinder self.view = view = QuickFinder(__version__, self.model, tkroot) else: from MainView import MainView self.view = view = MainView(__version__, self.model, tkroot) def parseCommandLineOptions(self): "Parse Command-Line Options" import getopt, sys try: optlist, args = getopt.getopt(sys.argv[1:], "c:ht:", ['help', 'config=', 'noconf', 'type=', 'finder', 'import=', 'export=']) except getopt.GetoptError, msg: print "ERROR: " + str(msg) self.showCommandLineHelp() preffile = None for key, val in optlist: if key == "-c" or key == "--config": preffile = val return (optlist, args, preffile) def applyCommandLineOptions(self, optlist, args): "Overwrite Preferences with command-line options" if len(args) >= 1: Preferences.set("client.connection_string", args[0]) Preferences.set("client.connection_type", 'file') for key, val in optlist: if key == "-h" or key == "--help": self.showCommandLineHelp() elif key == "--noconf": self.nouserpref = True elif key == "--finder": self.startquickfinder = True elif key == "--import": self.importfile = val elif key == "--export": self.exportfile = val # Command Line Arguments override Preferences: elif key == "-t" or key == "--type": Preferences.set("client.connection_type",val) def showCommandLineHelp(self): "Print Help Screen and Exit" import sys print CMDLINE_HELP sys.exit(0) def startServer(self): "start the XML-RPC Server" import os, sys # Where to look for the server executable: serverpaths = [ os.path.dirname(sys.argv[0])+'/pycocuma-server', 'pycocuma-server', 'CoCuMa_Server.py' ] for path in serverpaths: serverfilename = path if os.access(serverfilename, os.R_OK): break # Run our Server Daemon: os.spawnv(os.P_NOWAIT, sys.executable, [sys.executable, serverfilename, '-h', Preferences.get('server.listen_host'), '-p', Preferences.get('server.listen_port'), '-f', Preferences.get('server.addressbook_filename'), '-j', Preferences.get('server.calendar_filename') ]) def doImport(self, filename): "Import into model from file or stdin" import converters, sys, os parts = filename.split(':') if len(parts) > 1: # format specified (e.g. vcard or csv) srcformat = parts[0] filename = parts[1] else: # try to guess by file extension root, ext = os.path.splitext(filename) if ext == "csv": srcformat = ext else: srcformat = "vcard" if filename == "-": # use StdIn: fd = sys.stdin else: # read file: fd = file(filename, 'rb') try: converters.importvcards(self.model, srcformat, fd, 'utf-8') finally: fd.close() def doExport(self, filename): "Export from model to file or stdout" import converters, sys, os parts = filename.split(':') if len(parts) > 1: # format specified (e.g. vcard or csv) dstformat = parts[0] filename = parts[1] else: # try to guess by file extension root, ext = os.path.splitext(filename) if ext == "csv": dstformat = ext elif ext == "xml": dstformat = "xmlrdf" else: dstformat = "vcard" if filename == "-": # use StdOut: fd = sys.stdout else: # read file: fd = file(filename, 'wb') outfile = converters.EncodedFileWriter(fd, 'utf-8') try: converters.exportvcards(self.model, dstformat, outfile, 'utf-8') finally: fd.close() def Run(self): "Fire up the server and the client's main window" if Preferences.get("client.connection_type").lower() == "xmlrpc"\ and Preferences.get("client.autostart_server").lower() == "yes": self.startServer() if self.splash: self.splash.update("Connecting...") self.model.Open(Preferences.get('client.connection_type'), Preferences.get('client.connection_string')) if not self.nogui: if self.splash: self.splash.destroy() self.splash = None self.view.tkroot.mainloop() if self.importfile: self.doImport(self.importfile) if self.exportfile: self.doExport(self.exportfile) if self.model.isConnected(): Preferences.set('client.connection_type', broker.Request("Connection Type")) Preferences.set('client.connection_string', broker.Request("Connection String")) def CleanUp(self): "Close the connection to server and save user preferences" self.model.Close(final=1) if not self.nogui: self.view.tkroot.destroy() if not self.nouserpref: Preferences.Save()