]>
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 serv
.execute_delayed(random
.randrange(config
.ttrig
),self
.start_enigme
,(serv
,c
,token
))
129 def start_enigme(self
,serv
,channel
,token
=None):
130 # On reste silencieux si lechan n'est pas actif
131 if not self
.is_active(channel
):
132 serv
.execute_delayed(config
.ttrig
*5,self
.start_enigme
,(serv
,channel
,token
))
134 if self
.play_status
[channel
][0]==0 and channel
in self
.play_channels
:
136 if token
==self
.play_status
[channel
][-1]:
139 if time
.time() > self
.play_status
[channel
][-1]+config
.time_incompressible
:
144 enigme
,indice
,answer_reg
,answer
=self
.get_enigme()
145 log(self
.serveur
,channel
,u
"$Énigme$".encode("utf8"),("%s; %s; %s; %s"%(enigme
, indice
, answer_reg
, answer
)).encode("utf8"))
146 serv
.privmsg(channel
,enigme
.encode("utf8"))
148 self
.play_status
[channel
]=[1,enigme
,indice
,answer_reg
,answer
,token
]
149 serv
.execute_delayed(random
.randrange(config
.ttrig
*3,config
.ttrig
*5),self
.give_indice
,(serv
,channel
,token
))
152 def give_indice(self
,serv
,channel
,token
):
153 if self
.play_status
[channel
][0]==1:
155 # c'est donc que l'indice a été demandé
156 if self
.play_status
[channel
][-1]+config
.time_incompressible_clue
<time
.time():
157 token
=self
.play_status
[channel
][-1]
158 if self
.play_status
[channel
][-1]==token
:
159 indice
=self
.play_status
[channel
][2]
160 serv
.privmsg(channel
,"indice : %s"%(indice).encode("utf8"))
161 self
.play_status
[channel
][0]=2
162 serv
.execute_delayed(random
.randrange(config
.ttrig
*1,config
.ttrig
*3),self
.give_answer
,(serv
,channel
,token
))
163 def give_answer(self
,serv
,channel
,token
):
164 if self
.play_status
[channel
][0]==2 and self
.play_status
[channel
][-1]==token
:
165 answer
=self
.play_status
[channel
][4]
166 serv
.privmsg(channel
,"C'était : %s"%(answer).encode("utf8"))
168 self
.play_status
[channel
]=[0,token
]
169 serv
.execute_delayed(random
.randrange(config
.Ttrig
*5,config
.Ttrig
*10),self
.start_enigme
,(serv
,channel
,token
))
171 def get_enigme(self
):
172 # on récupère les déconnaissances
173 f
=open(config
.source_file
)
176 l
=re
.findall("%\n(.*)\n(.*)\n(.*)\n(.*)\n(.*)\n",t
)
177 dec
={int(i
[0]):list(i
[1:]) for i
in l
if len(i
)==5}
178 # on va chercher combien de fois elles ont été jouées
179 played_file
=get_config_played_file(self
.serveur
)
183 l
=re
.findall("(.*):(.*)",t
)
184 played
={int(i
[0]):int(i
[1]) for i
in l
}
185 # on récupère le nombre d'occurrences le plus faible
186 mini
=min(played
.values())
187 # on choisit un id dans ceux qui ont ce nombre d'occurences
188 id_choisi
=random
.choice([k
for k
,v
in played
.items() if v
==mini
])
189 enigme
,indice
,answer_reg
,answer
=dec
[id_choisi
]
190 # on incrémente la choisie
192 # on enregistre le played_file
193 f
=open(played_file
,"w")
194 f
.write("\n".join(["%-3s : %s"%(k
,v
) for k
,v
in played
.items()]))
196 return enigme
.decode("utf8"),indice
.decode("utf8"),answer_reg
.decode("utf8"),answer
.decode("utf8")
198 def pourmoi(self
, serv
, message
):
201 if message
[:size
]==pseudo
and len(message
)>size
and message
[size
]==":":
202 return (True,message
[size
+1:].strip(" "))
204 return (False,message
)
206 def on_privmsg(self
, serv
, ev
):
207 if ignore_event(serv
, ev
):
209 message
=ev
.arguments()[0]
210 auteur
= irclib
.nm_to_n(ev
.source())
212 test
=bot_unicode(message
)
213 except UnicodeBotError
:
214 if config
.utf8_trigger
:
215 serv
.privmsg(auteur
, random
.choice(config
.utf8_fail_answers
).encode("utf8"))
217 message
=message
.split()
218 cmd
=message
[0].lower()
221 helpmsg_default
="""Liste des commandes :
222 HELP Affiche ce message d'aide
223 SCORE Affiche ton score (SCORE TRANSFERT <pseudo> [<n>] pour transférer des points)
224 SCORES Affiche les scores"""
226 JOIN Faire rejoindre un channel (sans paramètres, donne la liste des chans actuels)
227 LEAVE Faire quitter un channel
228 PLAY Passe un channel en mode "jouer"
229 NOPLAY Passe un channel en mode "ne pas jouer"
230 QUIET Se taire sur un channel
231 NOQUIET Opposé de QUIET
232 RELOAD Recharge la config"""
234 SCORES {DEL|ADD|SUB} Tu veux un dessin ?
235 SAY Fais envoyer un message sur un chan ou à une personne
236 STAY Ignorera les prochains LEAVE pour un chan
237 NOSTAY Opposé de STAY
238 STATUS Montre l'état courant
240 helpmsg
=helpmsg_default
241 if auteur
in self
.ops
:
243 if auteur
in self
.overops
:
244 helpmsg
+=helpmsg_overops
245 for ligne
in helpmsg
.split("\n"):
246 serv
.privmsg(auteur
,ligne
)
248 if auteur
in self
.ops
:
250 if message
[1] in self
.chanlist
:
251 serv
.privmsg(auteur
,"Je suis déjà sur %s"%(message
[1]))
253 serv
.join(message
[1])
254 self
.chanlist
.append(message
[1])
255 self
.update_activity(message
[1],force
=True)
256 serv
.privmsg(auteur
,"Channels : "+" ".join(self
.chanlist
))
257 log(self
.serveur
,"priv",auteur
," ".join(message
))
259 serv
.privmsg(auteur
,"Channels : "+" ".join(self
.chanlist
))
263 if auteur
in self
.ops
and len(message
)>1:
264 if message
[1] in self
.chanlist
:
265 if not (message
[1] in self
.stay_channels
) or auteur
in self
.overops
:
266 self
.quitter(message
[1]," ".join(message
[2:]))
267 self
.chanlist
.remove(message
[1])
268 log(self
.serveur
,"priv",auteur
," ".join(message
)+"[successful]")
270 serv
.privmsg(auteur
,"Non, je reste !")
271 log(self
.serveur
,"priv",auteur
," ".join(message
)+"[failed]")
273 serv
.privmsg(auteur
,"Je ne suis pas sur %s"%(message
[1]))
277 if auteur
in self
.overops
:
279 if message
[1] in self
.stay_channels
:
280 serv
.privmsg(auteur
,"Je stay déjà sur %s."%(message
[1]))
281 log(self
.serveur
,"priv",auteur
," ".join(message
)+"[failed]")
283 self
.stay_channels
.append(message
[1])
284 serv
.privmsg(auteur
,"Stay channels : "+" ".join(self
.stay_channels
))
285 log(self
.serveur
,"priv",auteur
," ".join(message
)+"[successful]")
287 serv
.privmsg(auteur
,"Stay channels : "+" ".join(self
.stay_channels
))
291 if auteur
in self
.overops
:
293 if message
[1] in self
.stay_channels
:
294 self
.stay_channels
.remove(message
[1])
295 serv
.privmsg(auteur
,"Stay channels : "+" ".join(self
.stay_channels
))
296 log(self
.serveur
,"priv",auteur
," ".join(message
)+"[successful]")
298 serv
.privmsg(auteur
,"Je ne stay pas sur %s."%(message
[1]))
299 log(self
.serveur
,"priv",auteur
," ".join(message
)+"[failed]")
303 if auteur
in self
.ops
:
305 if message
[1] in self
.play_channels
:
306 serv
.privmsg(auteur
,"Je play déjà sur %s."%(message
[1]))
307 log(self
.serveur
,"priv",auteur
," ".join(message
)+"[failed]")
309 self
.play_channels
.append(message
[1])
310 self
.play_status
[message
[1]]=[0,time
.time()-3600]
311 serv
.privmsg(auteur
,"Play channels : "+" ".join(self
.play_channels
))
312 log(self
.serveur
,"priv",auteur
," ".join(message
)+"[successful]")
314 serv
.privmsg(auteur
,"Play channels : "+" ".join(self
.play_channels
))
318 if auteur
in self
.ops
:
320 if message
[1] in self
.play_channels
:
321 self
.play_channels
.remove(message
[1])
322 serv
.privmsg(auteur
,"Play channels : "+" ".join(self
.play_channels
))
323 log(self
.serveur
,"priv",auteur
," ".join(message
)+"[successful]")
325 serv
.privmsg(auteur
,"Je ne play pas sur %s."%(message
[1]))
326 log(self
.serveur
,"priv",auteur
," ".join(message
)+"[failed]")
330 if auteur
in self
.ops
:
332 if message
[1] in self
.quiet_channels
:
333 serv
.privmsg(auteur
,"Je me la ferme déjà sur %s"%(message
[1]))
334 log(self
.serveur
,"priv",auteur
," ".join(message
)+"[failed]")
336 self
.quiet_channels
.append(message
[1])
337 serv
.privmsg(auteur
,"Quiet channels : "+" ".join(self
.quiet_channels
))
338 log(self
.serveur
,"priv",auteur
," ".join(message
)+"[successful]")
340 serv
.privmsg(auteur
,"Quiet channels : "+" ".join(self
.quiet_channels
))
344 if auteur
in self
.ops
:
346 if message
[1] in self
.quiet_channels
:
347 self
.quiet_channels
.remove(message
[1])
348 serv
.privmsg(auteur
,"Quiet channels : "+" ".join(self
.quiet_channels
))
349 log(self
.serveur
,"priv",auteur
," ".join(message
)+"[successful]")
351 serv
.privmsg(auteur
,"Je ne me la ferme pas sur %s."%(message
[1]))
352 log(self
.serveur
,"priv",auteur
," ".join(message
)+"[failed]")
356 if auteur
in self
.ops
:
358 log(self
.serveur
,"priv",auteur
," ".join(message
)+"[successful]")
361 elif cmd
in ["states","status"]:
362 if auteur
in self
.overops
:
363 for k
in self
.play_status
.keys():
364 serv
.privmsg(auteur
,(u
"%s : %s"%(k
,"; ".join([unicode(i
) for i
in self
.play_status
[k
]]))).encode("utf8") )
366 if auteur
in self
.overops
and len(message
)>2:
367 serv
.privmsg(message
[1]," ".join(message
[2:]))
368 log(self
.serveur
,"priv",auteur
," ".join(message
))
369 elif len(message
)<=2:
370 serv
.privmsg(auteur
,"Syntaxe : SAY <channel> <message>")
374 if auteur
in self
.overops
:
375 log(self
.serveur
,"priv",auteur
," ".join(message
)+"[successful]")
379 if len(message
) in [3,4] and message
[1].lower()=="transfert":
380 scores
=self
.get_scores()
381 de
,to
=auteur
,message
[2]
382 value
=scores
.get(de
,0)
385 asked
=int(message
[3])
387 serv
.privmsg(auteur
,"Syntaxe : SCORE TRANSFERT <pseudo> [<n>]")
392 serv
.privmsg(auteur
,"Vous n'avez pas de points")
395 serv
.privmsg(auteur
,"Bien tenté…")
398 serv
.privmsg(auteur
,"Vous n'avez que %s points"%(value))
401 self
.add_score(de
,-asked
)
402 self
.add_score(to
,asked
)
403 serv
.privmsg(auteur
,"Transfert de %s points de %s à %s"%(asked
,de
,to
))
405 serv
.privmsg(auteur
,"Syntaxe : SCORE TRANSFERT <pseudo> [<n>]")
407 serv
.privmsg(auteur
,"Votre score : %s"%(self
.get_scores().get(auteur
,0)) )
410 scores
=self
.get_scores().items()
412 scores
.sort(lambda x
,y
:cmp(x
[1],y
[1]))
414 serv
.privmsg(auteur
,"Scores by score : "+" ; ".join(["%s %s"%(i
[0],i
[1]) for i
in scores
]))
416 scores
.sort(lambda x
,y
:cmp(x
[0].lower(),y
[0].lower()))
417 serv
.privmsg(auteur
,"Scores by pseudo : "+" ; ".join(["%s %s"%(i
[0],i
[1]) for i
in scores
]))
418 elif auteur
in self
.overops
:
419 souscmd
=message
[1].lower()
423 scores
=self
.get_scores()
424 if scores
.has_key(todelete
):
426 self
.save_scores(scores
)
427 serv
.privmsg(auteur
,"Score de %s supprimé"%(todelete))
429 serv
.privmsg(auteur
,"Ce score n'existe pas : %s"%(todelete))
431 serv
.privmsg(auteur
,"Syntaxe : SCORES DEL <pseudo>")
432 elif souscmd
in ["add","sub"]:
434 toadd
,val
=message
[2],message
[3]
438 serv
.privmsg(auteur
,"Syntaxe : SCORES {ADD|SUB} <pseudo> <n>")
442 self
.add_score(toadd
,val
)
443 serv
.privmsg(auteur
,"Done")
445 serv
.privmsg(auteur
,"Syntaxe : SCORES {ADD|SUB} <pseudo> <n>")
447 serv
.privmsg(auteur
,"Syntaxe : SCORES {DEL|ADD|SUB} <pseudo> [<n>]")
453 serv
.privmsg(auteur
,"Je n'ai pas compris. Essaye HELP…")
455 def on_pubmsg(self
, serv
, ev
):
456 if ignore_event(serv
, ev
):
458 auteur
= irclib
.nm_to_n(ev
.source())
460 message
= ev
.arguments()[0]
461 self
.update_activity(canal
,auteur
,message
)
463 test
=bot_unicode(message
)
464 except UnicodeBotError
:
465 if config
.utf8_trigger
and not canal
in self
.quiet_channels
:
466 serv
.privmsg(canal
, (u
"%s: %s"%(auteur
,random
.choice(config
.utf8_fail_answers
))).encode("utf8"))
469 pour_moi
,message
=self
.pourmoi(serv
,message
)
470 if pour_moi
and message
.split()!=[]:
471 cmd
=message
.split()[0].lower()
473 args
=" ".join(message
.split()[1:])
476 if cmd
in ["meurs","die","crève"]:
477 if auteur
in self
.overops
:
479 log(self
.serveur
,canal
,auteur
,message
+"[successful]")
481 serv
.privmsg(canal
,"%s: crève !"%(auteur))
482 log(self
.serveur
,canal
,auteur
,message
+"[failed]")
483 elif cmd
in ["meur", "meurt","meurre","meurres"] and not canal
in self
.quiet_channels
:
484 serv
.privmsg(canal
,'%s: Mourir, impératif, 2ème personne du singulier : "meurs" (de rien)'%(auteur))
485 elif cmd
== "reload":
486 if auteur
in self
.ops
:
487 log(self
.serveur
, canal
, auteur
, message
+"[successful]")
489 elif cmd
in ["part","leave","dégage"]:
490 if auteur
in self
.ops
and (not (canal
in self
.stay_channels
)
491 or auteur
in self
.overops
):
493 log(self
.serveur
,canal
,auteur
,message
+"[successful]")
494 self
.chanlist
.remove(canal
)
496 serv
.privmsg(canal
,"%s: Non, je reste !"%(auteur))
497 log(self
.serveur
,canal
,auteur
,message
+"[failed]")
499 elif cmd
in ["deviens","pseudo"]:
500 if auteur
in self
.ops
:
503 log(self
.serveur
,canal
,auteur
,message
+"[successful]")
504 elif cmd
in ["coucou"] and not canal
in self
.quiet_channels
:
505 serv
.privmsg(canal
,"%s: coucou"%(auteur))
506 elif cmd
in ["ping"] and not canal
in self
.quiet_channels
:
507 serv
.privmsg(canal
,"%s: pong"%(auteur))
508 elif cmd
in ["déconnaissance","deconnaissance","énigme","enigme","encore","aco","moo","moo !","moo !"]:
509 if canal
in self
.play_channels
:
510 if self
.play_status
.get(canal
,[-1])[0]==0:
512 self
.start_enigme(serv
,canal
)
514 serv
.privmsg(canal
,"%s: Je peux souffler une minute ?"%(auteur))
516 serv
.privmsg(canal
,("%s: Rappel : %s"%(auteur
,self
.play_status
[canal
][1])).encode("utf8") )
518 serv
.privmsg(canal
,"%s: pas ici…"%(auteur))
519 elif cmd
in ["score","!score"]:
520 serv
.privmsg(auteur
,"Votre score : %s"%(self
.get_scores().get(auteur
,0)) )
521 elif cmd
in ["scores","!scores"]:
522 scores
=self
.get_scores().items()
524 scores
.sort(lambda x
,y
:cmp(x
[1],y
[1]))
526 serv
.privmsg(auteur
,"Scores by score : "+" ; ".join(["%s %s"%(i
[0],i
[1]) for i
in scores
]))
528 scores
.sort(lambda x
,y
:cmp(x
[0].lower(),y
[0].lower()))
529 serv
.privmsg(auteur
,"Scores by pseudo : "+" ; ".join(["%s %s"%(i
[0],i
[1]) for i
in scores
]))
530 elif cmd
=="indice" and canal
in self
.play_channels
:
531 self
.give_indice(serv
,canal
,None)
532 elif is_tag(message
) and not canal
in self
.quiet_channels
:
533 if auteur
in self
.ops
:
534 action
=random
.choice(config
.tag_actions
)
535 serv
.action(canal
,action
.encode("utf8"))
536 self
.quiet_channels
.append(canal
)
538 answer
=random
.choice(config
.tag_answers
)
539 for ligne
in answer
.split("\n"):
540 serv
.privmsg(canal
,"%s: %s"%(auteur
,ligne
.encode("utf8")))
541 elif "Bâille, cru aile ou orld" in message
:
542 self
.mourir(u
"Un de mes easters eggs (non en fait j'en ai qu'un) a été découvert par %s !"%auteur
)
548 if self
.play_status
.get(canal
,[-1])[0] in [1,2]:
549 answer_regexp
=self
.play_status
[canal
][3]
550 answer
=self
.play_status
[canal
][4]
551 if reussi(message
.decode("utf8"),answer
,answer_regexp
,auteur
):
552 serv
.privmsg(canal
,(u
"%s: bravo ! (C'était %s)"%(auteur
,answer
)).encode("utf8"))
553 log(self
.serveur
,canal
,auteur
+"$win",message
)
554 self
.add_score(auteur
,1)
556 self
.play_status
[canal
]=[0,token
]
557 serv
.execute_delayed(random
.randrange(config
.Ttrig
*5,config
.Ttrig
*10),self
.start_enigme
,(serv
,canal
,token
))
559 def on_kick(self
,serv
,ev
):
560 auteur
= irclib
.nm_to_n(ev
.source())
561 channel
= ev
.target()
562 victime
= ev
.arguments()[0]
563 raison
= ev
.arguments()[1]
564 if victime
==self
.nick
:
565 log(self
.serveur
,"%s kické de %s par %s (raison : %s)" %(victime
,channel
,auteur
,raison
))
568 self
.update_activity(channel
,force
=True)
569 # on ne dit rien au rejoin
570 #l1,l2=config.kick_answers,config.kick_actions
571 #n1,n2=len(l1),len(l2)
572 #i=random.randrange(n1+n2)
574 # serv.action(channel,l2[i-n1].format(auteur).encode("utf8"))
576 # serv.privmsg(channel,l1[i].format(auteur).encode("utf8"))
578 def quitter(self
,chan
,leave_message
=None):
579 if leave_message
==None:
580 leave_message
=random
.choice(config
.leave_messages
)
581 self
.serv
.part(chan
,message
=leave_message
.encode("utf8"))
583 def mourir(self
,quit_message
=None):
584 if quit_message
==None:
585 quit_message
=random
.choice(config
.quit_messages
)
586 self
.die(msg
=quit_message
.encode("utf8"))
588 def get_scores(self
):
589 f
=open(config
.score_file
)
590 scores
=pickle
.load(f
)
594 def add_score(self
,pseudo
,value
):
595 scores
=self
.get_scores()
596 if scores
.has_key(pseudo
):
597 scores
[pseudo
]+=value
600 self
.save_scores(scores
)
602 def save_scores(self
,scores
):
603 f
=open(config
.score_file
,"w")
604 pickle
.dump(scores
,f
)
608 return self
.serv
.get_nickname()
609 nick
= property(_getnick
)
611 def update_activity(self
,canal
="",pseudo
="",message
="",force
=False):
612 if force
or (not pseudo
in config
.idle_bots
and all([not re
.match(ignore
, message
) for ignore
in config
.idle_messages
])):
613 self
.last_activity
[canal
]=time
.time()
614 def is_active(self
,canal
):
615 # Si on n'a pas d'info sur le chan, il est inactif
616 return time
.time()-self
.last_activity
.get(canal
, config
.idle_time
)<config
.idle_time
618 def reload(self
, auteur
=None):
620 if auteur
in [None, "SIGHUP"]:
621 towrite
= "Config reloaded" + " (SIGHUP received)"*(auteur
== "SIGHUP")
622 for to
in config
.report_bugs_to
:
623 self
.serv
.privmsg(to
, towrite
)
624 log(self
.serveur
, towrite
)
626 self
.serv
.privmsg(auteur
,"Config reloaded")
628 def start_as_daemon(self
, outfile
):
629 sys
.stderr
= Logger(outfile
)
633 class Logger(object):
634 """Pour écrire ailleurs que sur stdout"""
635 def __init__(self
, filename
="deconnaisseur.full.log"):
636 self
.filename
= filename
638 def write(self
, message
):
639 f
= open(self
.filename
, "a")
644 if __name__
=="__main__":
647 print "Usage : deconnaisseur.py <serveur> [--debug] [--no-output] [--daemon [--pidfile]] [--outfile]"
648 print " --outfile sans --no-output ni --daemon n'a aucun effet"
651 if "--daemon" in sys
.argv
:
652 thisfile
= os
.path
.realpath(__file__
)
653 thisdirectory
= thisfile
.rsplit("/", 1)[0]
654 os
.chdir(thisdirectory
)
658 if "debug" in sys
.argv
or "--debug" in sys
.argv
:
662 serveurs
={"a♡":"acoeur.crans.org","acoeur":"acoeur.crans.org","acoeur.crans.org":"acoeur.crans.org",
663 "irc":"irc.crans.org","crans":"irc.crans.org","irc.crans.org":"irc.crans.org"}
664 if "--no-output" in sys
.argv
or "--daemon" in sys
.argv
:
665 outfile
= "/var/log/bots/deconnaisseur.full.log"
668 if arg
[0].strip('-') in ["out", "outfile", "logfile"]:
670 sys
.stdout
= Logger(outfile
)
672 serveur
=serveurs
[serveur
]
674 print "Server Unknown : %s"%(serveur)
676 deconnaisseur
=Deconnaisseur(serveur
,debug
)
677 # Si on reçoit un SIGHUP, on reload la config
678 def sighup_handler(signum
, frame
):
679 deconnaisseur
.reload("SIGHUP")
680 signal
.signal(signal
.SIGHUP
, sighup_handler
)
682 child_pid
= os
.fork()
685 deconnaisseur
.start_as_daemon(outfile
)
687 # on enregistre le pid de deconnaisseur
688 pidfile
= "/var/run/bots/deconnaisseur.pid"
691 if arg
[0].strip('-') in ["pidfile"]:
693 f
= open(pidfile
, "w")
694 f
.write("%s\n" % child_pid
)
697 deconnaisseur
.start()