usingGee;classModuleMucLog:Module{protectedweakModuleMucmuc;protectedHashMap<string,RoomLog>rooms;classRoomLog:Object{publicstringjid;publicstringlogpath;publicstringfilename;protectedweakModuleMucLogmuclog;protectedFileStreamfile;publicstringgetid(Timetime){returntime.format("%s");}protectedintlastday;protectedintlastyear;protectedintlastmonth;publicRoomLog(ModuleMucLogmuclog,stringjid){this.jid=jid;this.muclog=muclog;logpath=muclog.getconf(jid,"log-path",null);filename=null;write(Time.local(newtime_t()),"logstart","","Log started");}~RoomLog(){write(Time.local(newtime_t()),"logstop","","Log stopped");}publicvoidwrite(Timetime,string_class,stringnick,stringstr){if((lastday!=time.day)||(lastmonth!=time.month)||(lastyear!=time.year)){varfname=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){intstart=0;intlength=fname.length;while(true){varpos=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){varloghead=muclog.getconf(jid,"log-head",null);if(loghead!="null"){try{varheadfile=newIOChannel.file(loghead,"r");stringhead;size_tlength;headfile.read_to_end(outhead,outlength);headfile.shutdown(false);file.printf("%s\n",head.replace("<muc>",jid).replace("<date>",time.format("%d.%m.%Y")));}catch(FileErrorfe){log("muc_log",LogLevelFlags.LEVEL_WARNING,"Failed to read head");}}}filename=fname;lastyear=time.year;lastmonth=time.month;lastday=time.day;}varid=getid(time);vartimes=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);file.flush();}}publicstringgetconf(stringjid,stringkey,string?def){varres=cfg["muc "+jid,key];if(res==null)res=cfg["muc",key];if(res==null)res=def;returnres;}publicModuleMucLog(Configcfg,Connectionconn){base(cfg,conn);rooms=newHashMap<string,RoomLog>();muc=null;foreach(varmoduleinconn.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){caseModuleMuc.State.CONNECTED:if(getconf(conf.jid,"log","no")=="yes"){varroom=newRoomLog(this,conf.jid);rooms[conf.jid]=room;varsb=newStringBuilder();varnotfirst=false;sb.append("Participants: ");foreach(varoccupantinconf.occupants.values){if(notfirst)sb.append(", ");elsenotfirst=true;sb.append(Markup.escape_text(occupant.nick).replace(" "," "));}room.write(Time.local(newtime_t()),"userlist","",sb.str);}break;caseModuleMuc.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)){varroom=rooms[conf.jid];if(room!=null){varnick=Markup.escape_text(user.nick).replace(" "," ");room.write(Time.local(newtime_t()),"message",nick,Markup.escape_text(body).replace("\n","<br/>"));}}});muc.on_join.connect((conf,user)=>{varroom=rooms[conf.jid];if(room!=null){varnick=Markup.escape_text(user.nick).replace(" "," ");room.write(Time.local(newtime_t()),"join","*",nick+" has joined the room");}});muc.on_part.connect((conf,user)=>{varroom=rooms[conf.jid];if(room!=null){varnick=Markup.escape_text(user.nick).replace(" "," ");room.write(Time.local(newtime_t()),"part","*",nick+" has left the room");}});}publicoverridestringname(){return"muc_log";}}