]>
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
))
408 serv
.privmsg(auteur
,"Syntaxe : SCORE TRANSFERT <pseudo> [<n>]")
410 serv
.privmsg(auteur
,"Votre score : %s"%(self
.get_scores().get(auteur
,0)) )
413 scores
=self
.get_scores().items()
415 scores
.sort(lambda x
,y
:cmp(x
[1],y
[1]))
417 serv
.privmsg(auteur
,"Scores by score : "+" ; ".join(["%s %s"%(i
[0],i
[1]) for i
in scores
]))
419 scores
.sort(lambda x
,y
:cmp(x
[0].lower(),y
[0].lower()))
420 serv
.privmsg(auteur
,"Scores by pseudo : "+" ; ".join(["%s %s"%(i
[0],i
[1]) for i
in scores
]))
421 elif auteur
in self
.overops
:
422 souscmd
=message
[1].lower()
426 scores
=self
.get_scores()
427 if scores
.has_key(todelete
):
429 self
.save_scores(scores
)
430 serv
.privmsg(auteur
,"Score de %s supprimé"%(todelete))
432 serv
.privmsg(auteur
,"Ce score n'existe pas : %s"%(todelete))
434 serv
.privmsg(auteur
,"Syntaxe : SCORES DEL <pseudo>")
435 elif souscmd
in ["add","sub"]:
437 toadd
,val
=message
[2],message
[3]
441 serv
.privmsg(auteur
,"Syntaxe : SCORES {ADD|SUB} <pseudo> <n>")
445 self
.add_score(toadd
,val
)
446 serv
.privmsg(auteur
,"Done")
448 serv
.privmsg(auteur
,"Syntaxe : SCORES {ADD|SUB} <pseudo> <n>")
450 serv
.privmsg(auteur
,"Syntaxe : SCORES {DEL|ADD|SUB} <pseudo> [<n>]")
456 serv
.privmsg(auteur
,"Je n'ai pas compris. Essaye HELP…")
458 def on_pubmsg(self
, serv
, ev
):
459 if ignore_event(serv
, ev
):
461 auteur
= irclib
.nm_to_n(ev
.source())
463 message
= ev
.arguments()[0]
464 self
.update_activity(canal
,auteur
,message
)
466 test
=bot_unicode(message
)
467 except UnicodeBotError
:
468 if config
.utf8_trigger
and not canal
in self
.quiet_channels
:
469 serv
.privmsg(canal
, (u
"%s: %s"%(auteur
,random
.choice(config
.utf8_fail_answers
))).encode("utf8"))
472 pour_moi
,message
=self
.pourmoi(serv
,message
)
473 if pour_moi
and message
.split()!=[]:
474 cmd
=message
.split()[0].lower()
476 args
=" ".join(message
.split()[1:])
479 if cmd
in ["meurs","die","crève"]:
480 if auteur
in self
.overops
:
482 log(self
.serveur
,canal
,auteur
,message
+"[successful]")
484 serv
.privmsg(canal
,"%s: crève !"%(auteur))
485 log(self
.serveur
,canal
,auteur
,message
+"[failed]")
486 elif cmd
in ["meur", "meurt","meurre","meurres"] and not canal
in self
.quiet_channels
:
487 serv
.privmsg(canal
,'%s: Mourir, impératif, 2ème personne du singulier : "meurs" (de rien)'%(auteur))
488 elif cmd
== "reload":
489 if auteur
in self
.ops
:
490 log(self
.serveur
, canal
, auteur
, message
+"[successful]")
492 elif cmd
in ["part","leave","dégage"]:
493 if auteur
in self
.ops
and (not (canal
in self
.stay_channels
)
494 or auteur
in self
.overops
):
496 log(self
.serveur
,canal
,auteur
,message
+"[successful]")
497 self
.chanlist
.remove(canal
)
499 serv
.privmsg(canal
,"%s: Non, je reste !"%(auteur))
500 log(self
.serveur
,canal
,auteur
,message
+"[failed]")
502 elif cmd
in ["deviens","pseudo"]:
503 if auteur
in self
.ops
:
506 log(self
.serveur
,canal
,auteur
,message
+"[successful]")
507 elif cmd
in ["coucou"] and not canal
in self
.quiet_channels
:
508 serv
.privmsg(canal
,"%s: coucou"%(auteur))
509 elif cmd
in ["ping"] and not canal
in self
.quiet_channels
:
510 serv
.privmsg(canal
,"%s: pong"%(auteur))
511 elif cmd
in ["déconnaissance","deconnaissance","énigme","enigme","encore","aco","moo","moo !","moo !"]:
512 if canal
in self
.play_channels
:
513 if self
.play_status
.get(canal
,[-1])[0]==0:
515 self
.start_enigme(serv
,canal
)
517 serv
.privmsg(canal
,"%s: Je peux souffler une minute ?"%(auteur))
519 serv
.privmsg(canal
,("%s: Rappel : %s"%(auteur
,self
.play_status
[canal
][1])).encode("utf8") )
521 serv
.privmsg(canal
,"%s: pas ici…"%(auteur))
522 elif cmd
in ["score","!score"]:
523 serv
.privmsg(auteur
,"Votre score : %s"%(self
.get_scores().get(auteur
,0)) )
524 elif cmd
in ["scores","!scores"]:
525 scores
=self
.get_scores().items()
527 scores
.sort(lambda x
,y
:cmp(x
[1],y
[1]))
529 serv
.privmsg(auteur
,"Scores by score : "+" ; ".join(["%s %s"%(i
[0],i
[1]) for i
in scores
]))
531 scores
.sort(lambda x
,y
:cmp(x
[0].lower(),y
[0].lower()))
532 serv
.privmsg(auteur
,"Scores by pseudo : "+" ; ".join(["%s %s"%(i
[0],i
[1]) for i
in scores
]))
533 elif cmd
=="indice" and canal
in self
.play_channels
:
534 self
.give_indice(serv
,canal
,None)
535 elif is_tag(message
) and not canal
in self
.quiet_channels
:
536 if auteur
in self
.ops
:
537 action
=random
.choice(config
.tag_actions
)
538 serv
.action(canal
,action
.encode("utf8"))
539 self
.quiet_channels
.append(canal
)
541 answer
=random
.choice(config
.tag_answers
)
542 for ligne
in answer
.split("\n"):
543 serv
.privmsg(canal
,"%s: %s"%(auteur
,ligne
.encode("utf8")))
544 elif "Bâille, cru aile ou orld" in message
:
545 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 self
.play_status
.get(canal
,[-1])[0] in [1,2]:
552 answer_regexp
=self
.play_status
[canal
][3]
553 answer
=self
.play_status
[canal
][4]
554 if reussi(message
.decode("utf8"),answer
,answer_regexp
,auteur
):
555 serv
.privmsg(canal
,(u
"%s: bravo ! (C'était %s)"%(auteur
,answer
)).encode("utf8"))
556 log(self
.serveur
,canal
,auteur
+"$win",message
)
557 self
.add_score(auteur
,1)
559 self
.play_status
[canal
]=[0,token
]
560 if config
.auto_trigger
:
561 serv
.execute_delayed(random
.randrange(config
.Ttrig
*5,config
.Ttrig
*10),self
.start_enigme
,(serv
,canal
,token
))
563 def on_kick(self
,serv
,ev
):
564 auteur
= irclib
.nm_to_n(ev
.source())
565 channel
= ev
.target()
566 victime
= ev
.arguments()[0]
567 raison
= ev
.arguments()[1]
568 if victime
==self
.nick
:
569 log(self
.serveur
,"%s kické de %s par %s (raison : %s)" %(victime
,channel
,auteur
,raison
))
572 self
.update_activity(channel
,force
=True)
573 # on ne dit rien au rejoin
574 #l1,l2=config.kick_answers,config.kick_actions
575 #n1,n2=len(l1),len(l2)
576 #i=random.randrange(n1+n2)
578 # serv.action(channel,l2[i-n1].format(auteur).encode("utf8"))
580 # serv.privmsg(channel,l1[i].format(auteur).encode("utf8"))
582 def quitter(self
,chan
,leave_message
=None):
583 if leave_message
==None:
584 leave_message
=random
.choice(config
.leave_messages
)
585 self
.serv
.part(chan
,message
=leave_message
.encode("utf8"))
587 def mourir(self
,quit_message
=None):
588 if quit_message
==None:
589 quit_message
=random
.choice(config
.quit_messages
)
590 self
.die(msg
=quit_message
.encode("utf8"))
592 def get_scores(self
):
593 f
=open(config
.score_file
)
594 scores
=pickle
.load(f
)
598 def add_score(self
,pseudo
,value
):
599 scores
=self
.get_scores()
600 if scores
.has_key(pseudo
):
601 scores
[pseudo
]+=value
604 self
.save_scores(scores
)
606 def save_scores(self
,scores
):
607 f
=open(config
.score_file
,"w")
608 pickle
.dump(scores
,f
)
612 return self
.serv
.get_nickname()
613 nick
= property(_getnick
)
615 def update_activity(self
,canal
="",pseudo
="",message
="",force
=False):
616 if force
or (not pseudo
in config
.idle_bots
and all([not re
.match(ignore
, message
) for ignore
in config
.idle_messages
])):
617 self
.last_activity
[canal
]=time
.time()
618 def is_active(self
,canal
):
619 # Si on n'a pas d'info sur le chan, il est inactif
620 return time
.time()-self
.last_activity
.get(canal
, config
.idle_time
)<config
.idle_time
622 def reload(self
, auteur
=None):
624 if auteur
in [None, "SIGHUP"]:
625 towrite
= "Config reloaded" + " (SIGHUP received)"*(auteur
== "SIGHUP")
626 for to
in config
.report_bugs_to
:
627 self
.serv
.privmsg(to
, towrite
)
628 log(self
.serveur
, towrite
)
630 self
.serv
.privmsg(auteur
,"Config reloaded")
632 def start_as_daemon(self
, outfile
):
633 sys
.stderr
= Logger(outfile
)
637 class Logger(object):
638 """Pour écrire ailleurs que sur stdout"""
639 def __init__(self
, filename
="deconnaisseur.full.log"):
640 self
.filename
= filename
642 def write(self
, message
):
643 f
= open(self
.filename
, "a")
648 if __name__
=="__main__":
651 print "Usage : deconnaisseur.py <serveur> [--debug] [--no-output] [--daemon [--pidfile]] [--outfile]"
652 print " --outfile sans --no-output ni --daemon n'a aucun effet"
655 if "--daemon" in sys
.argv
:
656 thisfile
= os
.path
.realpath(__file__
)
657 thisdirectory
= thisfile
.rsplit("/", 1)[0]
658 os
.chdir(thisdirectory
)
662 if "debug" in sys
.argv
or "--debug" in sys
.argv
:
666 serveurs
={"a♡":"acoeur.crans.org","acoeur":"acoeur.crans.org","acoeur.crans.org":"acoeur.crans.org",
667 "irc":"irc.crans.org","crans":"irc.crans.org","irc.crans.org":"irc.crans.org"}
668 if "--no-output" in sys
.argv
or "--daemon" in sys
.argv
:
669 outfile
= "/var/log/bots/deconnaisseur.full.log"
672 if arg
[0].strip('-') in ["out", "outfile", "logfile"]:
674 sys
.stdout
= Logger(outfile
)
676 serveur
=serveurs
[serveur
]
678 print "Server Unknown : %s"%(serveur)
680 deconnaisseur
=Deconnaisseur(serveur
,debug
)
681 # Si on reçoit un SIGHUP, on reload la config
682 def sighup_handler(signum
, frame
):
683 deconnaisseur
.reload("SIGHUP")
684 signal
.signal(signal
.SIGHUP
, sighup_handler
)
686 child_pid
= os
.fork()
689 deconnaisseur
.start_as_daemon(outfile
)
691 # on enregistre le pid de deconnaisseur
692 pidfile
= "/var/run/bots/deconnaisseur.pid"
695 if arg
[0].strip('-') in ["pidfile"]:
697 f
= open(pidfile
, "w")
698 f
.write("%s\n" % child_pid
)
701 deconnaisseur
.start()