muc_log.vala
changeset 3 dd7a02c6d476
child 4 8785de25b6bd
equal deleted inserted replaced
2:4e050075fab9 3:dd7a02c6d476
       
     1 using Gee;
       
     2 
       
     3 class ModuleMucLog : Module {
       
     4     protected weak ModuleMuc muc;
       
     5     protected HashMap<string,RoomLog> rooms;
       
     6     class RoomLog : Object {
       
     7         public string jid;
       
     8         public string logpath;
       
     9         public string filename;
       
    10         protected weak ModuleMucLog muclog;
       
    11         protected FileStream file;
       
    12         public string getid(Time time) {
       
    13             return time.format("%s");
       
    14         }
       
    15         protected int lastday;
       
    16         protected int lastyear;
       
    17         protected int lastmonth;
       
    18 
       
    19         public RoomLog(ModuleMucLog muclog, string jid) {
       
    20             this.jid = jid;
       
    21             this.muclog = muclog;
       
    22             logpath = muclog.getconf(jid, "log-path", null);
       
    23             filename = null;
       
    24             write(Time.local(new time_t()), "logstart", "", "Log started");
       
    25         }
       
    26         ~RoomLog() {
       
    27             write(Time.local(new time_t()), "logstop", "", "Log stopped");
       
    28             file.flush();
       
    29         }
       
    30         public void write(Time time, string _class, string nick, string str) {
       
    31 
       
    32             if ((lastday != time.day)||(lastmonth != time.month)||(lastyear!=time.year)) {
       
    33                 var fname = time.format(logpath).replace("<muc>",jid);
       
    34                 log("muc_log", LogLevelFlags.LEVEL_INFO, "Switching log file '%s' to '%s'", filename, fname);
       
    35                 if (file!=null) file.flush();
       
    36                 //try {
       
    37                     file = FileStream.open(fname,"a");
       
    38                 if (file==null) {
       
    39                     int start = 0;
       
    40                     int length = fname.length;
       
    41                     while (true) {
       
    42                         var pos = fname.index_of("/", start);
       
    43                         if (pos==-1)
       
    44                             break;
       
    45                         stderr.printf("--------------------- %s\n", fname[0:pos]);
       
    46                         Posix.mkdir(fname[0:pos],0777);
       
    47                         start = pos+1;
       
    48                     } 
       
    49 
       
    50                     file = FileStream.open(fname,"a");
       
    51                     if (file == null) {
       
    52                         log("muc_log", LogLevelFlags.LEVEL_WARNING, "Failed to create log file '%s'", fname);
       
    53                         return;
       
    54                     }
       
    55                 }
       
    56 
       
    57                 if (file.tell()==0) {
       
    58                     var loghead = muclog.getconf(jid, "log-head",null);
       
    59                     if (loghead!="null") {
       
    60                         try {
       
    61                             var headfile = new IOChannel.file(loghead,"r");
       
    62                             string head;
       
    63                             size_t length;
       
    64                             headfile.read_to_end(out head, out length);
       
    65                             headfile.shutdown(false);
       
    66                             file.printf("%s\n", head.replace("<muc>",jid).replace("<date>",time.format("%d.%m.%Y")));
       
    67                         } catch (FileError fe) {
       
    68                             log("muc_log", LogLevelFlags.LEVEL_WARNING, "Failed to read head");
       
    69                         }
       
    70                     }
       
    71                 }
       
    72                 filename = fname;
       
    73                 lastyear = time.year; lastmonth = time.month; lastday = time.day;
       
    74             }
       
    75             
       
    76             var id = getid(time);
       
    77             var times = time.format("%H:%M:%S");
       
    78             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);
       
    79             file.printf("<td class='nick'>%s</td><td class='text'>%s</td></tr>\n", nick, str);
       
    80         }
       
    81             
       
    82     }
       
    83     public string getconf(string jid, string key, string? def) {
       
    84         var res = cfg["muc "+jid, key];
       
    85         if (res==null) res = cfg["muc", key];
       
    86         if (res==null) res = def;
       
    87         return res;
       
    88     }
       
    89     public ModuleMucLog(Config cfg, Connection conn) {
       
    90         base(cfg, conn);
       
    91         rooms = new HashMap<string,RoomLog>();
       
    92         muc = null;
       
    93         foreach (var module in conn.modules) {
       
    94             if (module.name()=="muc")
       
    95                 muc = (ModuleMuc)module;
       
    96         }
       
    97         if (muc==null)
       
    98             log("muc_log", LogLevelFlags.LEVEL_ERROR, "Module 'muc' is not loaded");
       
    99         muc.state_changed.connect( (conf, olds, news, desc) => {
       
   100             switch (news) {
       
   101                 case ModuleMuc.State.CONNECTED:
       
   102                     if (getconf(conf.jid, "log", "no")=="yes") {
       
   103                         rooms[conf.jid] = new RoomLog(this, conf.jid);
       
   104                     }
       
   105                     break;
       
   106                 case ModuleMuc.State.DISCONNECTED:
       
   107                     rooms.unset(conf.jid);
       
   108                     break;
       
   109             }
       
   110         });
       
   111         muc.on_message.connect( (conf, user, message, body) => {
       
   112             if ((user!=null)&&(body!=null)&&(message.get_child("delay")==null)) {
       
   113                 var room = rooms[conf.jid];
       
   114                 if (room!=null) {
       
   115                     var nick = Markup.escape_text(user.nick).replace(" ","&nbsp;");
       
   116                     room.write(Time.local(new time_t()), "message", nick, Markup.escape_text(body).replace("\n","<br/>"));
       
   117                 }
       
   118             }
       
   119         });
       
   120     }
       
   121     public override string name() {
       
   122         return "muc_log";
       
   123     }
       
   124 }