diff -r 4e050075fab9 -r dd7a02c6d476 muc_log.vala --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/muc_log.vala Tue Oct 23 23:50:28 2012 +0400 @@ -0,0 +1,124 @@ +using Gee; + +class ModuleMucLog : Module { + protected weak ModuleMuc muc; + protected HashMap rooms; + class RoomLog : Object { + public string jid; + public string logpath; + public string filename; + protected weak ModuleMucLog muclog; + protected FileStream file; + public string getid(Time time) { + return time.format("%s"); + } + protected int lastday; + protected int lastyear; + protected int lastmonth; + + public RoomLog(ModuleMucLog muclog, string jid) { + this.jid = jid; + this.muclog = muclog; + logpath = muclog.getconf(jid, "log-path", null); + filename = null; + write(Time.local(new time_t()), "logstart", "", "Log started"); + } + ~RoomLog() { + write(Time.local(new time_t()), "logstop", "", "Log stopped"); + file.flush(); + } + public void write(Time time, string _class, string nick, string str) { + + if ((lastday != time.day)||(lastmonth != time.month)||(lastyear!=time.year)) { + var fname = time.format(logpath).replace("",jid); + log("muc_log", LogLevelFlags.LEVEL_INFO, "Switching log file '%s' to '%s'", filename, fname); + if (file!=null) file.flush(); + //try { + file = FileStream.open(fname,"a"); + if (file==null) { + int start = 0; + int length = fname.length; + while (true) { + var pos = fname.index_of("/", start); + if (pos==-1) + break; + stderr.printf("--------------------- %s\n", fname[0:pos]); + Posix.mkdir(fname[0:pos],0777); + start = pos+1; + } + + file = FileStream.open(fname,"a"); + if (file == null) { + log("muc_log", LogLevelFlags.LEVEL_WARNING, "Failed to create log file '%s'", fname); + return; + } + } + + if (file.tell()==0) { + var loghead = muclog.getconf(jid, "log-head",null); + if (loghead!="null") { + try { + var headfile = new IOChannel.file(loghead,"r"); + string head; + size_t length; + headfile.read_to_end(out head, out length); + headfile.shutdown(false); + file.printf("%s\n", head.replace("",jid).replace("",time.format("%d.%m.%Y"))); + } catch (FileError fe) { + log("muc_log", LogLevelFlags.LEVEL_WARNING, "Failed to read head"); + } + } + } + filename = fname; + lastyear = time.year; lastmonth = time.month; lastday = time.day; + } + + var id = getid(time); + var times = time.format("%H:%M:%S"); + file.printf("%s", id, _class, id, id, times); + file.printf("%s%s\n", nick, str); + } + + } + public string getconf(string jid, string key, string? def) { + var res = cfg["muc "+jid, key]; + if (res==null) res = cfg["muc", key]; + if (res==null) res = def; + return res; + } + public ModuleMucLog(Config cfg, Connection conn) { + base(cfg, conn); + rooms = new HashMap(); + muc = null; + foreach (var module in conn.modules) { + if (module.name()=="muc") + muc = (ModuleMuc)module; + } + if (muc==null) + log("muc_log", LogLevelFlags.LEVEL_ERROR, "Module 'muc' is not loaded"); + muc.state_changed.connect( (conf, olds, news, desc) => { + switch (news) { + case ModuleMuc.State.CONNECTED: + if (getconf(conf.jid, "log", "no")=="yes") { + rooms[conf.jid] = new RoomLog(this, conf.jid); + } + break; + case ModuleMuc.State.DISCONNECTED: + rooms.unset(conf.jid); + break; + } + }); + muc.on_message.connect( (conf, user, message, body) => { + if ((user!=null)&&(body!=null)&&(message.get_child("delay")==null)) { + var room = rooms[conf.jid]; + if (room!=null) { + var nick = Markup.escape_text(user.nick).replace(" "," "); + room.write(Time.local(new time_t()), "message", nick, Markup.escape_text(body).replace("\n","
")); + } + } + }); + } + public override string name() { + return "muc_log"; + } +}