muc_log.vala
changeset 3 dd7a02c6d476
child 4 8785de25b6bd
--- /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<string,RoomLog> 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("<muc>",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("<muc>",jid).replace("<date>",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("<tr id='l_%s' class='%s'><td class='time'><a id='i_%s' href='#i_%s'>%s</a></td>", id, _class, id, id, times);
+            file.printf("<td class='nick'>%s</td><td class='text'>%s</td></tr>\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<string,RoomLog>();
+        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(" ","&nbsp;");
+                    room.write(Time.local(new time_t()), "message", nick, Markup.escape_text(body).replace("\n","<br/>"));
+                }
+            }
+        });
+    }
+    public override string name() {
+        return "muc_log";
+    }
+}