GG



beagled/GaduGaduQueryable.cs:
----------------------------------------------
//
// GaduGaduQueryable.cs
//
// Copyright (C) 2005 Jakub W. Jozwicki <j jozwicki it-faq pl>
//
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
//
//	TODO:	Ask hackers from GG2, Kadu to implement gg protocol in Gnome
//				(I can do ~/.gconf/desktop/gnome/url-handlers/gg/%gconf.xml),
//				they should implement commandline options
//			Find out why Polish letters are missing in BEST query window
//			Do it before SuSE 9.3 is out
//
//	Tested GG Clients: http://www.kadu.net, http://www.gnugadu.org

using System;
using System.IO;
using System.Collections;
using System.Threading;

using System.Xml;
using System.Xml.Serialization;
	
using Beagle.Daemon;
using Beagle.Util;

namespace Beagle.Daemon.GaduGaduQueryable {

	[QueryableFlavor (Name="IMLog", Domain=QueryDomain.Local, 
RequireInotify=false)]
	public class GaduGaduQueryable : LuceneQueryable {

		private static Logger log = Logger.Get ("GaduGaduQueryable");
		
		string gg_dir,gg2_dir;
		int gg_wd,gg2_wd;
		
		public GaduGaduQueryable () : base ("GaduGaduIndex")
		{
			gg_dir = Path.Combine (PathFinder.HomeDir, ".gg");
			gg2_dir = Path.Combine (PathFinder.HomeDir, ".gg2");
			gg_dir = Path.Combine (gg_dir, "history");
			gg2_dir = Path.Combine (gg2_dir, "history");
		}

		public override void Start ()
		{
			base.Start ();
			ExceptionHandlingThread.Start (new ThreadStart (StartWorker));
		}

		private void StartWorker ()
		{
			if (!(Directory.Exists(gg_dir) || Directory.Exists(gg2_dir))) {
				GLib.Timeout.Add (60000, new GLib.TimeoutHandler (CheckForExistence));
                                return;
			}
				
			if (Inotify.Enabled) {
				Inotify.EventType mask = Inotify.EventType.CloseWrite;

				gg_wd = Inotify.Watch (gg_dir, mask);
				gg2_wd = Inotify.Watch (gg2_dir, mask);
				Inotify.Event += OnInotifyEvent;
				
			} else {
                                FileSystemWatcher fsw_gg = new 
FileSystemWatcher ();
								FileSystemWatcher fsw_gg2 = new FileSystemWatcher ();
                                fsw_gg.Path = gg_dir;
								fsw_gg2.Path = gg2_dir;

                                fsw_gg.Changed += new FileSystemEventHandler 
(OnChanged);
								fsw_gg2.Changed += new FileSystemEventHandler (OnChanged);
                                fsw_gg.Created += new FileSystemEventHandler 
(OnChanged);
								fsw_gg2.Created += new FileSystemEventHandler (OnChanged);

                                fsw_gg.EnableRaisingEvents = true;
								fsw_gg2.EnableRaisingEvents = true;
                        }
                        log.Info ("Scanning GaduGadu messages...");

                        Stopwatch stopwatch = new Stopwatch ();
                        int item_count = 0;
                        stopwatch.Start ();

                        DirectoryInfo dir = new DirectoryInfo (gg_dir);
                        foreach (FileInfo file in dir.GetFiles ()) {
							IndexTalk(file.FullName, Scheduler.Priority.Delayed);
							item_count++;
                        }
			
						DirectoryInfo dir2 = new DirectoryInfo (gg2_dir);
						foreach (FileInfo file in dir2.GetFiles ()) {
							IndexTalk(file.FullName, Scheduler.Priority.Delayed);
							item_count++;
						}

                        stopwatch.Stop ();
                        log.Info ("Scanned {0} items in {1}", item_count, 
stopwatch);
		}

		private bool CheckForExistence ()
		{
				if (!(Directory.Exists(gg_dir) || Directory.Exists(gg2_dir)))
                	return true;

				this.Start ();

				return false;
		}

		/////////////////////////////////////////////////

        // Modified/Created event using Inotify

		private void OnInotifyEvent (int wd, string path, string subitem,
									 string srcpath, Inotify.EventType type)
		{
			if (wd != gg_wd && wd!=gg2_wd)
				return;

			if (subitem == "")
				return;

			IndexTalk (Path.Combine (path, subitem), Scheduler.Priority.Immediate);
		}

		// Modified/Created event using FSW
		
		private void OnChanged (object o, FileSystemEventArgs args)
		{
			IndexTalk (args.FullPath, Scheduler.Priority.Immediate);
		}
		
