[Tkabber-dev] r1357 - branches/xml-import-export/plugins/roster

tkabber-svn at jabber.ru tkabber-svn at jabber.ru
Tue Jan 29 18:18:23 MSK 2008


Author: kostix
Date: 2008-01-29 18:18:22 +0300 (Tue, 29 Jan 2008)
New Revision: 1357

Added:
   branches/xml-import-export/plugins/roster/bkup_annotations.tcl
Modified:
   branches/xml-import-export/plugins/roster/annotations.tcl
Log:
plugins/roster/bkup_annotations.tcl: Added new roster plugin implementing
 backup/restore for "Annotations" (XEP-0145).

plugins/roster/annotations.tcl: Several changes to make this plugin
 more usable for bkup_annotations.tcl:
 * Creation of xmldata in [store_notes] moved to separate proc [serialize_notes].
 * Code processing one annotation sent by the server moved from [process_note]
   to the separate proc [create_note]. This new proc also accepts one
   optional agrument -merge which can be used to request conditional
   insetion of the node -- only if it's more recent that the existing one
   for the same JID, if any.
 * Implemented [more_recent] proc to help merging notes in [create_note].


Modified: branches/xml-import-export/plugins/roster/annotations.tcl
===================================================================
--- branches/xml-import-export/plugins/roster/annotations.tcl	2008-01-29 01:40:06 UTC (rev 1356)
+++ branches/xml-import-export/plugins/roster/annotations.tcl	2008-01-29 15:18:22 UTC (rev 1357)
@@ -35,30 +35,56 @@
 
     if {$res != "OK"} return
 
-    array set notes {}
+    array unset notes *
+    foreach xmldata $child {
+	jlib::wrapper:splitxml $xmldata tag vars isempty cdata children
 
-    foreach ch $child {
-	jlib::wrapper:splitxml $ch tag1 vars1 isempty1 cdata1 children1
+	if {[jlib::wrapper:getattr $vars xmlns] == $::NS(rosternotes)} {
+	    foreach note $children {
+		create_note $connid $note
+	    }
+	}
+    }
+}
 
-	if {[jlib::wrapper:getattr $vars1 xmlns] == $::NS(rosternotes)} {
-	    foreach note $children1 {
-		jlib::wrapper:splitxml $note ntag nvars nisempty ncdata nchildren
+proc annotations::create_note {connid xmldata args} {
+    variable notes
 
-		set jid [jlib::wrapper:getattr $nvars jid]
-		set cdate [jlib::wrapper:getattr $nvars cdate]
-		set mdate [jlib::wrapper:getattr $nvars mdate]
-		set notes($connid,jid,$jid) $jid
-		if {![catch { scan_time $cdate } cdate]} {
-		    set notes($connid,cdate,$jid) $cdate
-		}
-		if {![catch { scan_time $mdate } mdate]} {
-		    set notes($connid,mdate,$jid) $mdate
-		}
-		set notes($connid,note,$jid) $ncdata
-	    
+    set merge 0
+    foreach {opt val} $args {
+	switch -- $opt {
+	    -merge { set merge $val }
+	    default {
+		return -code error "Bad option \"$opt\":\
+		    must be -merge"
 	    }
 	}
     }
+
+    jlib::wrapper:splitxml $xmldata tag vars isempty cdata children
+
+    set jid [jlib::wrapper:getattr $vars jid]
+    set cdate [jlib::wrapper:getattr $vars cdate]
+    set mdate [jlib::wrapper:getattr $vars mdate]
+
+    if {![catch { scan_time $cdate } cdate]} {
+	set cdate [clock seconds]
+    }
+    if {![catch { scan_time $mdate } mdate]} {
+	set cdate [clock seconds]
+    }
+
+    puts "merge? $merge; $jid, $cdate, $mdate"
+
+    if {!$merge || [more_recent $connid $jid $cdate $mdate]} {
+	set notes($connid,jid,$jid)   $jid
+	set notes($connid,cdate,$jid) $cdate
+	set notes($connid,mdate,$jid) $mdate
+	set notes($connid,note,$jid)  $cdata
+	return 1
+    } else {
+	return 0
+    }
 }
 
 proc annotations::scan_time {timestamp} {
@@ -69,6 +95,18 @@
     }
 }
 
+proc annotations::more_recent {connid jid cdate mdate} {
+    variable notes
+
+    if {![info exists notes($connid,jid,$jid)]} {
+	return 1
+    } elseif {[info exists notes($connid,mdate,$jid)]} {
+	return [expr {$mdate > $notes($connid,mdate,$jid)}]
+    } elseif {[info exists notes($connid,cdate,$jid)]} {
+	return [expr {$cdate > $notes($connid,cdate,$jid)}]
+    }
+}
+
 proc annotations::cleanup_and_store_notes {connid} {
     variable notes
 
@@ -92,7 +130,7 @@
     store_notes $connid
 }
 
-proc annotations::store_notes {connid} {
+proc annotations::serialize_notes {connid} {
     variable notes
 
     set notelist {}
@@ -119,9 +157,13 @@
 	}
     }
 
-    private::store [list [jlib::wrapper:createtag storage \
-			      -vars [list xmlns $::NS(rosternotes)] \
-			      -subtags $notelist]] \
+    jlib::wrapper:createtag storage \
+	-vars [list xmlns $::NS(rosternotes)] \
+	-subtags $notelist
+}
+
+proc annotations::store_notes {connid} {
+    private::store [list [serialize_notes $connid]] \
 	-command [list [namespace current]::store_notes_result $connid] \
 	-connection $connid
 }
