Module pisi
[hide private]
[frames] | no frames]

Source Code for Module pisi

  1  #!/usr/bin/env python 
  2   
  3  """ 
  4  Main module for PISI 
  5   
  6  This file is part of Pisi. 
  7   
  8  This file is the python module to be started for running PISI. 
  9  Initialization is performed in here: 
 10   - Loading and parsing of configuration from file 
 11   - Importing of modules (for data sources) 
 12   
 13  Pisi is free software: you can redistribute it and/or modify 
 14  it under the terms of the GNU General Public License as published by 
 15  the Free Software Foundation, either version 3 of the License, or 
 16  (at your option) any later version. 
 17   
 18  Pisi is distributed in the hope that it will be useful, 
 19  but WITHOUT ANY WARRANTY; without even the implied warranty of 
 20  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 21  GNU General Public License for more details. 
 22   
 23  You should have received a copy of the GNU General Public License 
 24  along with Pisi.  If not, see <http://www.gnu.org/licenses/>. 
 25  """ 
 26   
 27  import ConfigParser 
 28  import os 
 29  import os.path 
 30  import sys 
 31   
 32  from events import events,  eventsSync 
 33  from contacts import contactsSync 
 34  from pisiconstants import * 
 35  import pisiprogress 
 36   
37 -def getConfiguration():
38 """ 39 Returns the entire content of the configuration file 40 """ 41 # Read configuration 42 homedir = os.environ.get('HOME') 43 configfolder = homedir + '/.pisi/' 44 configfile = configfolder + 'conf' 45 if not os.path.isfile(configfile): 46 raise ValueError("Couldn't find the configuration file: "+configfile) 47 config = ConfigParser.ConfigParser() 48 config.readfp(open(configfile)) 49 return config
50
51 -def readConfiguration():
52 """ 53 Loads configuration from the configuration file and returns the container with all the information as well as the config folder 54 """ 55 configfolder = os.path.join(os.environ.get('HOME'), '.pisi') 56 configfile = os.path.join(configfolder, 'conf') 57 pisiprogress.getCallback().verbose("Reading configfile: %s" %(configfile) ) 58 if not os.path.isfile(configfile): 59 sys.exit("Couldn't find the configuration file: "+configfile) 60 config = ConfigParser.ConfigParser() 61 config.readfp(open(configfile)) 62 return config, configfolder
63
64 -def importModules(configfolder, config, modulesToLoad, modulesNamesCombined, soft):
65 """ 66 Imports the required modules for handling the specific data sources 67 68 The required modules had been determined by examining the chosen data sources. 69 The required modules are now imported. 70 """ 71 # Create folders for the modules to use to save stuff 72 modulesFolder = configfolder+modulesToLoad[0]+modulesToLoad[1]+'/' 73 if not os.path.exists(modulesFolder): 74 os.mkdir( modulesFolder ) 75 76 source = [] 77 for i in range(0,2): 78 modulename = config.get( modulesToLoad[i], 'module' ) 79 if not os.path.exists(modulesFolder + modulesToLoad[i]): 80 os.mkdir( modulesFolder + modulesToLoad[i] ) 81 exec "from modules import " + modulename + " as module"+i.__str__() 82 exec "source.append( module"+i.__str__()+".SynchronizationModule(modulesNamesCombined, config, modulesToLoad[i], modulesFolder+modulesToLoad[i]+'/', True, soft) )" 83 # Now we have source[0] and source[1] as our 2 synchronization modules 84 return source
85
86 -def determineMode(config, modulesToLoad):
87 """ 88 Check, what type of information we have to synchronize 89 90 Checks, whether the two modules (for the given data sources) are equal in type for data they can sync (contacts - contacts or calendar - calendar). 91 This is done by simply comparing the starting part of the module names (all stuff left from '_'); this is a naming convention. 92 E.g. contacts_ldap and contacts_sqlite3 would return 'CONTACTS' mode, whereby contacts_ldap and calendar_google would raise an error. 93 An error is thrown whenever the two sources do not match in type, or if a type is not known or unvalid.. 94 """ 95 modes = [None, None] 96 for j in range(0, 2): 97 modulename = config.get( modulesToLoad[j], 'module' ) 98 modeString = modulename[:modulename.index("_")] 99 for i in range (0, len(MODE_STRINGS)): 100 if MODE_STRINGS[i] == modeString: 101 modes[j] = i 102 if modes[j] == None: 103 raise ValueError ("Mode check: mode <%s> not known." %(modulesToLoad[j])) 104 if modes[0] != modes[1]: 105 raise ValueError("Mode check: Source 1 and 2 are not compatible.") 106 pisiprogress.getCallback().verbose("Running in mode <%s>." %(MODE_STRINGS[modes[0]])) 107 return modes[0]
108
109 -def applyChanges(source):
110 """ 111 Write changes through to data source backends 112 113 All changes in syncing are only performed in memory. This function finally requests the data sources to make their changes permanent by calling 114 the corresponding function in there. 115 """ 116 pisiprogress.getCallback().verbose("Making changes permanent") 117 pisiprogress.getCallback().progress.push(0, 50) 118 try: 119 source[0].saveModifications() 120 except ValueError, ex: 121 pisiprogress.getCallback().error("Changes to source 1 (%s) could not be applied due to the following reason: %s" %(source[0].getName(), ex)) 122 pisiprogress.getCallback().progress.drop() 123 pisiprogress.getCallback().progress.push(50, 100) 124 try: 125 source[1].saveModifications() 126 except ValueError, ex: 127 pisiprogress.getCallback().error ("Changes to source 2 (%s) could not be applied due to the following reason: %s" %(source[1].getName(), ex)) 128 pisiprogress.getCallback().progress.drop()
129 130
131 -def determineConflictDetails(entry1, entry2):
132 diffList = {} 133 for key, value in entry1.attributes.iteritems(): 134 try: 135 if value == None or value == '': 136 continue 137 if entry2.attributes[key] != value: 138 diffList[key] = 1 139 except KeyError: 140 diffList[key] = 1 141 for key, value in entry2.attributes.iteritems(): 142 try: 143 if value == None or value == '': 144 continue 145 if entry1.attributes[key] != value: 146 diffList[key] = 1 147 except KeyError: 148 diffList[key] = 1 149 return diffList
150 151 """ 152 This starts the CLI version of PISI 153 """ 154 if __name__ == "__main__": 155 import pisicli 156 pisicli.startCLI() 157