If we get an EOF trying to read a uint or a time value, throw an exception.
[beagle.git] / Util / ImBuddy.cs
blob30518d353480e86269cfd179ff7a6ca150bc8ea5
1 //
2 // ImBuddy.cs
3 //
4 // Copyright (C) 2004 Matthew Jones <mattharrison sbcglobal net>
5 //
7 //
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
24 // SOFTWARE.
27 using System;
28 using System.Collections;
29 using System.Xml;
30 using System.IO;
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) {
43 Protocol = protocol;
44 OwnerAccountName = owneraccount;
45 BuddyAccountName = buddyaccount;
46 Alias = alias;
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) {
63 if (!verbose)
64 return;
65 Logger.Log.Debug ("{0}", str);
70 public class GaimBuddyListReader : ImBuddyListReader {
72 string buddyListPath;
73 string buddyListDir;
74 DateTime buddyListLastWriteTime;
75 uint timeoutId;
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))
84 Read ();
86 // Poll the file once every minute
87 timeoutId = GLib.Timeout.Add (60000, new GLib.TimeoutHandler (ReadTimeoutHandler));
90 ~GaimBuddyListReader ()
92 if (timeoutId > 0)
93 GLib.Source.Remove (timeoutId);
96 private bool ReadTimeoutHandler ()
98 if (File.Exists (buddyListPath))
99 Read ();
101 return true;
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)
113 return;
115 buddyListLastWriteTime = last_write;
117 buddyList = new Hashtable ();
119 try {
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")) {
142 AddBuddy (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;
153 protocol = "";
154 owner = "";
155 other = "";
156 alias = "";
157 iconlocation = "";
158 iconchecksum = "";
160 foreach (XmlAttribute attr in buddy.Attributes) {
161 switch (attr.Name) {
162 case "account":
163 owner = attr.Value;
164 DebugPrint ("owner: " + owner);
165 break;
166 case "proto":
167 protocol = attr.Value;
168 DebugPrint ("protocol: " + protocol);
169 break;
173 foreach (XmlNode attr in buddy.ChildNodes) {
174 switch (attr.LocalName) {
175 case "name":
176 other = attr.InnerText;
177 DebugPrint ("other: " + other);
178 break;
179 case "alias":
180 alias = attr.InnerText;
181 DebugPrint ("alias: " + alias);
182 break;
183 case "setting":
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);
196 break;
200 ImBuddy old;
202 alias = groupalias;
204 if (buddyList.ContainsKey (Format(other))) {
205 old = (ImBuddy)buddyList[Format(other)];
206 if (old.Alias == "" && alias != "")
207 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);
215 else
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;
223 protocol = "";
224 owner = "";
225 other = "";
226 alias = "";
227 iconlocation = "";
228 iconchecksum = "";
230 foreach (XmlAttribute attr in buddy.Attributes) {
231 switch (attr.Name) {
232 case "account":
233 owner = attr.Value;
234 DebugPrint ("owner: " + owner);
235 break;
236 case "proto":
237 protocol = attr.Value;
238 DebugPrint ("protocol: " + protocol);
239 break;
243 foreach (XmlNode attr in buddy.ChildNodes) {
244 switch (attr.LocalName) {
245 case "name":
246 other = attr.InnerText;
247 DebugPrint ("other: " + other);
248 break;
249 case "alias":
250 alias = attr.InnerText;
251 DebugPrint ("alias: " + alias);
252 break;
253 case "setting":
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);
266 break;
270 ImBuddy old;
272 if (buddyList.ContainsKey (Format(other))) {
273 old = (ImBuddy)buddyList[Format(other)];
274 if (old.Alias == "" && alias != "")
275 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);
283 else
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;
299 string buddyListDir;
300 DateTime buddyListLastWriteTime;
301 uint timeoutId;
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))
309 Read ();
311 // Poll the file once every minute
312 timeoutId = GLib.Timeout.Add (60000, new GLib.TimeoutHandler (ReadTimeoutHandler));
315 ~KopeteBuddyListReader ()
317 if (timeoutId > 0)
318 GLib.Source.Remove (timeoutId);
321 private bool ReadTimeoutHandler ()
323 if (File.Exists (buddyListPath))
324 Read ();
326 return true;
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)
338 return;
340 buddyListLastWriteTime = last_write;
342 buddyList = new Hashtable ();
344 try {
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;
360 protocol = "";
361 owner = "";
362 other = "";
363 alias = "";
364 iconlocation = "";
365 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) {
380 case "contactId":
381 other = plugin_data_node.InnerText;
382 DebugPrint ("Screen=" + other);
383 break;
384 case "accountId":
385 owner = plugin_data_node.InnerText;
386 DebugPrint ("Account=" + owner);
387 break;
388 case "displayName":
389 alias = plugin_data_node.InnerText;
390 DebugPrint ("Alias=" + alias);
391 break;
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)];