4 // Copyright (C) 2004 Matthew Jones <mattharrison sbcglobal net>
8 // Permission is hereby granted, free of charge, to any person obtaining a copy
9 // of this software and associated documentation files (the "Software"), to deal
10 // in the Software without restriction, including without limitation the rights
11 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 // copies of the Software, and to permit persons to whom the Software is
13 // furnished to do so, subject to the following conditions:
15 // The above copyright notice and this permission notice shall be included in all
16 // copies or substantial portions of the Software.
18 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
28 using System
.Collections
;
32 namespace Beagle
.Util
{
34 public class ImBuddy
{
35 public string Protocol
= "";
36 public string OwnerAccountName
= "";
37 public string BuddyAccountName
= "";
38 public string Alias
= "";
39 public string BuddyIconLocation
= "";
40 public string BuddyIconChecksum
= "";
42 public ImBuddy (string protocol
, string owneraccount
, string buddyaccount
, string alias, string iconlocation
, string iconchecksum
) {
44 OwnerAccountName
= owneraccount
;
45 BuddyAccountName
= buddyaccount
;
47 BuddyIconLocation
= iconlocation
;
48 BuddyIconChecksum
= iconchecksum
;
52 ///////////////////////////////////////////////////////////////////////////////
54 public abstract class ImBuddyListReader
{
56 public bool verbose
= false;
58 public Hashtable buddyList
= new Hashtable ();
60 abstract public void Read ();
62 public void DebugPrint (string str
) {
65 Logger
.Log
.Debug ("{0}", str
);
70 public class GaimBuddyListReader
: ImBuddyListReader
{
74 DateTime buddyListLastWriteTime
;
77 public GaimBuddyListReader ()
79 string home
= Environment
.GetEnvironmentVariable ("HOME");
80 buddyListDir
= Path
.Combine (home
, ".gaim");
81 buddyListPath
= Path
.Combine (buddyListDir
, "blist.xml");
83 if (File
.Exists (buddyListPath
))
86 // Poll the file once every minute
87 timeoutId
= GLib
.Timeout
.Add (60000, new GLib
.TimeoutHandler (ReadTimeoutHandler
));
90 ~
GaimBuddyListReader ()
93 GLib
.Source
.Remove (timeoutId
);
96 private bool ReadTimeoutHandler ()
98 if (File
.Exists (buddyListPath
))
104 private string Format (string name
) {
105 return name
.ToLower ().Replace (" ", "");
108 override public void Read ()
110 // If the file hasn't changed, don't do anything.
111 DateTime last_write
= File
.GetLastWriteTime (buddyListPath
);
112 if (last_write
== buddyListLastWriteTime
)
115 buddyListLastWriteTime
= last_write
;
117 buddyList
= new Hashtable ();
120 XmlDocument accounts
= new XmlDocument ();
121 accounts
.Load (buddyListPath
);
123 XmlNodeList contacts
= accounts
.SelectNodes ("//contact");
125 foreach (XmlNode contact
in contacts
) {
126 string groupalias
= "";
128 foreach (XmlAttribute attr
in contact
.Attributes
) {
129 if (attr
.Name
== "alias") {
130 groupalias
= attr
.Value
;
134 if (groupalias
!= "") {
135 foreach (XmlNode buddy
in contact
.ChildNodes
) {
136 AddBuddy (buddy
, groupalias
);
141 foreach (XmlNode buddy
in accounts
.SelectNodes ("//contact[not(@name)]/buddy")) {
144 } catch (Exception ex
) {
145 Logger
.Log
.Error (ex
, "Caught exception while trying to parse Gaim contact list:");
149 private void AddBuddy (XmlNode buddy
, string groupalias
)
151 string protocol
, owner
, other
, alias, iconlocation
, iconchecksum
;
160 foreach (XmlAttribute attr
in buddy
.Attributes
) {
164 DebugPrint ("owner: " + owner
);
167 protocol
= attr
.Value
;
168 DebugPrint ("protocol: " + protocol
);
173 foreach (XmlNode attr
in buddy
.ChildNodes
) {
174 switch (attr
.LocalName
) {
176 other
= attr
.InnerText
;
177 DebugPrint ("other: " + other
);
180 alias = attr
.InnerText
;
181 DebugPrint ("alias: " + alias);
184 foreach (XmlAttribute subattr
in attr
.Attributes
) {
185 if (subattr
.Name
== "name" && subattr
.Value
== "buddy_icon")
187 iconlocation
= attr
.InnerText
;
188 DebugPrint ("iconlocation: " + iconlocation
);
190 else if ( subattr
.Name
== "name" && subattr
.Value
== "icon_checksum")
192 iconchecksum
= attr
.InnerText
;
193 DebugPrint ("iconchecksum: " + iconchecksum
);
204 if (buddyList
.ContainsKey (Format(other
))) {
205 old
= (ImBuddy
)buddyList
[Format(other
)];
206 if (old
.Alias
== "" && alias != "")
208 if (old
.BuddyIconLocation
== "" && iconlocation
== "") {
209 old
.BuddyIconLocation
= iconlocation
;
210 old
.BuddyIconChecksum
= iconchecksum
;
212 buddyList
.Remove (Format(other
));
213 buddyList
.Add (Format(other
), old
);
216 buddyList
.Add (Format(other
), new ImBuddy (protocol
, owner
, Format(other
), alias, iconlocation
, iconchecksum
));
219 private void AddBuddy (XmlNode buddy
)
221 string protocol
, owner
, other
, alias, iconlocation
, iconchecksum
;
230 foreach (XmlAttribute attr
in buddy
.Attributes
) {
234 DebugPrint ("owner: " + owner
);
237 protocol
= attr
.Value
;
238 DebugPrint ("protocol: " + protocol
);
243 foreach (XmlNode attr
in buddy
.ChildNodes
) {
244 switch (attr
.LocalName
) {
246 other
= attr
.InnerText
;
247 DebugPrint ("other: " + other
);
250 alias = attr
.InnerText
;
251 DebugPrint ("alias: " + alias);
254 foreach (XmlAttribute subattr
in attr
.Attributes
) {
255 if (subattr
.Name
== "name" && subattr
.Value
== "buddy_icon")
257 iconlocation
= attr
.InnerText
;
258 DebugPrint ("iconlocation: " + iconlocation
);
260 else if ( subattr
.Name
== "name" && subattr
.Value
== "icon_checksum")
262 iconchecksum
= attr
.InnerText
;
263 DebugPrint ("iconchecksum: " + iconchecksum
);
272 if (buddyList
.ContainsKey (Format(other
))) {
273 old
= (ImBuddy
)buddyList
[Format(other
)];
274 if (old
.Alias
== "" && alias != "")
276 if (old
.BuddyIconLocation
== "" && iconlocation
== "") {
277 old
.BuddyIconLocation
= iconlocation
;
278 old
.BuddyIconChecksum
= iconchecksum
;
280 buddyList
.Remove (Format(other
));
281 buddyList
.Add (Format(other
), old
);
284 buddyList
.Add (Format(other
), new ImBuddy (protocol
, owner
, Format(other
), alias, iconlocation
, iconchecksum
));
288 public ImBuddy
Search (string buddy
) {
289 return (ImBuddy
)buddyList
[Format(buddy
)];
294 /////////////////////////////////////////////////////////////
296 public class KopeteBuddyListReader
: ImBuddyListReader
{
298 string buddyListPath
;
300 DateTime buddyListLastWriteTime
;
303 public KopeteBuddyListReader ()
305 buddyListDir
= Path
.Combine (PathFinder
.HomeDir
, ".kde/share/apps/kopete");
306 buddyListPath
= Path
.Combine (buddyListDir
, "contactlist.xml");
308 if (File
.Exists (buddyListPath
))
311 // Poll the file once every minute
312 timeoutId
= GLib
.Timeout
.Add (60000, new GLib
.TimeoutHandler (ReadTimeoutHandler
));
315 ~
KopeteBuddyListReader ()
318 GLib
.Source
.Remove (timeoutId
);
321 private bool ReadTimeoutHandler ()
323 if (File
.Exists (buddyListPath
))
329 private string Format (string name
) {
330 return name
.ToLower ().Replace (" ", "");
333 override public void Read ()
335 // If the file hasn't changed, don't do anything.
336 DateTime last_write
= File
.GetLastWriteTime (buddyListPath
);
337 if (last_write
== buddyListLastWriteTime
)
340 buddyListLastWriteTime
= last_write
;
342 buddyList
= new Hashtable ();
345 XmlDocument accounts
= new XmlDocument ();
346 accounts
.Load (buddyListPath
);
348 // Find all xml contact nodes in the contact list
349 foreach (XmlNode contact
in accounts
.SelectNodes ("//meta-contact"))
350 AddContact (contact
);
351 } catch (Exception ex
) {
352 Logger
.Log
.Error (ex
, "Caught exception while trying to parse Kopete contact list:");
356 private void AddContact (XmlNode contact
)
358 string protocol
, owner
, other
, alias, iconlocation
, iconchecksum
;
367 // For each and every meta-contact, there can be multiple
368 // buddy information entries if we have a contact added on
369 // multiple protocols. Loop through them.
371 foreach (XmlNode plugin_node
in contact
.SelectNodes ("plugin-data")) {
372 // Determin the protocol
373 XmlAttribute plugin_id_attr
= plugin_node
.Attributes
["plugin-id"];
374 protocol
= plugin_id_attr
.Value
.Substring (0, plugin_id_attr
.Value
.Length
-8).ToLower ();
375 DebugPrint ("Protocol=" + protocol
);
377 // Fetch all the buddy properties
378 foreach (XmlNode plugin_data_node
in plugin_node
.SelectNodes ("plugin-data-field")) {
379 switch (plugin_data_node
.Attributes
["key"].Value
) {
381 other
= plugin_data_node
.InnerText
;
382 DebugPrint ("Screen=" + other
);
385 owner
= plugin_data_node
.InnerText
;
386 DebugPrint ("Account=" + owner
);
389 alias = plugin_data_node
.InnerText
;
390 DebugPrint ("Alias=" + alias);
395 // Replace any earlier buddies with the same screenname
396 // FIXME: Not safe since we can have the same screenname on different accounts.
397 if (buddyList
.ContainsKey (Format(other
)))
398 buddyList
.Remove (Format(other
));
400 buddyList
.Add (Format(other
), new ImBuddy (protocol
, owner
, Format(other
), alias, iconlocation
, iconchecksum
));
405 public ImBuddy
Search (string buddy
) {
406 return (ImBuddy
)buddyList
[Format(buddy
)];