		private String CutString(String str, int len)
		{
			if (str.Length >len) {
				int i = len;
				while (i>0) {
					if (str[--i]==' ')
						break;
				}
				str = str.Substring(0,i==0 ? len : i); // nb: CutString("1234567",5)
			}
			return str;
		}
		
		/////////////////////////////////////////////////

		// Parse and index a gg talk
		
		private int IndexTalk (string filename, Scheduler.Priority priority)
		{
			FileInfo file = new FileInfo(filename);
			Talk talk;
			int item_count = 0;

			if (this.FileAttributesStore.IsUpToDate (file.FullName))
			        return 0;

			Scheduler.TaskGroup group = NewMarkingTaskGroup (file.FullName, 
file.LastWriteTime);
			
			talk = Talk.LoadFromFile(file.FullName);
			
			if(talk == null || talk.Items.Count == 0)
				return 0;
			
			foreach (Item item in talk.Items) {
				item_count++;
				
				Indexable indexable = new Indexable ( new Uri (String.Format ("talk:
{0};item={1}", talk.Source, item.gg_id)));
				indexable.MimeType = "text/html";
				indexable.Type = "IMLog";
				indexable.Timestamp = item.date;

				indexable.AddProperty (Property.NewKeyword ("fixme:identity", item.from));
				indexable.AddProperty (Property.NewKeyword ("fixme:speakingto", 
item.speakingto));
				indexable.AddProperty (Property.NewDate ("fixme:starttime", item.date));
				indexable.AddProperty (Property.NewKeyword ("fixme:itemuri", 
String.Concat(Talk.GGURI,item.gg_id)));
				indexable.AddProperty (Property.NewKeyword ("fixme:file", talk.Source));
				indexable.AddProperty (Property.NewKeyword ("fixme:protocol", 
Talk.GGPROT));
											
				String text = String.Format("[{0} {1}] {2} : {3}", item.from, 
item.date.ToString(), item.to, item.msg);
				StringReader reader = new StringReader (text);
				indexable.SetTextReader (reader);
				
				Scheduler.Task task = NewAddTask (indexable);
				task.Priority = priority;
				task.SubPriority = 0;
				task.AddTaskGroup (group);
				ThisScheduler.Add (task);
			}
		     
			return item_count;
		}
	}

	////////////////////////////////////////////////

	class Item
	{
		public static String RECEIVED = "chatrcv";
		public static String SENTBYME = "chatsend";
		
		public String from,to,speakingto,msg,gg_id;
		public DateTime date;
		
		public Item(String _from, String _to, String _speakingto, String _gg_id, 
DateTime _date, String _msg) {
			from = _from;
			to = _to;
			speakingto = _speakingto;
			gg_id = _gg_id;
			date = _date;
			msg = _msg;
		}
	}
	
	class Talk
	{
		public static String GGURI = "gg://";
		public static String GGPROT = "GaduGadu IM";
		public ArrayList Items;
		public String Source;
		
		public Talk(String src) {
			Items = new ArrayList();
			Source = src;
		}
		public static Talk LoadFromFile(String filename)
		{
			StreamReader reader = null;
			try {
				reader = File.OpenText(filename);
			}
			catch (Exception e) {}
			
			if (reader==null) {
				try{
					String path = Path.ChangeExtension(filename,"");
					path = path.Substring(0,path.Length);
					reader = File.OpenText(path);
				}
				catch (Exception e) { return null; }
			}
			
			String line, from = "", to = "", speakingto = "";
			Talk talk = new Talk(filename);
			
			while(reader!=null && (line=reader.ReadLine())!=null)
			{
				String[] str = line.Split(',');
				if (str.Length<3) continue;
				
				if (str[0].CompareTo(Item.RECEIVED)==0) {
					from = str[2];
					to = System.Environment.UserName;
					speakingto = from;
				}
				else if (str[0].CompareTo(Item.SENTBYME)==0) {
					from = System.Environment.UserName;
					to = str[2];
					speakingto = to;
				}
				else
					continue; //corrupted file
				
				DateTime d1 = new DateTime(1970, 1, 1);
				DateTime d2 = new DateTime(1970, 1, 1);
				try {
					d1 = d1.AddSeconds(Int32.Parse(str[3]));
					if (str.Length>4)
						d2 = d2.AddSeconds(Int32.Parse(str[4]));
				}
				catch (Exception e) {}
				
				try {
					if (Math.Abs((d1 - d2).TotalHours) < 1)
						talk.Items.Add(new 
Item(from,to,speakingto,str[1],d1.ToLocalTime(),str[5]));
					else
					talk.Items.Add(new 
Item(from,to,speakingto,str[1],d1.ToLocalTime(),str[4]));
				}
				catch (Exception ex) {} //corrupted file
			}
			reader.Close();
			return talk;
		}
	}
}
-----------------------------------------------------------



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]