]>
gitweb.pimeys.fr Git - bots/deconnaisseur.git/blob - deconnaisseur.py
4 # Codé par 20-100 le 23/04/12
6 # Un bot IRC qui sort des déconnaissances
16 from remplace_accents
import remplace_accents
18 # Oui, j'ai recodé ma version d'irclib pour pouvoir rattrapper les SIGHUP
19 sys
.path
.insert(0, "/home/vincent/scripts/python-myirclib")
26 def get_config_played_file(serveur
):
27 serveurs
={"acoeur.crans.org":"acoeur","irc.crans.org":"crans"}
28 return config
.played_file_template
%(serveurs
[serveur
])
30 def get_config_logfile(serveur
):
31 serveurs
={"acoeur.crans.org":"acoeur","irc.crans.org":"crans"}
32 return config
.logfile_template
%(serveurs
[serveur
])
34 class UnicodeBotError(Exception):
36 def bot_unicode(chain
):
39 except UnicodeDecodeError:
42 def log(serveur
,channel
,auteur
=None,message
=None):
43 f
=open(get_config_logfile(serveur
),"a")
44 if auteur
==message
==None:
45 # alors c'est que c'est pas un channel mais juste une ligne de log
46 chain
="%s %s"%(time
.strftime("%F %T"),channel
)
48 chain
="%s [%s:%s] %s"%(time
.strftime("%F %T"),channel
,auteur
,message
)
50 if config
.debug_stdout
:
54 def ignore_event(serv
, ev
):
55 """Retourne ``True`` si il faut ignorer cet évènement."""
56 for (blackmask
, exceptmask
) in config
.blacklisted_masks
:
57 usermask
= ev
.source()
58 if exceptmask
is None:
61 exceptit
= bool(irclib
.mask_matches(usermask
, exceptmask
))
62 blackit
= bool(irclib
.mask_matches(usermask
, blackmask
))
63 if blackit
and not exceptit
:
66 def reussi(message
,answer
,answer_regexp
,auteur
):
67 if auteur
in config
.level3
:
68 return answer
in message
69 if auteur
in config
.level2
:
70 return remplace_accents(answer
) in message
72 if re
.match(".*" + remplace_accents(answer_regexp
).lower(),remplace_accents(message
).lower()):
75 def is_something(chain
,matches
,avant
=u
".*(?:^| )",apres
=u
"(?:$|\.| |,|;).*",case_sensitive
=False,debug
=False):
77 chain
=unicode(chain
,"utf8")
79 chain
=unicode(chain
,"utf8").lower()
80 allmatches
="("+"|".join(matches
)+")"
81 reg
=(avant
+allmatches
+apres
).lower()
86 return is_something(chain
,config
.tag_triggers
)
88 class RefuseError(Exception):
91 class Deconnaisseur(ircbot
.SingleServerIRCBot
):
92 def __init__(self
,serveur
,debug
=False):
93 temporary_pseudo
=config
.pseudo
+str(random
.randrange(10000,100000))
94 ircbot
.SingleServerIRCBot
.__init
__(self
, [(serveur
, 6667)],
95 temporary_pseudo
,"Un bot irc.[flagellez 20-100, il le mérite]", 10)
98 self
.overops
=config
.overops
99 self
.ops
=self
.overops
+config
.ops
100 self
.chanlist
=config
.chanlist
101 self
.stay_channels
=config
.stay_channels
102 self
.play_channels
=config
.play_channels
103 self
.play_status
={i
:[0] for i
in self
.play_channels
}
104 self
.last_activity
={}
105 self
.quiet_channels
=[]
107 def give_me_my_pseudo(self
,serv
):
108 serv
.privmsg("NickServ","RECOVER %s %s"%(config
.pseudo
,config
.password
))
109 serv
.privmsg("NickServ","RELEASE %s %s"%(config
.pseudo
,config
.password
))
111 serv
.nick(config
.pseudo
)
113 def on_welcome(self
, serv
, ev
):
114 self
.serv
=serv
# ça serv ira :)
115 self
.give_me_my_pseudo(serv
)
116 serv
.privmsg("NickServ","identify %s"%(config
.password
))
117 log(self
.serveur
,"Connected")
119 self
.chanlist
=["#bot"]
120 self
.play_channels
=["#bot"]
121 for c
in self
.chanlist
:
122 log(self
.serveur
,"JOIN %s"%(c))
124 for c
in self
.play_channels
:
125 token
=time
.time()-3600
126 self
.play_status
[c
]=[0,token
]
127 if config
.auto_trigger
:
128 serv
.execute_delayed(random
.randrange(config
.ttrig
),self
.start_enigme
,(serv
,c
,token
))
130 def start_enigme(self
,serv
,channel
,token
=None):
131 # On reste silencieux si lechan n'est pas actif
132 if not self
.is_active(channel
):
133 if config
.auto_trigger
:
134 serv
.execute_delayed(config
.ttrig
*5,self
.start_enigme
,(serv
,channel
,token
))
136 if self
.play_status
[channel
][0]==0 and channel
in self
.play_channels
:
138 if token
==self
.play_status
[channel
][-1]:
141 if time
.time() > self
.play_status
[channel
][-1]+config
.time_incompressible
:
146 enigme
,indice
,answer_reg
,answer
=self
.get_enigme()
147 log(self
.serveur
,channel
,u
"$Énigme$".encode("utf8"),("%s; %s; %s; %s"%(enigme
, indice
, answer_reg
, answer
)).encode("utf8"))
148 serv
.privmsg(channel
,enigme
.encode("utf8"))
150 self
.play_status
[channel
]=[1,enigme
,indice
,answer_reg
,answer
,token
]
151 serv
.execute_delayed(random
.randrange(config
.ttrig
*3,config
.ttrig
*5),self
.give_indice
,(serv
,channel
,token
))
154 def give_indice(self
,serv
,channel
,token
):
155 if self
.play_status
[channel
][0]==1:
157 # c'est donc que l'indice a été demandé
158 if self
.play_status
[channel
][-1]+config
.time_incompressible_clue
<time
.time():
159 token
=self
.play_status
[channel
][-1]
160 if self
.play_status
[channel
][-1]==token
:
161 indice
=self
.play_status
[channel
][2]
162 serv
.privmsg(channel
,"indice : %s"%(indice).encode("utf8"))
163 self
.play_status
[channel
][0]=2
164 serv
.execute_delayed(random
.randrange(config
.ttrig
*1,config
.ttrig
*3),self
.give_answer
,(serv
,channel
,token
))
165 def give_answer(self
,serv
,channel
,token
):
166 if self
.play_status
[channel
][0]==2 and self
.play_status
[channel
][-1]==token
:
167 answer
=self
.play_status
[channel
][4]
168 serv
.privmsg(channel
,"C'était : %s"%(answer).encode("utf8"))
170 self
.play_status
[channel
]=[0,token
]
171 if config
.auto_trigger
:
172 serv
.execute_delayed(random
.randrange(config
.Ttrig
*5,config
.Ttrig
*10),self
.start_enigme
,(serv
,channel
,token
))
174 def get_enigme(self
):
175 # on récupère les déconnaissances
176 f
=open(config
.source_file
)
179 l
=re
.findall("%\n(.*)\n(.*)\n(.*)\n(.*)\n(.*)\n",t
)
180 dec
={int(i
[0]):list(i
[1:]) for i
in l
if len(i
)==5}
181 # on va chercher combien de fois elles ont été jouées
182 played_file
=get_config_played_file(self
.serveur
)
186 l
=re
.findall("(.*):(.*)",t
)
187 played
={int(i
[0]):int(i
[1]) for i
in l
}
188 # on récupère le nombre d'occurrences le plus faible
189 mini
=min(played
.values())
190 # on choisit un id dans ceux qui ont ce nombre d'occurences
191 id_choisi
=random
.choice([k
for k
,v
in played
.items() if v
==mini
])
192 enigme
,indice
,answer_reg
,answer
=dec
[id_choisi
]
193 # on incrémente la choisie
195 # on enregistre le played_file
196 f
=open(played_file
,"w")
197 f
.write("\n".join(["%-3s : %s"%(k
,v
) for k
,v
in played
.items()]))
199 return enigme
.decode("utf8"),indice
.decode("utf8"),answer_reg
.decode("utf8"),answer
.decode("utf8")
201 def pourmoi(self
, serv
, message
):
204 if message
[:size
]==pseudo
and len(message
)>size
and message
[size
]==":":
205 return (True,message
[size
+1:].strip(" "))
207 return (False,message
)
209 def on_privmsg(self
, serv
, ev
):
210 if ignore_event(serv
, ev
):
212 message
=ev
.arguments()[0]
213 auteur
= irclib
.nm_to_n(ev
.source())
215 test
=bot_unicode(message
)
216 except UnicodeBotError
:
217 if config
.utf8_trigger
:
218 serv
.privmsg(auteur
, random
.choice(config
.utf8_fail_answers
).encode("utf8"))
220 message
=message
.split()
221 cmd
=message
[0].lower()
224 helpmsg_default
="""Liste des commandes :
225 HELP Affiche ce message d'aide
226 SCORE Affiche ton score (SCORE TRANSFERT <pseudo> [<n>] pour transférer des points)
227 SCORES Affiche les scores"""
229 JOIN Faire rejoindre un channel (sans paramètres, donne la liste des chans actuels)
230 LEAVE Faire quitter un channel
231 PLAY Passe un channel en mode "jouer"
232 NOPLAY Passe un channel en mode "ne pas jouer"
233 QUIET Se taire sur un channel
234 NOQUIET Opposé de QUIET
235 RELOAD Recharge la config"""
237 SCORES {DEL|ADD|SUB} Tu veux un dessin ?
238 SAY Fais envoyer un message sur un chan ou à une personne
239 STAY Ignorera les prochains LEAVE pour un chan
240 NOSTAY Opposé de STAY
241 STATUS Montre l'état courant
243 helpmsg
=helpmsg_default
244 if auteur
in self
.ops
:
246 if auteur
in self
.overops
:
247 helpmsg
+=helpmsg_overops
248 for ligne
in helpmsg
.split("\n"):
249 serv
.privmsg(auteur
,ligne
)
251 if auteur
in self
.ops
:
253 if message
[1] in self
.chanlist
:
254 serv
.privmsg(auteur
,"Je suis déjà sur %s"%(message
[1]))
256 serv
.join(message
[1])
257 self
.chanlist
.append(message
[1])
258 self
.update_activity(message
[1],force
=True)
259 serv
.privmsg(auteur
,"Channels : "+" ".join(self
.chanlist
))
260 log(self
.serveur
,"priv",auteur
," ".join(message
))
262 serv
.privmsg(auteur
,"Channels : "+" ".join(self
.chanlist
))
266 if auteur
in self
.ops
and len(message
)>1:
267 if message
[1] in self
.chanlist
:
268 if not (message
[1] in self
.stay_channels
) or auteur
in self
.overops
:
269 self
.quitter(message
[1]," ".join(message
[2:]))
270 self
.chanlist
.remove(message
[1])
271 log(self
.serveur
,"priv",auteur
," ".join(message
)+"[successful]")
273 serv
.privmsg(auteur
,"Non, je reste !")
274 log(self
.serveur
,"priv",auteur
," ".join(message
)+"[failed]")
276 serv
.privmsg(auteur
,"Je ne suis pas sur %s"%(message
[1]))
280 if auteur
in self
.overops
:
282 if message
[1] in self
.stay_channels
:
283 serv
.privmsg(auteur
,"Je stay déjà sur %s."%(message
[1]))
284 log(self
.serveur
,"priv",auteur
," ".join(message
)+"[failed]")
286 self
.stay_channels
.append(message
[1])
287 serv
.privmsg(auteur
,"Stay channels : "+" ".join(self
.stay_channels
))
288 log(self
.serveur
,"priv",auteur
," ".join(message
)+"[successful]")
290 serv
.privmsg(auteur
,"Stay channels : "+" ".join(self
.stay_channels
))
294 if auteur
in self
.overops
:
296 if message
[1] in self
.stay_channels
:
297 self
.stay_channels
.remove(message
[1])
298 serv
.privmsg(auteur
,"Stay channels : "+" ".join(self
.stay_channels
))
299 log(self
.serveur
,"priv",auteur
," ".join(message
)+"[successful]")
301 serv
.privmsg(auteur
,"Je ne stay pas sur %s."%(message
[1]))
302 log(self
.serveur
,"priv",auteur
," ".join(message
)+"[failed]")
306 if auteur
in self
.ops
:
308 if message
[1] in self
.play_channels
:
309 serv
.privmsg(auteur
,"Je play déjà sur %s."%(message
[1]))
310 log(self
.serveur
,"priv",auteur
," ".join(message
)+"[failed]")
312 self
.play_channels
.append(message
[1])
313 self
.play_status
[message
[1]]=[0,time
.time()-3600]
314 serv
.privmsg(auteur
,"Play channels : "+" ".join(self
.play_channels
))
315 log(self
.serveur
,"priv",auteur
," ".join(message
)+"[successful]")
317 serv
.privmsg(auteur
,"Play channels : "+" ".join(self
.play_channels
))
321 if auteur
in self
.ops
:
323 if message
[1] in self
.play_channels
:
324 self
.play_channels
.remove(message
[1])
325 serv
.privmsg(auteur
,"Play channels : "+" ".join(self
.play_channels
))
326 log(self
.serveur
,"priv",auteur
," ".join(message
)+"[successful]")
328 serv
.privmsg(auteur
,"Je ne play pas sur %s."%(message
[1]))
329 log(self
.serveur
,"priv",auteur
," ".join(message
)+"[failed]")
333 if auteur
in self
.ops
:
335 if message
[1] in self
.quiet_channels
:
336 serv
.privmsg(auteur
,"Je me la ferme déjà sur %s"%(message
[1]))
337 log(self
.serveur
,"priv",auteur
," ".join(message
)+"[failed]")
339 self
.quiet_channels
.append(message
[1])
340 serv
.privmsg(auteur
,"Quiet channels : "+" ".join(self
.quiet_channels
))
341 log(self
.serveur
,"priv",auteur
," ".join(message
)+"[successful]")
343 serv
.privmsg(auteur
,"Quiet channels : "+" ".join(self
.quiet_channels
))
347 if auteur
in self
.ops
:
349 if message
[1] in self
.quiet_channels
:
350 self
.quiet_channels
.remove(message
[1])
351 serv
.privmsg(auteur
,"Quiet channels : "+" ".join(self
.quiet_channels
))
352 log(self
.serveur
,"priv",auteur
," ".join(message
)+"[successful]")
354 serv
.privmsg(auteur
,"Je ne me la ferme pas sur %s."%(message
[1]))
355 log(self
.serveur
,"priv",auteur
," ".join(message
)+"[failed]")
359 if auteur
in self
.ops
:
361 log(self
.serveur
,"priv",auteur
," ".join(message
)+"[successful]")
364 elif cmd
in ["states","status"]:
365 if auteur
in self
.overops
:
366 for k
in self
.play_status
.keys():
367 serv
.privmsg(auteur
,(u
"%s : %s"%(k
,"; ".join([unicode(i
) for i
in self
.play_status
[k
]]))).encode("utf8") )
369 if auteur
in self
.overops
and len(message
)>2:
370 serv
.privmsg(message
[1]," ".join(message
[2:]))
371 log(self
.serveur
,"priv",auteur
," ".join(message
))
372 elif len(message
)<=2:
373 serv
.privmsg(auteur
,"Syntaxe : SAY <channel> <message>")
377 if auteur
in self
.overops
:
378 log(self
.serveur
,"priv",auteur
," ".join(message
)+"[successful]")
382 if len(message
) in [3,4] and message
[1].lower()=="transfert":
383 scores
=self
.get_scores()
384 de
,to
=auteur
,message
[2]
385 value
=scores
.get(de
,0)
388 asked
=int(message
[3])
390 serv
.privmsg(auteur
,"Syntaxe : SCORE TRANSFERT <pseudo> [<n>]")
395 serv
.privmsg(auteur
,"Vous n'avez pas de points")
398 serv
.privmsg(auteur
,"Bien tenté…")
401 serv
.privmsg(auteur
,"Vous n'avez que %s points"%(value))
404 self
.add_score(de
,-asked
)
405 self
.add_score(to
,asked
)
406 serv
.privmsg(auteur
,"Transfert de %s points de %s à %s"%(asked
,de
,to
))
407 log(self
.serveur
,"Transfert de %s points de %s à %s"%(asked
,de
,to
))
409 serv
.privmsg(auteur
,"Syntaxe : SCORE TRANSFERT <pseudo> [<n>]")
411 serv
.privmsg(auteur
,"Votre score : %s"%(self
.get_scores().get(auteur
,0)) )
414 scores
=self
.get_scores().items()
416 scores
.sort(lambda x
,y
:cmp(x
[1],y
[1]))
418 serv
.privmsg(auteur
,"Scores by score : "+" ; ".join(["%s %s"%(i
[0],i
[1]) for i
in scores
]))
420 scores
.sort(lambda x
,y
:cmp(x
[0].lower(),y
[0].lower()))
421 serv
.privmsg(auteur
,"Scores by pseudo : "+" ; ".join(["%s %s"%(i
[0],i
[1]) for i
in scores
]))
422 elif auteur
in self
.overops
:
423 souscmd
=message
[1].lower()
427 scores
=self
.get_scores()
428 if scores
.has_key(todelete
):
430 self
.save_scores(scores
)
431 serv
.privmsg(auteur
,"Score de %s supprimé"%(todelete))
433 serv
.privmsg(auteur
,"Ce score n'existe pas : %s"%(todelete))
435 serv
.privmsg(auteur
,"Syntaxe : SCORES DEL <pseudo>")
436 elif souscmd
in ["add","sub"]:
438 toadd
,val
=message
[2],message
[3]
442 serv
.privmsg(auteur
,"Syntaxe : SCORES {ADD|SUB} <pseudo> <n>")
446 self
.add_score(toadd
,val
)
447 serv
.privmsg(auteur
,"Done")
449 serv
.privmsg(auteur
,"Syntaxe : SCORES {ADD|SUB} <pseudo> <n>")
451 serv
.privmsg(auteur
,"Syntaxe : SCORES {DEL|ADD|SUB} <pseudo> [<n>]")
457 serv
.privmsg(auteur
,"Je n'ai pas compris. Essaye HELP…")
459 def on_pubmsg(self
, serv
, ev
):
460 if ignore_event(serv
, ev
):
462 auteur
= irclib
.nm_to_n(ev
.source())
464 message
= ev
.arguments()[0]
465 self
.update_activity(canal
,auteur
,message
)
467 test
=bot_unicode(message
)
468 except UnicodeBotError
:
469 if config
.utf8_trigger
and not canal
in self
.quiet_channels
:
470 serv
.privmsg(canal
, (u
"%s: %s"%(auteur
,random
.choice(config
.utf8_fail_answers
))).encode("utf8"))
473 pour_moi
,message
=self
.pourmoi(serv
,message
)
474 if pour_moi
and message
.split()!=[]:
475 cmd
=message
.split()[0].lower()
477 args
=" ".join(message
.split()[1:])
480 if cmd
in ["meurs","die","crève"]:
481 if auteur
in self
.overops
:
483 log(self
.serveur
,canal
,auteur
,message
+"[successful]")
485 serv
.privmsg(canal
,"%s: crève !"%(auteur))
486 log(self
.serveur
,canal
,auteur
,message
+"[failed]")
487 elif cmd
in ["meur", "meurt","meurre","meurres"] and not canal
in self
.quiet_channels
:
488 serv
.privmsg(canal
,'%s: Mourir, impératif, 2ème personne du singulier : "meurs" (de rien)'%(auteur))
489 elif cmd
== "reload":
490 if auteur
in self
.ops
:
491 log(self
.serveur
, canal
, auteur
, message
+"[successful]")
493 elif cmd
in ["part","leave","dégage"]:
494 if auteur
in self
.ops
and (not (canal
in self
.stay_channels
)
495 or auteur
in self
.overops
):
497 log(self
.serveur
,canal
,auteur
,message
+"[successful]")
498 self
.chanlist
.remove(canal
)
500 serv
.privmsg(canal
,"%s: Non, je reste !"%(auteur))
501 log(self
.serveur
,canal
,auteur
,message
+"[failed]")
503 elif cmd
in ["deviens","pseudo"]:
504 if auteur
in self
.ops
:
507 log(self
.serveur
,canal
,auteur
,message
+"[successful]")
508 elif cmd
in ["coucou"] and not canal
in self
.quiet_channels
:
509 serv
.privmsg(canal
,"%s: coucou"%(auteur))
510 elif cmd
in ["ping"] and not canal
in self
.quiet_channels
:
511 serv
.privmsg(canal
,"%s: pong"%(auteur))
512 elif cmd
in ["déconnaissance","deconnaissance","énigme","enigme","encore","aco","moo","moo !","moo !"]:
513 if canal
in self
.play_channels
:
514 if self
.play_status
.get(canal
,[-1])[0]==0:
516 self
.start_enigme(serv
,canal
)
518 serv
.privmsg(canal
,"%s: Je peux souffler une minute ?"%(auteur))
520 serv
.privmsg(canal
,("%s: Rappel : %s"%(auteur
,self
.play_status
[canal
][1])).encode("utf8") )
522 serv
.privmsg(canal
,"%s: pas ici…"%(auteur))
523 elif cmd
in ["score","!score"]:
524 serv
.privmsg(auteur
,"Votre score : %s"%(self
.get_scores().get(auteur
,0)) )
525 elif cmd
in ["scores","!scores"]:
526 scores
=self
.get_scores().items()
528 scores
.sort(lambda x
,y
:cmp(x
[1],y
[1]))
530 serv
.privmsg(auteur
,"Scores by score : "+" ; ".join(["%s %s"%(i
[0],i
[1]) for i
in scores
]))
532 scores
.sort(lambda x
,y
:cmp(x
[0].lower(),y
[0].lower()))
533 serv
.privmsg(auteur
,"Scores by pseudo : "+" ; ".join(["%s %s"%(i
[0],i
[1]) for i
in scores
]))
534 elif cmd
=="indice" and canal
in self
.play_channels
:
535 self
.give_indice(serv
,canal
,None)
536 elif is_tag(message
) and not canal
in self
.quiet_channels
:
537 if auteur
in self
.ops
:
538 action
=random
.choice(config
.tag_actions
)
539 serv
.action(canal
,action
.encode("utf8"))
540 self
.quiet_channels
.append(canal
)
542 answer
=random
.choice(config
.tag_answers
)
543 for ligne
in answer
.split("\n"):
544 serv
.privmsg(canal
,"%s: %s"%(auteur
,ligne
.encode("utf8")))
545 elif "Bâille, cru aile ou orld" in message
:
546 self
.mourir(u
"Un de mes easters eggs (non en fait j'en ai qu'un) a été découvert par %s !"%auteur
)
551 if tryother
and pour_moi
:
552 if self
.play_status
.get(canal
,[-1])[0] in [1,2]:
553 answer_regexp
=self
.play_status
[canal
][3]
554 answer
=self
.play_status
[canal
][4]
555 if reussi(message
.decode("utf8"),answer
,answer_regexp
,auteur
):
556 serv
.privmsg(canal
,(u
"%s: bravo ! (C'était %s)"%(auteur
,answer
)).encode("utf8"))
557 log(self
.serveur
,canal
,auteur
+"$win",message
)
558 self
.add_score(auteur
,1)
560 self
.play_status
[canal
]=[0,token
]
561 if config
.auto_trigger
:
562 serv
.execute_delayed(random
.randrange(config
.Ttrig
*5,config
.Ttrig
*10),self
.start_enigme
,(serv
,canal
,token
))
564 def on_kick(self
,serv
,ev
):
565 auteur
= irclib
.nm_to_n(ev
.source())
566 channel
= ev
.target()
567 victime
= ev
.arguments()[0]
568 raison
= ev
.arguments()[1]
569 if victime
==self
.nick
:
570 log(self
.serveur
,"%s kické de %s par %s (raison : %s)" %(victime
,channel
,auteur
,raison
))
573 self
.update_activity(channel
,force
=True)
574 # on ne dit rien au rejoin
575 #l1,l2=config.kick_answers,config.kick_actions
576 #n1,n2=len(l1),len(l2)
577 #i=random.randrange(n1+n2)
579 # serv.action(channel,l2[i-n1].format(auteur).encode("utf8"))
581 # serv.privmsg(channel,l1[i].format(auteur).encode("utf8"))
583 def quitter(self
,chan
,leave_message
=None):
584 if leave_message
==None:
585 leave_message
=random
.choice(config
.leave_messages
)
586 self
.serv
.part(chan
,message
=leave_message
.encode("utf8"))
588 def mourir(self
,quit_message
=None):
589 if quit_message
==None:
590 quit_message
=random
.choice(config
.quit_messages
)
591 self
.die(msg
=quit_message
.encode("utf8"))
593 def get_scores(self
):
594 f
=open(config
.score_file
)
595 scores
=pickle
.load(f
)
599 def add_score(self
,pseudo
,value
):
600 scores
=self
.get_scores()
601 if scores
.has_key(pseudo
):
602 scores
[pseudo
]+=value
605 self
.save_scores(scores
)
607 def save_scores(self
,scores
):
608 f
=open(config
.score_file
,"w")
609 pickle
.dump(scores
,f
)
613 return self
.serv
.get_nickname()
614 nick
= property(_getnick
)
616 def update_activity(self
,canal
="",pseudo
="",message
="",force
=False):
617 if force
or (not pseudo
in config
.idle_bots
and all([not re
.match(ignore
, message
) for ignore
in config
.idle_messages
])):
618 self
.last_activity
[canal
]=time
.time()
619 def is_active(self
,canal
):
620 # Si on n'a pas d'info sur le chan, il est inactif
621 return time
.time()-self
.last_activity
.get(canal
, config
.idle_time
)<config
.idle_time
623 def reload(self
, auteur
=None):
625 if auteur
in [None, "SIGHUP"]:
626 towrite
= "Config reloaded" + " (SIGHUP received)"*(auteur
== "SIGHUP")
627 for to
in config
.report_bugs_to
:
628 self
.serv
.privmsg(to
, towrite
)
629 log(self
.serveur
, towrite
)
631 self
.serv
.privmsg(auteur
,"Config reloaded")
633 def start_as_daemon(self
, outfile
):
634 sys
.stderr
= Logger(outfile
)
638 class Logger(object):
639 """Pour écrire ailleurs que sur stdout"""
640 def __init__(self
, filename
="deconnaisseur.full.log"):
641 self
.filename
= filename
643 def write(self
, message
):
644 f
= open(self
.filename
, "a")
649 if __name__
=="__main__":
652 print "Usage : deconnaisseur.py <serveur> [--debug] [--no-output] [--daemon [--pidfile]] [--outfile]"
653 print " --outfile sans --no-output ni --daemon n'a aucun effet"
656 if "--daemon" in sys
.argv
:
657 thisfile
= os
.path
.realpath(__file__
)
658 thisdirectory
= thisfile
.rsplit("/", 1)[0]
659 os
.chdir(thisdirectory
)
663 if "debug" in sys
.argv
or "--debug" in sys
.argv
:
667 serveurs
={"a♡":"acoeur.crans.org","acoeur":"acoeur.crans.org","acoeur.crans.org":"acoeur.crans.org",
668 "irc":"irc.crans.org","crans":"irc.crans.org","irc.crans.org":"irc.crans.org"}
669 if "--no-output" in sys
.argv
or "--daemon" in sys
.argv
:
670 outfile
= "/var/log/bots/deconnaisseur.full.log"
673 if arg
[0].strip('-') in ["out", "outfile", "logfile"]:
675 sys
.stdout
= Logger(outfile
)
677 serveur
=serveurs
[serveur
]
679 print "Server Unknown : %s"%(serveur)
681 deconnaisseur
=Deconnaisseur(serveur
,debug
)
682 # Si on reçoit un SIGHUP, on reload la config
683 def sighup_handler(signum
, frame
):
684 deconnaisseur
.reload("SIGHUP")
685 signal
.signal(signal
.SIGHUP
, sighup_handler
)
687 child_pid
= os
.fork()
690 deconnaisseur
.start_as_daemon(outfile
)
692 # on enregistre le pid de deconnaisseur
693 pidfile
= "/var/run/bots/deconnaisseur.pid"
696 if arg
[0].strip('-') in ["pidfile"]:
698 f
= open(pidfile
, "w")
699 f
.write("%s\n" % child_pid
)
702 deconnaisseur
.start()