@@ -303,3 +345,4 @@
 
 hook::add userinfo_hook [namespace current]::annotations::note_page 40
 
+# vim:ts=8:sw=4:sts=4:noet

Added: branches/xml-import-export/plugins/roster/bkup_annotations.tcl
===================================================================
--- branches/xml-import-export/plugins/roster/bkup_annotations.tcl	                        (rev 0)
+++ branches/xml-import-export/plugins/roster/bkup_annotations.tcl	2008-01-29 15:18:22 UTC (rev 1357)
@@ -0,0 +1,62 @@
+# $Id$
+# Support for backup/restore of "annotations" (XEP-0145)
+# for roster items.
+# Depends on: annotations.tcl, backup.tcl
+
+namespace eval annobakup {
+    # Should probably go after the roster contacts, so we set prio to 60:
+    hook::add serialize_roster_hook \
+	[namespace current]::serialize_annotations 60
+    hook::add deserialize_roster_hook \
+	[namespace current]::deserialize_annotations 60
+}
+
+###############################################################################
+
+proc annobakup::serialize_annotations {connid level varName} {
+    upvar $level $varName subtags
+    global NS
+
+    set xmldata [::plugins::annotations::serialize_notes $connid]
+
+    lappend subtags [jlib::wrapper:createtag privstorage \
+	-vars {xmlns jabber:iq:private} \
+	-subtags [list $xmldata]]
+}
+
+###############################################################################
+
+proc annobakup::deserialize_annotations {connid data} {
+    global NS
+
+    jlib::wrapper:splitxml $data tag vars isempty cdata children
+    if {![string equal $tag privstorage]} return
+    set xmlns [jlib::wrapper:getattr $vars xmlns]
+    if {![string equal $xmlns $NS(private)]} {
+	return -code error "Bad roster element namespace \"$xmlns\":\
+	    must be \"$NS(private)\""
+    }
+
+    set updated 0
+
+    foreach storage $children {
+	jlib::wrapper:splitxml $storage ctag cvars cisempty ccdata cchildren
+	if {![string equal $ctag storage]} return
+	set xmlns [jlib::wrapper:getattr $cvars xmlns]
+	if {![string equal $xmlns $NS(rosternotes)]} return
+	
+	foreach child $cchildren {
+	    set added [::plugins::annotations::create_note \
+		    $connid $child -merge yes]
+	    set updated [expr {$updated || $added}]
+	}
+    }
+
+    puts "updated? $updated"
+
+    if {$updated} {
+	::plugins::annotations::cleanup_and_store_notes $connid
+    }
+}
+
+# vim:ts=8:sw=4:sts=4:noet


Property changes on: branches/xml-import-export/plugins/roster/bkup_annotations.tcl
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native



More information about the Tkabber-dev mailing list