4 # Codé par 20-100 le 25/05/12
6 # Un bot IRC qui pose des questions d'histoire
15 from cast_as_date
import *
17 config_password
="EtTaMère,ElleEstNéeQuand?"
18 config_pseudo
="historien"
19 config_chanlist
=["#bot","#flood"]
20 config_play_channels
=["#flood"]
21 config_stay_channels
=["#flood","#bot"]
22 config_overops
=["[20-100]","[20-100]_"]
23 config_ops
=["PEB","Petite-Peste"]
25 config_source_file
="dates.txt"
26 config_played_file_template
="played.%s.txt" #il faut rajouter le nom du serveur
27 def get_config_played_file(serveur
):
28 serveurs
={"acoeur.crans.org":"acoeur","irc.crans.org":"crans"}
29 return config_played_file_template
%(serveurs
[serveur
])
30 ttrig
=120 #time trigger (normalement 120, mais diminué pour les tests)
31 Ttrig
=600 #between two enigms
32 config_time_incompressible
=15 #on peut pas retrigger en dessous de ce temps (60)
33 config_time_incompressible_clue
=60 #on peut pas forcer la demande d'indice en dessous
35 config_score_file
="scores.pickle"
37 config_tag_triggers
=[u
"t(|a)g",u
"ta gueule",u
"la ferme",u
"ferme( |-)la",u
"tais-toi",u
"chut"]
38 config_tag_actions
=[u
"se tait",u
"ferme sa gueule",u
"se la ferme",u
"la ferme"]
39 config_tag_answers
=[u
"J'me tais si j'veux !",
40 u
"Je t'entends pas :°",
42 u
"Non, j'ai pas envie",
43 u
"Peut-être quand toi tu la fermeras, et encore…"]
48 config_debug_stdout
= True
49 config_logfile_template
="historien.%s.log"
50 def get_config_logfile(serveur
):
51 serveurs
={"acoeur.crans.org":"acoeur","irc.crans.org":"crans"}
52 return config_logfile_template
%(serveurs
[serveur
])
54 config_quit_messages
=[u
"%s : %s quitte le serveur IRC"]
56 config_leave_messages
=[u
"%s : %s quitte le channel"]
58 # Quand personne ne cause, on finit par se taire
59 # temps au bout duquel, si personne n'a parlé, on se tait
60 config_idle_time
=20*60
61 # liste des bots, qui ne sont pas considérés comme de l'activité
62 config_idle_bots
=["deconnaisseur","Basile","historien","hung","salesman","Shadobot","Wen","___"]
64 class UnicodeBotError(Exception):
66 def bot_unicode(chain
):
69 except UnicodeDecodeError:
72 def log(serveur
,channel
,auteur
=None,message
=None):
73 f
=open(get_config_logfile(serveur
),"a")
74 if auteur
==message
==None:
75 # alors c'est que c'est pas un channel mais juste une ligne de log
76 chain
="%s %s"%(time
.strftime("%F %T"),channel
)
78 chain
="%s [%s:%s] %s"%(time
.strftime("%F %T"),channel
,auteur
,message
)
80 if config_debug_stdout
:
89 config_noscore
=["[20-100]","[20-100]_"] # parce que 20-100 est nul en histoire
91 class GoodCentury(Exception):
94 def reussi(message
,answer
,auteur
):
95 if auteur
in config_level3
:
96 return answer
in message
97 if auteur
in config_level2
:
98 return answer
in message
101 date
=cast_as_date(message
.lower().strip())
102 except ThisIsNotADate
:
104 realdate
=map(lambda x
:int(x
), answer
.split('/'))
107 if date
[0]==realdate
[0]:
108 score
=config_score_annee
109 if date
[1]==realdate
[1]:
110 score
+=config_score_mois
111 if date
[2]==realdate
[2]:
112 score
+=config_score_jour
113 elif date
[0]/100 == realdate
[0]/100:
117 def is_something(chain
,matches
,avant
=u
".*(?:^| )",apres
=u
"(?:$|\.| |,|;).*",case_sensitive
=False,debug
=False):
119 chain
=unicode(chain
,"utf8")
121 chain
=unicode(chain
,"utf8").lower()
122 allmatches
="("+"|".join(matches
)+")"
123 reg
=(avant
+allmatches
+apres
).lower()
124 o
=re
.match(reg
,chain
)
128 return is_something(chain
,config_tag_triggers
)
130 class RefuseError(Exception):
133 class Historien(ircbot
.SingleServerIRCBot
):
134 def __init__(self
,serveur
,debug
=False):
135 temporary_pseudo
=config_pseudo
+str(random
.randrange(10000,100000))
136 ircbot
.SingleServerIRCBot
.__init
__(self
, [(serveur
, 6667)],
137 temporary_pseudo
,"Un bot irc qui a au moins l'agreg d'histoire", 10)
140 self
.overops
=config_overops
141 self
.ops
=self
.overops
+config_ops
142 self
.chanlist
=config_chanlist
143 self
.stay_channels
=config_stay_channels
144 self
.play_channels
=config_play_channels
145 self
.play_status
={i
:[0] for i
in self
.play_channels
}
146 self
.last_activity
={}
147 self
.quiet_channels
=[]
149 def give_me_my_pseudo(self
,serv
):
150 serv
.privmsg("NickServ","RECOVER %s %s"%(config_pseudo
,config_password
))
151 serv
.privmsg("NickServ","RELEASE %s %s"%(config_pseudo
,config_password
))
153 serv
.nick(config_pseudo
)
155 def on_welcome(self
, serv
, ev
):
156 self
.serv
=serv
# ça serv ira :)
157 self
.give_me_my_pseudo(serv
)
158 serv
.privmsg("NickServ","identify %s"%(config_password))
159 log(self
.serveur
,"Connected")
161 self
.chanlist
=["#bot"]
162 self
.play_channels
=["#bot"]
163 for c
in self
.chanlist
:
164 log(self
.serveur
,"JOIN %s"%(c))
166 self
.update_activity(c
,"") # la chaîne vide ne sera jamais un nom de bot et donc marchera toujours
167 for c
in self
.play_channels
:
168 token
=time
.time()-3600
169 self
.play_status
[c
]=[0,token
]
170 serv
.execute_delayed(random
.randrange(ttrig
),self
.start_enigme
,(serv
,c
,token
))
172 def start_enigme(self
,serv
,channel
,token
=None):
173 # On reste silencieux si lechan n'est pas actif
174 if not self
.is_active(channel
):
175 serv
.execute_delayed(ttrig
*5,self
.start_enigme
,(serv
,channel
,token
))
177 if self
.play_status
[channel
][0]==0 and channel
in self
.play_channels
:
179 if token
==self
.play_status
[channel
][-1]:
182 if time
.time() > self
.play_status
[channel
][-1]+config_time_incompressible
:
187 date
,evenement
=self
.get_enigme()
188 log(self
.serveur
,channel
,u
"$Date$".encode("utf8"),("%s : %s"%(date
, evenement
)).encode("utf8"))
189 serv
.privmsg(channel
,evenement
.encode("utf8"))
191 # le 0 est le flag "bon siècle" n' pas encore été dit
192 self
.play_status
[channel
]=[1,date
,evenement
,0,token
]
193 serv
.execute_delayed(random
.randrange(ttrig
*3,ttrig
*5),self
.give_indice
,(serv
,channel
,token
))
196 def give_indice(self
,serv
,channel
,token
):
197 if self
.play_status
[channel
][0]==1:
199 # c'est donc que l'indice a été demandé
200 if self
.play_status
[channel
][-1]+config_time_incompressible_clue
<time
.time():
201 token
=self
.play_status
[channel
][-1]
202 if self
.play_status
[channel
][-1]==token
:
203 date
=self
.play_status
[channel
][1]
205 serv
.privmsg(channel
,"indice : %s"%(indice).encode("utf8"))
206 self
.play_status
[channel
][0]=2
207 serv
.execute_delayed(random
.randrange(ttrig
*1,ttrig
*3),self
.give_answer
,(serv
,channel
,token
))
208 def give_answer(self
,serv
,channel
,token
):
209 if self
.play_status
[channel
][0]==2 and self
.play_status
[channel
][-1]==token
:
210 date
=self
.play_status
[channel
][1]
211 serv
.privmsg(channel
,"C'était le %s"%(date).encode("utf8"))
213 self
.play_status
[channel
]=[0,token
]
214 serv
.execute_delayed(random
.randrange(Ttrig
*5,Ttrig
*10),self
.start_enigme
,(serv
,channel
,token
))
216 def get_enigme(self
):
217 # on récupère les dates
218 f
=open(config_source_file
)
221 l
=[i
.split(" : ",2) for i
in l
]
222 dates
={int(i
[0]):i
[1:] for i
in l
}
223 # on va chercher combien de fois elles ont été jouées
224 played_file
=get_config_played_file(self
.serveur
)
228 l
=re
.findall("(.*):(.*)",t
)
229 played
={int(i
[0]):int(i
[1]) for i
in l
}
230 # on récupère le nombre d'occurrences le plus faible
231 mini
=min(played
.values())
232 # on choisit un id dans ceux qui ont ce nombre d'occurences
233 id_choisi
=random
.choice([k
for k
,v
in played
.items() if v
==mini
])
234 date
,evenement
=dates
[id_choisi
]
235 evenement
=evenement
.replace("\n","")
236 # on incrémente la choisie
238 # on enregistre le played_file
239 f
=open(played_file
,"w")
240 f
.write("\n".join(["%-4s : %s"%(k
,v
) for k
,v
in played
.items()]))
242 return map(lambda x
:x
.decode("utf8"), [date
,evenement
])
244 def pourmoi(self
, serv
, message
):
247 if message
[:size
]==pseudo
and len(message
)>size
and message
[size
]==":":
248 return (True,message
[size
+1:].strip(" "))
250 return (False,message
)
252 def on_privmsg(self
, serv
, ev
):
253 message
=ev
.arguments()[0]
254 auteur
= irclib
.nm_to_n(ev
.source())
256 test
=bot_unicode(message
)
257 except UnicodeBotError
:
259 "Euh, tu fais de la merde avec ton encodage là, j'ai failli crasher…")
261 message
=message
.split()
262 cmd
=message
[0].lower()
265 helpmsg_default
="""Liste des commandes :
266 HELP Affiche ce message d'aide
267 SCORE Affiche ton score (SCORE TRANSFERT <pseudo> [<n>] pour transférer des points)
268 SCORES Affiche les scores"""
270 JOIN Faire rejoindre un channel (sans paramètres, donne la liste des chans actuels)
271 LEAVE Faire quitter un channel
272 PLAY Passe un channel en mode "jouer"
273 NOPLAY Passe un channel en mode "ne pas jouer"
274 QUIET Se taire sur un channel
275 NOQUIET Opposé de QUIET"""
277 SCORES {DEL|ADD|SUB} Tu veux un dessin ?
278 SAY Fais envoyer un message sur un chan ou à une personne
279 STAY Ignorera les prochains LEAVE pour un chan
280 NOSTAY Opposé de STAY
281 STATUS Montre l'état courant
283 helpmsg
=helpmsg_default
284 if auteur
in self
.ops
:
286 if auteur
in self
.overops
:
287 helpmsg
+=helpmsg_overops
288 for ligne
in helpmsg
.split("\n"):
289 serv
.privmsg(auteur
,ligne
)
291 if auteur
in self
.ops
:
293 if message
[1] in self
.chanlist
:
294 serv
.privmsg(auteur
,"Je suis déjà sur %s"%(message
[1]))
296 serv
.join(message
[1])
297 self
.chanlist
.append(message
[1])
298 serv
.privmsg(auteur
,"Channels : "+" ".join(self
.chanlist
))
299 log(self
.serveur
,"priv",auteur
," ".join(message
))
301 serv
.privmsg(auteur
,"Channels : "+" ".join(self
.chanlist
))
305 if auteur
in self
.ops
and len(message
)>1:
306 if message
[1] in self
.chanlist
:
307 if not (message
[1] in self
.stay_channels
) or auteur
in self
.overops
:
308 self
.quitter(message
[1]," ".join(message
[2:]))
309 self
.chanlist
.remove(message
[1])
310 log(self
.serveur
,"priv",auteur
," ".join(message
)+"[successful]")
312 serv
.privmsg(auteur
,"Non, je reste !")
313 log(self
.serveur
,"priv",auteur
," ".join(message
)+"[failed]")
315 serv
.privmsg(auteur
,"Je ne suis pas sur %s"%(message
[1]))
319 if auteur
in self
.overops
:
321 if message
[1] in self
.stay_channels
:
322 serv
.privmsg(auteur
,"Je stay déjà sur %s."%(message
[1]))
323 log(self
.serveur
,"priv",auteur
," ".join(message
)+"[failed]")
325 self
.stay_channels
.append(message
[1])
326 serv
.privmsg(auteur
,"Stay channels : "+" ".join(self
.stay_channels
))
327 log(self
.serveur
,"priv",auteur
," ".join(message
)+"[successful]")
329 serv
.privmsg(auteur
,"Stay channels : "+" ".join(self
.stay_channels
))
333 if auteur
in self
.overops
:
335 if message
[1] in self
.stay_channels
:
336 self
.stay_channels
.remove(message
[1])
337 serv
.privmsg(auteur
,"Stay channels : "+" ".join(self
.stay_channels
))
338 log(self
.serveur
,"priv",auteur
," ".join(message
)+"[successful]")
340 serv
.privmsg(auteur
,"Je ne stay pas sur %s."%(message
[1]))
341 log(self
.serveur
,"priv",auteur
," ".join(message
)+"[failed]")
345 if auteur
in self
.ops
:
347 if message
[1] in self
.play_channels
:
348 serv
.privmsg(auteur
,"Je play déjà sur %s."%(message
[1]))
349 log(self
.serveur
,"priv",auteur
," ".join(message
)+"[failed]")
351 self
.play_channels
.append(message
[1])
352 self
.play_status
[message
[1]]=[0,time
.time()-3600]
353 serv
.privmsg(auteur
,"Play channels : "+" ".join(self
.play_channels
))
354 log(self
.serveur
,"priv",auteur
," ".join(message
)+"[successful]")
356 serv
.privmsg(auteur
,"Play channels : "+" ".join(self
.play_channels
))
360 if auteur
in self
.ops
:
362 if message
[1] in self
.play_channels
:
363 self
.play_channels
.remove(message
[1])
364 serv
.privmsg(auteur
,"Play channels : "+" ".join(self
.play_channels
))
365 log(self
.serveur
,"priv",auteur
," ".join(message
)+"[successful]")
367 serv
.privmsg(auteur
,"Je ne play pas sur %s."%(message
[1]))
368 log(self
.serveur
,"priv",auteur
," ".join(message
)+"[failed]")
372 if auteur
in self
.ops
:
374 if message
[1] in self
.quiet_channels
:
375 serv
.privmsg(auteur
,"Je me la ferme déjà sur %s"%(message
[1]))
376 log(self
.serveur
,"priv",auteur
," ".join(message
)+"[failed]")
378 self
.quiet_channels
.append(message
[1])
379 serv
.privmsg(auteur
,"Quiet channels : "+" ".join(self
.quiet_channels
))
380 log(self
.serveur
,"priv",auteur
," ".join(message
)+"[successful]")
382 serv
.privmsg(auteur
,"Quiet channels : "+" ".join(self
.quiet_channels
))
386 if auteur
in self
.ops
:
388 if message
[1] in self
.quiet_channels
:
389 self
.quiet_channels
.remove(message
[1])
390 serv
.privmsg(auteur
,"Quiet channels : "+" ".join(self
.quiet_channels
))
391 log(self
.serveur
,"priv",auteur
," ".join(message
)+"[successful]")
393 serv
.privmsg(auteur
,"Je ne me la ferme pas sur %s."%(message
[1]))
394 log(self
.serveur
,"priv",auteur
," ".join(message
)+"[failed]")
397 elif cmd
in ["states","status"]:
398 if auteur
in self
.overops
:
399 for k
in self
.play_status
.keys():
400 serv
.privmsg(auteur
,(u
"%s : %s"%(k
," | ".join([unicode(i
) for i
in self
.play_status
[k
]]))).encode("utf8") )
402 if auteur
in self
.overops
and len(message
)>2:
403 serv
.privmsg(message
[1]," ".join(message
[2:]))
404 log(self
.serveur
,"priv",auteur
," ".join(message
))
405 elif len(message
)<=2:
406 serv
.privmsg(auteur
,"Syntaxe : SAY <channel> <message>")
410 if auteur
in self
.overops
:
411 log(self
.serveur
,"priv",auteur
," ".join(message
)+"[successful]")
415 if len(message
) in [3,4] and message
[1].lower()=="transfert":
416 scores
=self
.get_scores()
417 de
,to
=auteur
,message
[2]
418 value
=scores
.get(de
,0)
421 asked
=int(message
[3])
423 serv
.privmsg(auteur
,"Syntaxe : SCORE TRANSFERT <pseudo> [<n>]")
428 serv
.privmsg(auteur
,"Vous n'avez pas de points")
431 serv
.privmsg(auteur
,"Bien tenté…")
434 serv
.privmsg(auteur
,"Vous n'avez que %s points"%(value))
437 self
.add_score(de
,-asked
)
438 self
.add_score(to
,asked
)
439 serv
.privmsg(auteur
,"Transfert de %s points de %s à %s"%(asked
,de
,to
))
441 serv
.privmsg(auteur
,"Syntaxe : SCORE TRANSFERT <pseudo> [<n>]")
443 serv
.privmsg(auteur
,"Votre score : %s"%(self
.get_scores().get(auteur
,0)) )
446 scores
=self
.get_scores().items()
448 scores
.sort(lambda x
,y
:cmp(x
[1],y
[1]))
450 serv
.privmsg(auteur
,"Scores by score : "+" ; ".join(["%s %s"%(i
[0],i
[1]) for i
in scores
]))
452 scores
.sort(lambda x
,y
:cmp(x
[0].lower(),y
[0].lower()))
453 serv
.privmsg(auteur
,"Scores by pseudo : "+" ; ".join(["%s %s"%(i
[0],i
[1]) for i
in scores
]))
454 elif auteur
in self
.overops
:
455 souscmd
=message
[1].lower()
459 scores
=self
.get_scores()
460 if scores
.has_key(todelete
):
462 self
.save_scores(scores
)
463 serv
.privmsg(auteur
,"Score de %s supprimé"%(todelete))
465 serv
.privmsg(auteur
,"Ce score n'existe pas : %s"%(todelete))
467 serv
.privmsg(auteur
,"Syntaxe : SCORES DEL <pseudo>")
468 elif souscmd
in ["add","sub"]:
470 toadd
,val
=message
[2],message
[3]
474 serv
.privmsg(auteur
,"Syntaxe : SCORES {ADD|SUB} <pseudo> <n>")
478 self
.add_score(toadd
,val
)
479 serv
.privmsg(auteur
,"Done")
481 serv
.privmsg(auteur
,"Syntaxe : SCORES {ADD|SUB} <pseudo> <n>")
483 serv
.privmsg(auteur
,"Syntaxe : SCORES {DEL|ADD|SUB} <pseudo> [<n>]")
489 serv
.privmsg(auteur
,"Je n'ai pas compris. Essaye HELP…")
491 def on_pubmsg(self
, serv
, ev
):
492 auteur
= irclib
.nm_to_n(ev
.source())
494 message
= ev
.arguments()[0]
495 self
.update_activity(canal
,auteur
)
497 test
=bot_unicode(message
)
498 except UnicodeBotError
:
499 if not canal
in self
.quiet_channels
:
501 "%s: Euh, tu fais de la merde avec ton encodage là, j'ai failli crasher…"%(auteur))
504 pour_moi
,message
=self
.pourmoi(serv
,message
)
505 if pour_moi
and message
.split()!=[]:
506 cmd
=message
.split()[0].lower()
508 args
=" ".join(message
.split()[1:])
511 if cmd
in ["meurs","die","crève"]:
512 if auteur
in self
.overops
:
514 log(self
.serveur
,canal
,auteur
,message
+"[successful]")
516 serv
.privmsg(canal
,"%s: crève !"%(auteur))
517 log(self
.serveur
,canal
,auteur
,message
+"[failed]")
518 if cmd
in ["meur", "meurt","meurre","meurres"] and not canal
in self
.quiet_channels
:
519 serv
.privmsg(canal
,'%s: Mourir, impératif, 2ème personne du singulier : "meurs" (de rien)'%(auteur))
520 if cmd
in ["part","leave","dégage"]:
521 if auteur
in self
.ops
and (not (canal
in self
.stay_channels
)
522 or auteur
in self
.overops
):
524 log(self
.serveur
,canal
,auteur
,message
+"[successful]")
525 self
.chanlist
.remove(canal
)
527 serv
.privmsg(canal
,"%s: Non, je reste !"%(auteur))
528 log(self
.serveur
,canal
,auteur
,message
+"[failed]")
530 if cmd
in ["deviens","pseudo"]:
531 if auteur
in self
.ops
:
534 log(self
.serveur
,canal
,auteur
,message
+"[successful]")
535 if cmd
in ["coucou"] and not canal
in self
.quiet_channels
:
536 serv
.privmsg(canal
,"%s: coucou"%(auteur))
537 if cmd
in ["ping"] and not canal
in self
.quiet_channels
:
538 serv
.privmsg(canal
,"%s: pong"%(auteur))
539 if cmd
in ["date","dates","histoire","énigme","enigme","encore"]:
540 if canal
in self
.play_channels
:
541 if self
.play_status
.get(canal
,[-1])[0]==0:
543 self
.start_enigme(serv
,canal
)
545 serv
.privmsg(canal
,"%s: Je peux souffler une minute ?"%(auteur))
547 serv
.privmsg(canal
,("%s: Rappel : %s"%(auteur
,self
.play_status
[canal
][2])).encode("utf8") )
549 serv
.privmsg(canal
,"%s: pas ici…"%(auteur))
550 if cmd
in ["score","!score"]:
551 serv
.privmsg(auteur
,"Votre score : %s"%(self
.get_scores().get(auteur
,0)) )
552 if cmd
in ["scores","!scores"]:
553 scores
=self
.get_scores().items()
555 scores
.sort(lambda x
,y
:cmp(x
[1],y
[1]))
557 serv
.privmsg(auteur
,"Scores by score : "+" ; ".join(["%s %s"%(i
[0],i
[1]) for i
in scores
]))
559 scores
.sort(lambda x
,y
:cmp(x
[0].lower(),y
[0].lower()))
560 serv
.privmsg(auteur
,"Scores by pseudo : "+" ; ".join(["%s %s"%(i
[0],i
[1]) for i
in scores
]))
561 if cmd
=="indice" and canal
in self
.play_channels
:
562 self
.give_indice(serv
,canal
,None)
563 if is_tag(message
) and not canal
in self
.quiet_channels
:
564 if auteur
in self
.ops
:
565 action
=random
.choice(config_tag_actions
)
566 serv
.action(canal
,action
.encode("utf8"))
567 self
.quiet_channels
.append(canal
)
569 answer
=random
.choice(config_tag_answers
)
570 for ligne
in answer
.split("\n"):
571 serv
.privmsg(canal
,"%s: %s"%(auteur
,ligne
.encode("utf8")))
577 if self
.play_status
.get(canal
,[-1])[0] in [1,2]:
578 answer
=self
.play_status
[canal
][1]
579 flag_century
=self
.play_status
[canal
][3]
581 score_obtenu
=reussi(message
.decode("utf8"),answer
,auteur
)
584 serv
.privmsg(canal
,"%s: C'est le bon siècle, mais pas la bonne année, cherche encore ;)"%(auteur))
585 self
.play_status
[canal
][3]=1
588 if self
.play_status
[canal
][0]==1:
589 bonusmsg
=u
" [+bonus_mois"*(score_obtenu
>config_score_annee
)+u
"+bonus_jour"*(score_obtenu
>config_score_annee
+config_score_mois
)+u
"]"
593 serv
.privmsg(canal
,(u
"%s: bravo ! (C'était le %s)%s"%(auteur
,answer
,bonusmsg
)).encode("utf8"))
594 log(self
.serveur
,canal
,auteur
+"$win",message
)
595 if auteur
in config_noscore
:
597 self
.add_score(auteur
,score_obtenu
)
599 self
.play_status
[canal
]=[0,token
]
600 serv
.execute_delayed(random
.randrange(Ttrig
*5,Ttrig
*10),self
.start_enigme
,(serv
,canal
,token
))
602 def on_kick(self
,serv
,ev
):
603 auteur
= irclib
.nm_to_n(ev
.source())
604 channel
= ev
.target()
605 victime
= ev
.arguments()[0]
606 raison
= ev
.arguments()[1]
607 if victime
==self
.nick
:
608 log(self
.serveur
,"%s kické de %s par %s (raison : %s)" %(victime
,channel
,auteur
,raison
))
611 self
.update_activity(message
[1],"")
612 # on ne dit rien au rejoin
613 #l1,l2=config_kick_answers,config_kick_actions
614 #n1,n2=len(l1),len(l2)
615 #i=random.randrange(n1+n2)
617 # serv.action(channel,l2[i-n1].format(auteur).encode("utf8"))
619 # serv.privmsg(channel,l1[i].format(auteur).encode("utf8"))
621 def quitter(self
,chan
,leave_message
=None):
622 if leave_message
==None:
623 leave_message
=random
.choice(config_leave_messages
)
625 leave_message
=leave_message
%(time
.strftime("le %d/%m/%Y à %T").decode("utf8"),self
.nick
)
628 self
.serv
.part(chan
,message
=leave_message
.encode("utf8"))
631 quit_message
=random
.choice(config_quit_messages
)
633 quit_message
=quit_message
%(time
.strftime("le %d/%m/%Y à %T").decode("utf8"),self
.nick
)
636 self
.die(msg
=quit_message
.encode("utf8"))
638 def get_scores(self
):
639 f
=open(config_score_file
)
640 scores
=pickle
.load(f
)
644 def add_score(self
,pseudo
,value
):
645 scores
=self
.get_scores()
646 if scores
.has_key(pseudo
):
647 scores
[pseudo
]+=value
650 self
.save_scores(scores
)
652 def save_scores(self
,scores
):
653 f
=open(config_score_file
,"w")
654 pickle
.dump(scores
,f
)
658 return self
.serv
.get_nickname()
659 nick
= property(_getnick
)
661 def update_activity(self
,canal
,pseudo
):
662 if not pseudo
in config_idle_bots
:
663 self
.last_activity
[canal
]=time
.time()
664 def is_active(self
,canal
):
665 return time
.time()-self
.last_activity
[canal
]<config_idle_time
667 if __name__
=="__main__":
670 print "Usage : historien.py <serveur> [--debug]"
673 if "debug" in sys
.argv
or "--debug" in sys
.argv
:
677 serveurs
={"a♡":"acoeur.crans.org","acoeur":"acoeur.crans.org","acoeur.crans.org":"acoeur.crans.org",
678 "irc":"irc.crans.org","crans":"irc.crans.org","irc.crans.org":"irc.crans.org"}
680 serveur
=serveurs
[serveur
]
682 print "Server Unknown : %s"%(serveur)
684 historien
=Historien(serveur
,debug
)