Package modules :: Module contacts_syncml
[hide private]
[frames] | no frames]

Source Code for Module modules.contacts_syncml

  1  """  
  2  Syncronize with SyncML 
  3   
  4  This file is part of Pisi. This implementation is based on the Conduit branch of John Carr (http://git.gnome.org/cgit/conduit/log/?h=syncml), 
  5  which was one of the very first Python Syncml implementation - based on a ctime binding to the libsyncml library (https://libsyncml.opensync.org/). 
  6  The bindings were kept as found there - but I changed a lot the SyncModule file - in order to keep it as simple as possible. 
  7  Go and check L{thirdparty.conduit.SyncmlModule} for some more details. 
  8   
  9  Pisi is free software: you can redistribute it and/or modify 
 10  it under the terms of the GNU General Public License as published by 
 11  the Free Software Foundation, either version 3 of the License, or 
 12  (at your option) any later version. 
 13   
 14  Pisi is distributed in the hope that it will be useful, 
 15  but WITHOUT ANY WARRANTY; without even the implied warranty of 
 16  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 17  GNU General Public License for more details. 
 18   
 19  You should have received a copy of the GNU General Public License 
 20  along with Pisi.  If not, see <http://www.gnu.org/licenses/> 
 21   
 22  """ 
 23   
 24  import os.path 
 25  import sys,os,re 
 26  import vobject 
 27   
 28  # Allows us to import contact 
 29  sys.path.insert(0,os.path.abspath(__file__+"/../..")) 
 30  from contacts import contacts 
 31  from pisiconstants import * 
 32  import vobjecttools 
 33  import pisiprogress 
 34  import thirdparty.conduit.SyncmlModule as SyncmlModule 
 35   
 36  SYNCMLSERVER_IDENTIFIER = "pisi" 
 37  """What app name to use when connecting to Syncml server""" 
 38   
39 -class SynchronizationModule(contacts.AbstractContactSynchronizationModule):
40 """ 41 The implementation of the interface L{contacts.AbstractContactSynchronizationModule} for SyncML server connectivity 42 """
43 - def __init__( self, modulesString, config, configsection, folder, verbose=False, soft=False):
44 """ 45 Constructor 46 47 Super class constructor (L{contacts.AbstractContactSynchronizationModule.__init__}) is called. 48 Local variables are initialized. 49 """ 50 contacts.AbstractContactSynchronizationModule.__init__(self, verbose, soft, modulesString, config, configsection, "SyncML") 51 pisiprogress.getCallback().verbose('contact syncml module loaded') 52 self._url = config.get(configsection,'url') 53 self._username = config.get(configsection,'username') 54 self._password = config.get(configsection,'password') 55 self._database = config.get(configsection,'database') 56 self._mapping = {}
57
58 - def load(self):
59 """ 60 Loads all attributes for all contact entries from the SyncML backend 61 62 For each entry a new L{contacts.contacts.Contact} instance is created and stored in the instance dictionary L{contacts.AbstractContactSynchronizationModule._allContacts}. 63 For data parsing (VCF) the tools layer in L{vobjecttools} is used. 64 """ 65 pisiprogress.getCallback().progress.push(0, 100) 66 pisiprogress.getCallback().verbose("SyncML: Loading") 67 if_contacts = SyncmlModule.SyncmlContactsInterface(self._url, self._username, self._password, self._database, SYNCMLSERVER_IDENTIFIER) 68 contacts_raw = if_contacts.downloadItems() # load 69 if_contacts.finish() 70 pisiprogress.getCallback().progress.setProgress(20) 71 pisiprogress.getCallback().update("Loading") 72 73 i = 0 74 for x in contacts_raw.keys(): 75 content = vobject.readComponents(contacts_raw[x]) 76 for y in content: 77 atts = vobjecttools.extractVcfEntry(y) 78 id = contacts.assembleID(atts) 79 c = contacts.Contact(id, atts) 80 self._allContacts[id] = c 81 self._mapping[id] = x 82 i += 1 83 pisiprogress.getCallback().progress.setProgress(20 + ((i*80) / len(contacts_raw))) 84 pisiprogress.getCallback().update('Loading') 85 86 pisiprogress.getCallback().progress.drop()
87
88 - def saveModifications(self):
89 """ 90 Save whatever changes have come by 91 92 The history of actions for this data source is iterated. For each item in there the corresponding action is carried out on the item in question. 93 For data assembling (VCF) the tools layer in L{vobjecttools} is used. 94 """ 95 pisiprogress.getCallback().verbose("SyncML module: I apply %d changes now" %(len(self._history))) 96 if_contacts = SyncmlModule.SyncmlContactsInterface(self._url, self._username, self._password, self._database, SYNCMLSERVER_IDENTIFIER) 97 98 mods = {} 99 dels = {} 100 adds = {} 101 102 i=0 103 for listItem in self._history: 104 action = listItem[0] 105 id = listItem[1] 106 if action == ACTIONID_ADD: 107 pisiprogress.getCallback().verbose( "\t\t<syncml> adding %s" %(id)) 108 c = self.getContact(id) 109 vcard = vobjecttools.createRawVcard(c) 110 adds[str(i)] = vcard.serialize() 111 elif action == ACTIONID_DELETE: 112 pisiprogress.getCallback().verbose("\t\t<syncml> deleting %s" %(id)) 113 syncml_id = self._mapping[id] 114 dels[syncml_id] = "" 115 elif action == ACTIONID_MODIFY: 116 pisiprogress.getCallback().verbose("\t\t<syncml> replacing %s" %(id)) 117 c = self.getContact(id) 118 syncml_id = self._mapping[id] 119 vcard = vobjecttools.createRawVcard(c) 120 # mods[syncml_id] = vcard.serialize() # causing problems - no proper replacement 121 dels[syncml_id] = "" 122 adds[str(i)] = vcard.serialize() 123 i+=1 124 pisiprogress.getCallback().progress.setProgress(i * 90 / len(self._history)) 125 pisiprogress.getCallback().update('Storing') 126 127 if_contacts.applyChanges(mods = mods, dels = dels, adds = adds) 128 if_contacts.finish() 129 pisiprogress.getCallback().progress.setProgress(100) 130 pisiprogress.getCallback().update('Storing')
131