2 # -*- coding: utf-8 -*-
7 from SimpleXMLRPCServer import SimpleXMLRPCServer
10 socket.setdefaulttimeout(60) # Timeout auf 60 sec. setzen
23 class ProgressDialog(gtk.Dialog):
26 #self.progressbar.pulse()
29 def __init__(self,title="Sync process", parent=None):
30 gtk.Dialog.__init__(self,title,parent,gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,())
32 logging.info("ProgressDialog, init")
34 label=gtk.Label("Sync process running...please wait")
35 self.vbox.pack_start(label, True, True, 0)
36 label=gtk.Label("(this can take some minutes)")
37 self.vbox.pack_start(label, True, True, 0)
39 #self.progressbar=gtk.ProgressBar()
40 #self.vbox.pack_start(self.progressbar, True, True, 0)
42 #self.set_keep_above(True)
49 'syncFinished' : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE,(gobject.TYPE_STRING,)),
50 'syncBeforeStart' : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE,(gobject.TYPE_STRING,)),
53 def changeSyncStatus(self,active,title):
54 self.syncStatusLabel.set_text(title)
56 if self.progress==None:
57 self.progress=ProgressDialog(parent=self.parentwindow)
60 if self.progress!=None:
62 self.progress.destroy()
66 if self.progress!=None:
68 #if self.server!=None:
72 def getUeberblickBox(self):
73 frame=gtk.Frame("Abfrage")
78 if (self.rpcserver==None): return False
82 while (len(self.poll.poll(0))>0):
83 self.rpcserver.handle_request()
86 def get_ip_address(self,ifname):
87 return socket.gethostbyname(socket.gethostname())
89 # s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
90 # ip=socket.inet_ntoa(fcntl.ioctl(s.fileno(),0x8915,struct.pack('256s', ifname[:15]))[20:24])
93 # ip=socket.gethostbyname(socket.gethostname())
98 def getLastSyncDate(self,sync_uuid):
99 sql="SELECT syncpartner,pcdatum FROM sync WHERE uuid=?"
100 rows=self.db.ladeSQL(sql,(sync_uuid,))
101 if (rows!=None)and(len(rows)==1):
102 syncpartner,pcdatum = rows[0]
105 logging.info("LastSyncDatum: "+str(pcdatum)+" Jetzt "+str(int(time.time())))
109 def writeSQLTupel(self,newSQLs):
113 for newSQL in newSQLs:
115 #print "SQL1: ",newSQL[1]
116 #print "SQL2: ",newSQL[2]
117 #print "SQL3: ",newSQL[3]
118 #print "Param:",string.split(newSQL[3]," <<Tren-ner>> ")
121 param=string.split(newSQL[3]," <<Tren-ner>> ")
128 if (newSQL[5]!=None)and(len(newSQL[5])>0):
129 sql="SELECT * FROM logtable WHERE rowid=? ORDER BY pcdatum DESC"
130 rows=self.db.ladeSQL(sql,(newSQL[5],))
131 if (rows!=None)and(len(rows)>0):
132 if (rows[0][1]>newSQL[1])and(len(rows[0][5])>0):
133 logging.info("newer sync entry, ignoring old one")
134 print "newer sync entry, ignoring old one"
137 if (commitSQL==True):
138 self.db.speichereSQL(newSQL[2],param,commit=False,pcdatum=newSQL[1],rowid=newSQL[5])
140 logging.error("writeSQLTupel: Error")
143 if (pausenzaehler % 10)==0:
145 while (gtk.events_pending()):
146 gtk.main_iteration();
148 logging.info("Alle SQLs an sqlite geschickt, commiting now")
150 logging.info("Alle SQLs commited")
153 def doSync(self,sync_uuid,pcdatum,newSQLs,pcdatumjetzt):
154 #print uuid,pcdatum,newSQLs
155 self.changeSyncStatus(True,"sync process running")
158 while (gtk.events_pending()):
159 gtk.main_iteration();
160 diff=time.time()-pcdatumjetzt
166 sql="SELECT * FROM logtable WHERE pcdatum>?"
167 rows=self.db.ladeSQL(sql,(pcdatum,))
168 logging.info("doSync read sqls")
169 self.writeSQLTupel(newSQLs)
170 logging.info("doSync wrote "+str(len(newSQLs))+" sqls")
174 def getRemoteSyncUUID(self):
175 return self.sync_uuid
178 def startServer(self, widget, data=None):
180 self.db.speichereDirekt("syncServerIP",self.comboIP.get_child().get_text())
182 if (widget.get_active()==True):
183 logging.info("Starting Server")
186 ip=self.comboIP.get_child().get_text()
187 self.rpcserver = SimpleXMLRPCServer((ip, self.port),allow_none=True)
188 self.rpcserver.register_function(pow)
189 self.rpcserver.register_function(self.getLastSyncDate)
190 self.rpcserver.register_function(self.doSync)
191 self.rpcserver.register_function(self.getRemoteSyncUUID)
192 self.rpcserver.register_function(self.doSaveFinalTime)
193 self.rpcserver.register_function(self.pulse)
194 self.poll=select.poll()
195 self.poll.register(self.rpcserver.fileno())
196 gobject.timeout_add(1000, self.handleRPC)
197 self.syncServerStatusLabel.set_text("Syncserver running...")
200 self.db.speichereDirekt("startSyncServer",True)
202 s=str(sys.exc_info())
203 logging.error("libsync: could not start server. Error: "+s)
204 mbox=gtk.MessageDialog(None,gtk.DIALOG_MODAL,gtk.MESSAGE_ERROR,gtk.BUTTONS_OK,"Konnte Sync-Server nicht starten. Bitte IP und Port überprüfen.") #gtk.DIALOG_MODAL
205 mbox.set_modal(False)
209 widget.set_active(False)
212 logging.info("Stopping Server")
217 self.syncServerStatusLabel.set_text("Syncserver not running...")
219 self.db.speichereDirekt("startSyncServer",False)
221 def doSaveFinalTime(self,sync_uuid,pcdatum=None):
222 if (pcdatum==None): pcdatum=int(time.time())
223 if (time.time()>pcdatum):
224 pcdatum=int(time.time()) #größere Zeit nehmen
229 sql="DELETE FROM sync WHERE uuid=?"
230 self.db.speichereSQL(sql,(sync_uuid,),log=False)
231 sql="INSERT INTO sync (syncpartner,uuid,pcdatum) VALUES (?,?,?)"
232 self.db.speichereSQL(sql,("x",str(sync_uuid),pcdatum),log=False)
233 self.emit("syncFinished","syncFinished")
235 self.changeSyncStatus(False,"no sync process (at the moment)")
236 return (self.sync_uuid,pcdatum)
239 def syncButton(self, widget, data=None):
240 logging.info("Syncing")
241 #sql="DELETE FROM logtable WHERE sql LIKE externeStundenplanung"
242 #self.db.speichereSQL(sql)
244 self.changeSyncStatus(True,"sync process running")
245 while (gtk.events_pending()):
246 gtk.main_iteration();
247 self.emit("syncBeforeStart","syncBeforeStart")
249 self.db.speichereDirekt("syncRemoteIP",self.comboRemoteIP.get_child().get_text())
251 self.server = xmlrpclib.ServerProxy("http://"+self.comboRemoteIP.get_child().get_text()+":"+str(self.port),allow_none=True)
252 #lastDate=server.getLastSyncDate(str(self.sync_uuid))
253 server_sync_uuid=self.server.getRemoteSyncUUID()
254 lastDate=self.getLastSyncDate(str(server_sync_uuid))
256 print ("LastSyncDate: "+str(lastDate)+" Now: "+str(int(time.time())))
258 sql="SELECT * FROM logtable WHERE pcdatum>?"
259 rows=self.db.ladeSQL(sql,(lastDate,))
261 newSQLs=self.server.doSync(self.sync_uuid,lastDate,rows,time.time())
263 logging.info("did do sync, processing sqls now")
265 self.writeSQLTupel(newSQLs)
267 sync_uuid, finalpcdatum=self.server.doSaveFinalTime(self.sync_uuid)
268 self.doSaveFinalTime(sync_uuid, finalpcdatum)
270 self.changeSyncStatus(False,"no sync process (at the moment)")
272 mbox = gtk.MessageDialog(None,gtk.DIALOG_MODAL,gtk.MESSAGE_INFO,gtk.BUTTONS_OK,"Synchronisation erfolgreich beendet")
273 response = mbox.run()
277 logging.warning("Zeitdiff zu groß/oder anderer db-Fehler")
278 self.changeSyncStatus(False,"no sync process (at the moment)")
279 mbox = gtk.MessageDialog(None,gtk.DIALOG_MODAL,gtk.MESSAGE_INFO,gtk.BUTTONS_OK,"Zeit differiert zu viel zwischen den Systemen")
280 response = mbox.run()
283 self.emit("syncFinished","syncFinished")
286 logging.warning("Sync connect failed")
287 self.changeSyncStatus(False,"no sync process (at the moment)")
288 mbox = gtk.MessageDialog(None,gtk.DIALOG_MODAL,gtk.MESSAGE_INFO,gtk.BUTTONS_OK,"Sync gescheitert. Fehler:"+str(sys.exc_info()))
289 response = mbox.run()
293 self.emit("syncFinished","syncFinished")
299 def __init__(self,db,parentwindow,port):
300 gtk.VBox.__init__(self,homogeneous=False, spacing=0)
302 logging.info("Sync, init")
307 self.parentwindow=parentwindow
310 #sql = "DROP TABLE sync"
311 #self.db.speichereSQL(sql,log=False)
313 sql = "CREATE TABLE sync (id INTEGER PRIMARY KEY, syncpartner TEXT, uuid TEXT, pcdatum INTEGER)"
314 self.db.speichereSQL(sql,log=False)
318 sql="SELECT uuid,pcdatum FROM sync WHERE syncpartner=?"
319 rows=self.db.ladeSQL(sql,("self",)) #Eigene Id feststellen
322 if (rows==None)or(len(rows)!=1):
323 sql="DELETE FROM sync WHERE syncpartner=?"
324 self.db.speichereSQL(sql,("self",),log=False)
329 self.sync_uuid=str(uuid.uuid4())
330 sql="INSERT INTO sync (syncpartner,uuid,pcdatum) VALUES (?,?,?)"
331 self.db.speichereSQL(sql,("self",str(self.sync_uuid),int(time.time())),log=False)
334 sync_uuid,pcdatum = rows[0]
335 self.sync_uuid=sync_uuid
343 frame=gtk.Frame("LokalerSync-Server (Port "+str(self.port)+")")
347 self.comboIP=gtk.combo_box_entry_new_text()
350 self.comboIP.append_text("") #self.get_ip_address("eth0"))
351 #self.comboIP.append_text(self.get_ip_address("eth1")) #fixme
352 #self.comboIP.append_text(self.get_ip_address("eth2"))
353 #self.comboIP.append_text(self.get_ip_address("eth3"))
355 #self.comboIP.append_text(self.get_ip_address("wlan0"))
356 #self.comboIP.append_text(self.get_ip_address("wlan1"))
360 frame.add(self.comboIP)
361 serverbutton=gtk.ToggleButton("SyncServer starten")
362 serverbutton.connect("clicked",self.startServer,(None,))
363 self.pack_start(frame, expand=False, fill=True, padding=1)
364 self.pack_start(serverbutton, expand=False, fill=True, padding=1)
365 self.syncServerStatusLabel=gtk.Label("Syncserver not running")
366 self.pack_start(self.syncServerStatusLabel, expand=False, fill=True, padding=1)
368 frame=gtk.Frame("RemoteSync-Server (Port "+str(self.port)+")")
369 self.comboRemoteIP=gtk.combo_box_entry_new_text()
370 self.comboRemoteIP.append_text("192.168.0.?")
371 self.comboRemoteIP.append_text("192.168.1.?")
372 self.comboRemoteIP.append_text("192.168.176.?")
373 frame.add(self.comboRemoteIP)
374 syncbutton=gtk.Button("Verbinde zu Remote-SyncServer")
375 syncbutton.connect("clicked",self.syncButton,(None,))
376 self.pack_start(frame, expand=False, fill=True, padding=1)
377 self.pack_start(syncbutton, expand=False, fill=True, padding=1)
378 self.syncStatusLabel=gtk.Label("no sync process (at the moment)")
379 self.pack_start(self.syncStatusLabel, expand=False, fill=True, padding=1)
382 #self.comboRemoteIP.set_text_column("Test")
383 self.comboRemoteIP.get_child().set_text(self.db.ladeDirekt("syncRemoteIP"))
384 self.comboIP.get_child().set_text(self.db.ladeDirekt("syncServerIP"))
387 if (self.db.ladeDirekt("startSyncServer",False)==True):
388 serverbutton.set_active(True)