1# $Id$ 2 3if {![cequal $::interface tk]} return 4 5package require base64 6package require sha1 7 8namespace eval ::avatar { 9 set options(announce) 0 10 set options(share) 0 11} 12 13############################################################################## 14 15proc ::avatar::setup_menu {} { 16 catch { 17 #set m [.mainframe getmenu services] 18 #for {set ind [$m index end]} {$ind > 0} {incr ind -1} { 19 # if {[$m type $ind] == "separator"} { 20 # break 21 # } 22 #} 23 set m [.mainframe getmenu plugins] 24 25 set mm .avatar_menu 26 menu $mm -tearoff $ifacetk::options(show_tearoffs) 27 $mm add checkbutton -label [::msgcat::mc "Announce"] \ 28 -variable avatar::options(announce) 29 $mm add checkbutton -label [::msgcat::mc "Allow downloading"] \ 30 -variable avatar::options(share) 31 $mm add command -label [::msgcat::mc "Send to server"] \ 32 -command {avatar::store_on_server} 33 34 $m add cascade -label [::msgcat::mc "Avatar"] \ 35 -menu $mm 36 } 37} 38 39hook::add finload_hook ::avatar::setup_menu 40 41############################################################################## 42 43proc ::avatar::load_file {filename} { 44 variable avatar 45 variable options 46 47 image create photo user_avatar -file $filename 48 set f [open $filename] 49 fconfigure $f -translation binary 50 set data [read $f] 51 close $f 52 53 set avatar(userhash) [sha1::sha1 $data] 54 set avatar(userdata) [base64::encode $data] 55 56 set options(announce) 1 57 set options(share) 1 58} 59 60############################################################################## 61 62proc ::avatar::get_presence_x {varname xlib status} { 63 variable avatar 64 variable options 65 upvar 2 $varname var 66 67 if {$options(announce) && [info exists avatar(userhash)]} { 68 lappend var [::xmpp::xml::create x \ 69 -xmlns $::NS(xavatar) \ 70 -subelement [::xmpp::xml::create hash \ 71 -cdata $avatar(userhash)]] 72 73 } 74 return 75} 76 77hook::add presence_xlist_hook ::avatar::get_presence_x 78 79############################################################################## 80 81proc ::avatar::process_presence {xlib from type x args} { 82 switch -- $type { 83 available - 84 unavailable { 85 foreach xs $x { 86 ::xmpp::xml::split $xs tag xmlns attrs cdata subels 87 if {$xmlns == $::NS(xavatar)} { 88 set_hash $xlib $from $subels 89 break 90 } 91 } 92 } 93 } 94} 95 96hook::add client_presence_hook ::avatar::process_presence 97 98############################################################################## 99 100proc ::avatar::insert_userinfo {tab xlib jid editable} { 101 if {$editable} return 102 103 set avatar_img [get_image $xlib [get_jid_of_user $xlib $jid]] 104 if {$avatar_img != ""} { 105 set avatar [$tab insert end avatar -text [::msgcat::mc "Avatar"]] 106 107 set av [userinfo::pack_frame $avatar.avatar [::msgcat::mc "Avatar"]] 108 label $av.a -image $avatar_img 109 pack $av.a -expand yes -fill both 110 } 111} 112 113hook::add userinfo_hook ::avatar::insert_userinfo 40 114 115############################################################################## 116 117proc ::avatar::set_hash {xlib jid children} { 118 variable avatar 119 120 debugmsg avatar "set hash $xlib $jid $children" 121 foreach child $children { 122 ::xmpp::xml::split $child tag xmlns attrs cdata subels 123 if {$tag == "hash"} { 124 set hash $cdata 125 } 126 } 127 if {[info exists hash]} { 128 if {![info exists avatar(hash,$xlib,$jid)] || \ 129 $hash != $avatar(hash,$xlib,$jid)} { 130 set avatar(hash,$xlib,$jid) $hash 131 set avatar(needupdate,$xlib,$jid) 1 132 } 133 } 134} 135 136############################################################################## 137 138proc ::avatar::get_image {xlib jid} { 139 variable avatar 140 141 debugmsg avatar "$jid; [array name avatar]" 142 if {[info exists avatar(hash,$xlib,$jid)]} { 143 if {![info exists avatar(data,$xlib,$jid)]} { 144 image create photo avatar$xlib@$jid 145 get $xlib $jid 146 } elseif {$avatar(needupdate,$xlib,$jid)} { 147 get $xlib $jid 148 } 149 return avatar$xlib@$jid 150 } else { 151 return "" 152 } 153} 154 155############################################################################## 156 157proc ::avatar::get {xlib jid} { 158 variable avatar 159 160 set avatar(needupdate,$xlib,$jid) 0 161 162 ::xmpp::sendIQ $xlib get \ 163 -query [::xmpp::xml::create query \ 164 -xmlns $::NS(iqavatar)] \ 165 -to $jid -command [list avatar::recv $xlib $jid] 166} 167 168proc ::avatar::recv {xlib jid res child} { 169 variable avatar 170 171 if {![string equal $res ok]} { 172 ::xmpp::sendIQ $xlib get \ 173 -query [::xmpp::xml::create query \ 174 -xmlns storage:client:avatar] \ 175 -to [::xmpp::jid::stripResource $jid] \ 176 -command [list avatar::recv_from_serv $xlib $jid] 177 178 return 179 } 180 181 ::xmpp::xml::split $child tag xmlns attrs cdata subels 182 foreach subel $subels { 183 ::xmpp::xml::split $subel stag sxmlns sattrs scdata ssubels 184 if {$stag == "data"} { 185 catch { 186 set avatar(data,$xlib,$jid) [base64::decode $scdata] 187 avatar$xlib@$jid put $scdata 188 } 189 } 190 } 191} 192 193proc ::avatar::recv_from_serv {xlib jid res child} { 194 variable avatar 195 196 if {![string equal $res ok]} { 197 # TODO 198 return 199 } 200 201 ::xmpp::xml::split $child tag xmlns attrs cdata subels 202 foreach subel $subels { 203 ::xmpp::xml::split $subel stag sxmlns sattrs scdata ssubels 204 if {$stag == "data"} { 205 catch { 206 set avatar(data,$xlib,$jid) [base64::decode $scdata] 207 avatar$xlib@$jid put $scdata 208 } 209 } 210 } 211} 212 213############################################################################## 214 215proc ::avatar::store_on_server {{xlib ""}} { 216 variable avatar 217 218 if {[llength [connections]] == 0} return 219 220 if {$xlib == ""} { 221 set xlib [lindex [connections] 0] 222 } 223 224 if {![info exists avatar(userdata)]} { 225 MessageDlg .avatar_error -aspect 50000 -icon error \ 226 -message [::msgcat::mc "No avatar to store"] -type user \ 227 -buttons ok -default 0 -cancel 0 228 return 229 } 230 231 ::xmpp::sendIQ $xlib set \ 232 -query [::xmpp::xml::create query \ 233 -xmlns storage:client:avatar \ 234 -subelement [::xmpp::xml::create data \ 235 -cdata $avatar(userdata)]] 236} 237 238############################################################################## 239 240proc ::avatar::iq_reply {xlib from child args} { 241 variable avatar 242 variable options 243 244 if {$options(share) && [info exists avatar(userdata)]} { 245 set res [::xmpp::xml::create query \ 246 -xmlns $::NS(iqavatar) \ 247 -subelement [::xmpp::xml::create data \ 248 -cdata $avatar(userdata)]] 249 return [list result $res] 250 } else { 251 return [list error cancel service-unavailable] 252 } 253} 254 255::xmpp::iq::register get query $::NS(iqavatar) ::avatar::iq_reply 256 257############################################################################## 258 259