--- /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(" "," ");
+ room.write(Time.local(new time_t()), "message", nick, Markup.escape_text(body).replace("\n","<br/>"));
+ }
+ }
+ });
+ }
+ public override string name() {
+ return "muc_log";
+ }
+}