GG
- From: "Jakub W. Jozwicki" <jakub007 go2 pl>
- To: dashboard-hackers gnome org
- Subject: GG
- Date: Thu, 31 Mar 2005 19:45:35 +0200
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]