4 # Codé par 20-100 le 23/04/12
6 # Un bot IRC qui sort des déconnaissances
15 from remplace_accents
import remplace_accents
17 # Oui, j'ai recodé ma version d'irclib pour pouvoir rattrapper les SIGHUP
18 sys
.path
.insert(0, "/home/vincent/scripts/python-myirclib")
23 config_password
="PatrickSébastien"
24 config_pseudo
="deconnaisseur"
25 config_chanlist
=["#bot","#flood"]
26 config_play_channels
=["#flood"]
27 config_stay_channels
=["#flood","#bot"]
28 config_overops
=["[20-100]","[20-100]_","PEB"]
29 config_ops
=["Nit","Eguel","Harry"]
31 config_source_file
="deconnaissances.txt"
32 config_played_file_template
="played.%s.txt" #il faut rajouter le nom du serveur
33 def get_config_played_file(serveur
):
34 serveurs
={"acoeur.crans.org":"acoeur","irc.crans.org":"crans"}
35 return config_played_file_template
%(serveurs
[serveur
])
36 ttrig
=120 #time trigger (normalement 120, mais diminué pour les tests)
37 Ttrig
=600 #between two enigms (600)
38 config_time_incompressible
=15 #on peut pas retrigger en dessous de ce temps (60)
39 config_time_incompressible_clue
=60 #on peut pas forcer la demande d'indice en dessous
41 config_score_file
="scores.pickle"
43 config_tag_triggers
=[u
"t(|a)g",u
"ta gueule",u
"la ferme",u
"ferme( |-)la",u
"tais-toi",u
"chut"]
44 config_tag_actions
=[u
"se tait",u
"ferme sa gueule",u
"se la ferme",u
"la ferme"]
45 config_tag_answers
=[u
"J'me tais si j'veux !",
46 u
"Je t'entends pas :°",
48 u
"Non, j'ai pas envie",
49 u
"Peut-être quand toi tu la fermeras, et encore…"]
52 config_level3
=["[20-100]","Petite-Peste","PEB","Constance","pika"]
54 config_debug_stdout
= True
55 config_logfile_template
="deconnaisseur.%s.log"
56 def get_config_logfile(serveur
):
57 serveurs
={"acoeur.crans.org":"acoeur","irc.crans.org":"crans"}
58 return config_logfile_template
%(serveurs
[serveur
])
60 config_quit_messages
=[u
"Se décrocher la mâchoire, pas cuit bras d'oiseau ou métalld précieuxld"]
62 config_leave_messages
=[u
"On continuera à jouer plus tard ;)"]
64 # Quand personne ne cause, on finit par se taire
65 # temps au bout duquel, si personne n'a parlé, on se tait
66 config_idle_time
=20*60
67 # liste des bots, qui ne sont pas considérés comme de l'activité
68 config_idle_bots
=["deconnaisseur","Basile","historien","hung","salesman","Shadobot","Wen","___","Sanctuary","Saturnin"]
70 class UnicodeBotError(Exception):
72 def bot_unicode(chain
):
75 except UnicodeDecodeError:
78 def log(serveur
,channel
,auteur
=None,message
=None):
79 f
=open(get_config_logfile(serveur
),"a")
80 if auteur
==message
==None:
81 # alors c'est que c'est pas un channel mais juste une ligne de log
82 chain
="%s %s"%(time
.strftime("%F %T"),channel
)
84 chain
="%s [%s:%s] %s"%(time
.strftime("%F %T"),channel
,auteur
,message
)
86 if config_debug_stdout
:
91 def reussi(message
,answer
,answer_regexp
,auteur
):
92 if auteur
in config_level3
:
93 return answer
in message
94 if auteur
in config_level2
:
95 return remplace_accents(answer
) in message
97 if re
.match(remplace_accents(answer_regexp
).lower(),remplace_accents(message
).lower()):
100 def is_something(chain
,matches
,avant
=u
".*(?:^| )",apres
=u
"(?:$|\.| |,|;).*",case_sensitive
=False,debug
=False):
102 chain
=unicode(chain
,"utf8")
104 chain
=unicode(chain
,"utf8").lower()
105 allmatches
="("+"|".join(matches
)+")"
106 reg
=(avant
+allmatches
+apres
).lower()
107 o
=re
.match(reg
,chain
)
111 return is_something(chain
,config_tag_triggers
)
113 class RefuseError(Exception):
116 class Deconnaisseur(ircbot
.SingleServerIRCBot
):
117 def __init__(self
,serveur
,debug
=False):
118 temporary_pseudo
=config_pseudo
+str(random
.randrange(10000,100000))
119 ircbot
.SingleServerIRCBot
.__init
__(self
, [(serveur
, 6667)],
120 temporary_pseudo
,"Un bot irc.[flagellez 20-100, il le mérite]", 10)
123 self
.overops
=config_overops
124 self
.ops
=self
.overops
+config_ops
125 self
.chanlist
=config_chanlist
126 self
.stay_channels
=config_stay_channels
127 self
.play_channels
=config_play_channels
128 self
.play_status
={i
:[0] for i
in self
.play_channels
}
129 self
.last_activity
={}
130 self
.quiet_channels
=[]
132 def give_me_my_pseudo(self
,serv
):
133 serv
.privmsg("NickServ","RECOVER %s %s"%(config_pseudo
,config_password
))
134 serv
.privmsg("NickServ","RELEASE %s %s"%(config_pseudo
,config_password
))
136 serv
.nick(config_pseudo
)
138 def on_welcome(self
, serv
, ev
):
139 self
.serv
=serv
# ça serv ira :)
140 self
.give_me_my_pseudo(serv
)
141 serv
.privmsg("NickServ","identify %s"%(config_password))
142 log(self
.serveur
,"Connected")
144 self
.chanlist
=["#bot"]
145 self
.play_channels
=["#bot"]
146 for c
in self
.chanlist
:
147 log(self
.serveur
,"JOIN %s"%(c))
149 self
.update_activity(c
,"") # la chaîne vide ne sera jamais un nom de bot et donc marchera toujours
150 for c
in self
.play_channels
:
151 token
=time
.time()-3600
152 self
.play_status
[c
]=[0,token
]
153 serv
.execute_delayed(random
.randrange(ttrig
),self
.start_enigme
,(serv
,c
,token
))
155 def start_enigme(self
,serv
,channel
,token
=None):
156 # On reste silencieux si lechan n'est pas actif
157 if not self
.is_active(channel
):
158 serv
.execute_delayed(ttrig
*5,self
.start_enigme
,(serv
,channel
,token
))
160 if self
.play_status
[channel
][0]==0 and channel
in self
.play_channels
:
162 if token
==self
.play_status
[channel
][-1]:
165 if time
.time() > self
.play_status
[channel
][-1]+config_time_incompressible
:
170 enigme
,indice
,answer_reg
,answer
=self
.get_enigme()
171 log(self
.serveur
,channel
,u
"$Énigme$".encode("utf8"),("%s; %s; %s; %s"%(enigme
, indice
, answer_reg
, answer
)).encode("utf8"))
172 serv
.privmsg(channel
,enigme
.encode("utf8"))
174 self
.play_status
[channel
]=[1,enigme
,indice
,answer_reg
,answer
,token
]
175 serv
.execute_delayed(random
.randrange(ttrig
*3,ttrig
*5),self
.give_indice
,(serv
,channel
,token
))
178 def give_indice(self
,serv
,channel
,token
):
179 if self
.play_status
[channel
][0]==1:
181 # c'est donc que l'indice a été demandé
182 if self
.play_status
[channel
][-1]+config_time_incompressible_clue
<time
.time():
183 token
=self
.play_status
[channel
][-1]
184 if self
.play_status
[channel
][-1]==token
:
185 indice
=self
.play_status
[channel
][2]
186 serv
.privmsg(channel
,"indice : %s"%(indice).encode("utf8"))
187 self
.play_status
[channel
][0]=2
188 serv
.execute_delayed(random
.randrange(ttrig
*1,ttrig
*3),self
.give_answer
,(serv
,channel
,token
))
189 def give_answer(self
,serv
,channel
,token
):
190 if self
.play_status
[channel
][0]==2 and self
.play_status
[channel
][-1]==token
:
191 answer
=self
.play_status
[channel
][4]
192 serv
.privmsg(channel
,"C'était : %s"%(answer).encode("utf8"))
194 self
.play_status
[channel
]=[0,token
]
195 serv
.execute_delayed(random
.randrange(Ttrig
*5,Ttrig
*10),self
.start_enigme
,(serv
,channel
,token
))
197 def get_enigme(self
):
198 # on récupère les déconnaissances
199 f
=open(config_source_file
)
202 l
=re
.findall("%\n(.*)\n(.*)\n(.*)\n(.*)\n(.*)\n",t
)
203 dec
={int(i
[0]):list(i
[1:]) for i
in l
if len(i
)==5}
204 # on va chercher combien de fois elles ont été jouées
205 played_file
=get_config_played_file(self
.serveur
)
209 l
=re
.findall("(.*):(.*)",t
)
210 played
={int(i
[0]):int(i
[1]) for i
in l
}
211 # on récupère le nombre d'occurrences le plus faible
212 mini
=min(played
.values())
213 # on choisit un id dans ceux qui ont ce nombre d'occurences
214 id_choisi
=random
.choice([k
for k
,v
in played
.items() if v
==mini
])
215 enigme
,indice
,answer_reg
,answer
=dec
[id_choisi
]
216 # on incrémente la choisie
218 # on enregistre le played_file
219 f
=open(played_file
,"w")
220 f
.write("\n".join(["%-3s : %s"%(k
,v
) for k
,v
in played
.items()]))
222 return enigme
.decode("utf8"),indice
.decode("utf8"),answer_reg
.decode("utf8"),answer
.decode("utf8")
224 def pourmoi(self
, serv
, message
):
227 if message
[:size
]==pseudo
and len(message
)>size
and message
[size
]==":":
228 return (True,message
[size
+1:].strip(" "))
230 return (False,message
)
232 def on_privmsg(self
, serv
, ev
):
233 message
=ev
.arguments()[0]
234 auteur
= irclib
.nm_to_n(ev
.source())
236 test
=bot_unicode(message
)
237 except UnicodeBotError
:
239 "Euh, tu fais de la merde avec ton encodage là, j'ai failli crasher…")
241 message
=message
.split()
242 cmd
=message
[0].lower()
245 helpmsg_default
="""Liste des commandes :
246 HELP Affiche ce message d'aide
247 SCORE Affiche ton score (SCORE TRANSFERT <pseudo> [<n>] pour transférer des points)
248 SCORES Affiche les scores"""
250 JOIN Faire rejoindre un channel (sans paramètres, donne la liste des chans actuels)
251 LEAVE Faire quitter un channel
252 PLAY Passe un channel en mode "jouer"
253 NOPLAY Passe un channel en mode "ne pas jouer"
254 QUIET Se taire sur un channel
255 NOQUIET Opposé de QUIET"""
257 SCORES {DEL|ADD|SUB} Tu veux un dessin ?
258 SAY Fais envoyer un message sur un chan ou à une personne
259 STAY Ignorera les prochains LEAVE pour un chan
260 NOSTAY Opposé de STAY
261 STATUS Montre l'état courant
263 helpmsg
=helpmsg_default
264 if auteur
in self
.ops
:
266 if auteur
in self
.overops
:
267 helpmsg
+=helpmsg_overops
268 for ligne
in helpmsg
.split("\n"):
269 serv
.privmsg(auteur
,ligne
)
271 if auteur
in self
.ops
:
273 if message
[1] in self
.chanlist
:
274 serv
.privmsg(auteur
,"Je suis déjà sur %s"%(message
[1]))
276 serv
.join(message
[1])
277 self
.chanlist
.append(message
[1])
278 self
.update_activity(message
[1],"")
279 serv
.privmsg(auteur
,"Channels : "+" ".join(self
.chanlist
))
280 log(self
.serveur
,"priv",auteur
," ".join(message
))
282 serv
.privmsg(auteur
,"Channels : "+" ".join(self
.chanlist
))
286 if auteur
in self
.ops
and len(message
)>1:
287 if message
[1] in self
.chanlist
:
288 if not (message
[1] in self
.stay_channels
) or auteur
in self
.overops
:
289 self
.quitter(message
[1]," ".join(message
[2:]))
290 self
.chanlist
.remove(message
[1])
291 log(self
.serveur
,"priv",auteur
," ".join(message
)+"[successful]")
293 serv
.privmsg(auteur
,"Non, je reste !")
294 log(self
.serveur
,"priv",auteur
," ".join(message
)+"[failed]")
296 serv
.privmsg(auteur
,"Je ne suis pas sur %s"%(message
[1]))
300 if auteur
in self
.overops
:
302 if message
[1] in self
.stay_channels
:
303 serv
.privmsg(auteur
,"Je stay déjà sur %s."%(message
[1]))
304 log(self
.serveur
,"priv",auteur
," ".join(message
)+"[failed]")
306 self
.stay_channels
.append(message
[1])
307 serv
.privmsg(auteur
,"Stay channels : "+" ".join(self
.stay_channels
))
308 log(self
.serveur
,"priv",auteur
," ".join(message
)+"[successful]")
310 serv
.privmsg(auteur
,"Stay channels : "+" ".join(self
.stay_channels
))
314 if auteur
in self
.overops
:
316 if message
[1] in self
.stay_channels
:
317 self
.stay_channels
.remove(message
[1])
318 serv
.privmsg(auteur
,"Stay channels : "+" ".join(self
.stay_channels
))
319 log(self
.serveur
,"priv",auteur
," ".join(message
)+"[successful]")
321 serv
.privmsg(auteur
,"Je ne stay pas sur %s."%(message
[1]))
322 log(self
.serveur
,"priv",auteur
," ".join(message
)+"[failed]")
326 if auteur
in self
.ops
:
328 if message
[1] in self
.play_channels
:
329 serv
.privmsg(auteur
,"Je play déjà sur %s."%(message
[1]))
330 log(self
.serveur
,"priv",auteur
," ".join(message
)+"[failed]")
332 self
.play_channels
.append(message
[1])
333 self
.play_status
[message
[1]]=[0,time
.time()-3600]
334 serv
.privmsg(auteur
,"Play channels : "+" ".join(self
.play_channels
))
335 log(self
.serveur
,"priv",auteur
," ".join(message
)+"[successful]")
337 serv
.privmsg(auteur
,"Play channels : "+" ".join(self
.play_channels
))
341 if auteur
in self
.ops
:
343 if message
[1] in self
.play_channels
:
344 self
.play_channels
.remove(message
[1])
345 serv
.privmsg(auteur
,"Play channels : "+" ".join(self
.play_channels
))
346 log(self
.serveur
,"priv",auteur
," ".join(message
)+"[successful]")
348 serv
.privmsg(auteur
,"Je ne play pas sur %s."%(message
[1]))
349 log(self
.serveur
,"priv",auteur
," ".join(message
)+"[failed]")
353 if auteur
in self
.ops
:
355 if message
[1] in self
.quiet_channels
:
356 serv
.privmsg(auteur
,"Je me la ferme déjà sur %s"%(message
[1]))
357 log(self
.serveur
,"priv",auteur
," ".join(message
)+"[failed]")
359 self
.quiet_channels
.append(message
[1])
360 serv
.privmsg(auteur
,"Quiet channels : "+" ".join(self
.quiet_channels
))
361 log(self
.serveur
,"priv",auteur
," ".join(message
)+"[successful]")
363 serv
.privmsg(auteur
,"Quiet channels : "+" ".join(self
.quiet_channels
))
367 if auteur
in self
.ops
:
369 if message
[1] in self
.quiet_channels
:
370 self
.quiet_channels
.remove(message
[1])
371 serv
.privmsg(auteur
,"Quiet channels : "+" ".join(self
.quiet_channels
))
372 log(self
.serveur
,"priv",auteur
," ".join(message
)+"[successful]")
374 serv
.privmsg(auteur
,"Je ne me la ferme pas sur %s."%(message
[1]))
375 log(self
.serveur
,"priv",auteur
," ".join(message
)+"[failed]")
378 elif cmd
in ["states","status"]:
379 if auteur
in self
.overops
:
380 for k
in self
.play_status
.keys():
381 serv
.privmsg(auteur
,(u
"%s : %s"%(k
,"; ".join([unicode(i
) for i
in self
.play_status
[k
]]))).encode("utf8") )
383 if auteur
in self
.overops
and len(message
)>2:
384 serv
.privmsg(message
[1]," ".join(message
[2:]))
385 log(self
.serveur
,"priv",auteur
," ".join(message
))
386 elif len(message
)<=2:
387 serv
.privmsg(auteur
,"Syntaxe : SAY <channel> <message>")
391 if auteur
in self
.overops
:
392 log(self
.serveur
,"priv",auteur
," ".join(message
)+"[successful]")
396 if len(message
) in [3,4] and message
[1].lower()=="transfert":
397 scores
=self
.get_scores()
398 de
,to
=auteur
,message
[2]
399 value
=scores
.get(de
,0)
402 asked
=int(message
[3])
404 serv
.privmsg(auteur
,"Syntaxe : SCORE TRANSFERT <pseudo> [<n>]")
409 serv
.privmsg(auteur
,"Vous n'avez pas de points")
412 serv
.privmsg(auteur
,"Bien tenté…")
415 serv
.privmsg(auteur
,"Vous n'avez que %s points"%(value))
418 self
.add_score(de
,-asked
)
419 self
.add_score(to
,asked
)
420 serv
.privmsg(auteur
,"Transfert de %s points de %s à %s"%(asked
,de
,to
))
422 serv
.privmsg(auteur
,"Syntaxe : SCORE TRANSFERT <pseudo> [<n>]")
424 serv
.privmsg(auteur
,"Votre score : %s"%(self
.get_scores().get(auteur
,0)) )
427 scores
=self
.get_scores().items()
429 scores
.sort(lambda x
,y
:cmp(x
[1],y
[1]))
431 serv
.privmsg(auteur
,"Scores by score : "+" ; ".join(["%s %s"%(i
[0],i
[1]) for i
in scores
]))
433 scores
.sort(lambda x
,y
:cmp(x
[0].lower(),y
[0].lower()))
434 serv
.privmsg(auteur
,"Scores by pseudo : "+" ; ".join(["%s %s"%(i
[0],i
[1]) for i
in scores
]))
435 elif auteur
in self
.overops
:
436 souscmd
=message
[1].lower()
440 scores
=self
.get_scores()
441 if scores
.has_key(todelete
):
443 self
.save_scores(scores
)
444 serv
.privmsg(auteur
,"Score de %s supprimé"%(todelete))
446 serv
.privmsg(auteur
,"Ce score n'existe pas : %s"%(todelete))
448 serv
.privmsg(auteur
,"Syntaxe : SCORES DEL <pseudo>")
449 elif souscmd
in ["add","sub"]:
451 toadd
,val
=message
[2],message
[3]
455 serv
.privmsg(auteur
,"Syntaxe : SCORES {ADD|SUB} <pseudo> <n>")
459 self
.add_score(toadd
,val
)
460 serv
.privmsg(auteur
,"Done")
462 serv
.privmsg(auteur
,"Syntaxe : SCORES {ADD|SUB} <pseudo> <n>")
464 serv
.privmsg(auteur
,"Syntaxe : SCORES {DEL|ADD|SUB} <pseudo> [<n>]")
470 serv
.privmsg(auteur
,"Je n'ai pas compris. Essaye HELP…")
472 def on_pubmsg(self
, serv
, ev
):
473 auteur
= irclib
.nm_to_n(ev
.source())
475 message
= ev
.arguments()[0]
476 self
.update_activity(canal
,auteur
)
478 test
=bot_unicode(message
)
479 except UnicodeBotError
:
480 if not canal
in self
.quiet_channels
:
482 "%s: Euh, tu fais de la merde avec ton encodage là, j'ai failli crasher…"%(auteur))
485 pour_moi
,message
=self
.pourmoi(serv
,message
)
486 if pour_moi
and message
.split()!=[]:
487 cmd
=message
.split()[0].lower()
489 args
=" ".join(message
.split()[1:])
492 if cmd
in ["meurs","die","crève"]:
493 if auteur
in self
.overops
:
495 log(self
.serveur
,canal
,auteur
,message
+"[successful]")
497 serv
.privmsg(canal
,"%s: crève !"%(auteur))
498 log(self
.serveur
,canal
,auteur
,message
+"[failed]")
499 if cmd
in ["meur", "meurt","meurre","meurres"] and not canal
in self
.quiet_channels
:
500 serv
.privmsg(canal
,'%s: Mourir, impératif, 2ème personne du singulier : "meurs" (de rien)'%(auteur))
501 if cmd
in ["part","leave","dégage"]:
502 if auteur
in self
.ops
and (not (canal
in self
.stay_channels
)
503 or auteur
in self
.overops
):
505 log(self
.serveur
,canal
,auteur
,message
+"[successful]")
506 self
.chanlist
.remove(canal
)
508 serv
.privmsg(canal
,"%s: Non, je reste !"%(auteur))
509 log(self
.serveur
,canal
,auteur
,message
+"[failed]")
511 if cmd
in ["deviens","pseudo"]:
512 if auteur
in self
.ops
:
515 log(self
.serveur
,canal
,auteur
,message
+"[successful]")
516 if cmd
in ["coucou"] and not canal
in self
.quiet_channels
:
517 serv
.privmsg(canal
,"%s: coucou"%(auteur))
518 if cmd
in ["ping"] and not canal
in self
.quiet_channels
:
519 serv
.privmsg(canal
,"%s: pong"%(auteur))
520 if cmd
in ["déconnaissance","deconnaissance","énigme","enigme","encore"]:
521 if canal
in self
.play_channels
:
522 if self
.play_status
.get(canal
,[-1])[0]==0:
524 self
.start_enigme(serv
,canal
)
526 serv
.privmsg(canal
,"%s: Je peux souffler une minute ?"%(auteur))
528 serv
.privmsg(canal
,("%s: Rappel : %s"%(auteur
,self
.play_status
[canal
][1])).encode("utf8") )
530 serv
.privmsg(canal
,"%s: pas ici…"%(auteur))
531 if cmd
in ["score","!score"]:
532 serv
.privmsg(auteur
,"Votre score : %s"%(self
.get_scores().get(auteur
,0)) )
533 if cmd
in ["scores","!scores"]:
534 scores
=self
.get_scores().items()
536 scores
.sort(lambda x
,y
:cmp(x
[1],y
[1]))
538 serv
.privmsg(auteur
,"Scores by score : "+" ; ".join(["%s %s"%(i
[0],i
[1]) for i
in scores
]))
540 scores
.sort(lambda x
,y
:cmp(x
[0].lower(),y
[0].lower()))
541 serv
.privmsg(auteur
,"Scores by pseudo : "+" ; ".join(["%s %s"%(i
[0],i
[1]) for i
in scores
]))
542 if cmd
=="indice" and canal
in self
.play_channels
:
543 self
.give_indice(serv
,canal
,None)
544 if is_tag(message
) and not canal
in self
.quiet_channels
:
545 if auteur
in self
.ops
:
546 action
=random
.choice(config_tag_actions
)
547 serv
.action(canal
,action
.encode("utf8"))
548 self
.quiet_channels
.append(canal
)
550 answer
=random
.choice(config_tag_answers
)
551 for ligne
in answer
.split("\n"):
552 serv
.privmsg(canal
,"%s: %s"%(auteur
,ligne
.encode("utf8")))
553 if "Bâille, cru aile ou orld" in message
:
554 self
.mourir(u
"Un de mes easters eggs (non en fait j'en ai qu'un) a été découvert par %s !"%auteur
)
560 if self
.play_status
.get(canal
,[-1])[0] in [1,2]:
561 answer_regexp
=self
.play_status
[canal
][3]
562 answer
=self
.play_status
[canal
][4]
563 if reussi(message
.decode("utf8"),answer
,answer_regexp
,auteur
):
564 serv
.privmsg(canal
,(u
"%s: bravo ! (C'était %s)"%(auteur
,answer
)).encode("utf8"))
565 log(self
.serveur
,canal
,auteur
+"$win",message
)
566 self
.add_score(auteur
,1)
568 self
.play_status
[canal
]=[0,token
]
569 serv
.execute_delayed(random
.randrange(Ttrig
*5,Ttrig
*10),self
.start_enigme
,(serv
,canal
,token
))
571 def on_kick(self
,serv
,ev
):
572 auteur
= irclib
.nm_to_n(ev
.source())
573 channel
= ev
.target()
574 victime
= ev
.arguments()[0]
575 raison
= ev
.arguments()[1]
576 if victime
==self
.nick
:
577 log(self
.serveur
,"%s kické de %s par %s (raison : %s)" %(victime
,channel
,auteur
,raison
))
580 self
.update_activity(channel
,"")
581 # on ne dit rien au rejoin
582 #l1,l2=config_kick_answers,config_kick_actions
583 #n1,n2=len(l1),len(l2)
584 #i=random.randrange(n1+n2)
586 # serv.action(channel,l2[i-n1].format(auteur).encode("utf8"))
588 # serv.privmsg(channel,l1[i].format(auteur).encode("utf8"))
590 def quitter(self
,chan
,leave_message
=None):
591 if leave_message
==None:
592 leave_message
=random
.choice(config_leave_messages
)
593 self
.serv
.part(chan
,message
=leave_message
.encode("utf8"))
595 def mourir(self
,quit_message
=None):
596 if quit_message
==None:
597 quit_message
=random
.choice(config_quit_messages
)
598 self
.die(msg
=quit_message
.encode("utf8"))
600 def get_scores(self
):
601 f
=open(config_score_file
)
602 scores
=pickle
.load(f
)
606 def add_score(self
,pseudo
,value
):
607 scores
=self
.get_scores()
608 if scores
.has_key(pseudo
):
609 scores
[pseudo
]+=value
612 self
.save_scores(scores
)
614 def save_scores(self
,scores
):
615 f
=open(config_score_file
,"w")
616 pickle
.dump(scores
,f
)
620 return self
.serv
.get_nickname()
621 nick
= property(_getnick
)
623 def update_activity(self
,canal
,pseudo
):
624 if not pseudo
in config_idle_bots
:
625 self
.last_activity
[canal
]=time
.time()
626 def is_active(self
,canal
):
627 return time
.time()-self
.last_activity
[canal
]<config_idle_time
629 def start_as_daemon(self
, outfile
):
630 sys
.stderr
= Logger(outfile
)
634 class Logger(object):
635 """Pour écrire ailleurs que sur stdout"""
636 def __init__(self
, filename
="deconnaisseur.full.log"):
637 self
.filename
= filename
639 def write(self
, message
):
640 f
= open(self
.filename
, "a")
645 if __name__
=="__main__":
648 print "Usage : deconnaisseur.py <serveur> [--debug] [--no-output] [--daemon [--pidfile]] [--outfile]"
649 print " --outfile sans --no-output ni --daemon n'a aucun effet"
652 if "--daemon" in sys
.argv
:
653 thisfile
= os
.path
.realpath(__file__
)
654 thisdirectory
= thisfile
.rsplit("/", 1)[0]
655 os
.chdir(thisdirectory
)
659 if "debug" in sys
.argv
or "--debug" in sys
.argv
:
663 serveurs
={"a♡":"acoeur.crans.org","acoeur":"acoeur.crans.org","acoeur.crans.org":"acoeur.crans.org",
664 "irc":"irc.crans.org","crans":"irc.crans.org","irc.crans.org":"irc.crans.org"}
665 if "--no-output" in sys
.argv
or "--daemon" in sys
.argv
:
666 outfile
= "/var/log/bots/deconnaisseur.full.log"
669 if arg
[0].strip('-') in ["out", "outfile", "logfile"]:
671 sys
.stdout
= Logger(outfile
)
673 serveur
=serveurs
[serveur
]
675 print "Server Unknown : %s"%(serveur)
677 deconnaisseur
=Deconnaisseur(serveur
,debug
)
679 child_pid
= os
.fork()
682 deconnaisseur
.start_as_daemon(outfile
)
684 # on enregistre le pid de deconnaisseur
685 pidfile
= "/var/run/bots/deconnaisseur.pid"
688 if arg
[0].strip('-') in ["pidfile"]:
690 f
= open(pidfile
, "w")
691 f
.write("%s\n" % child_pid
)
694 deconnaisseur
.start()