]> gitweb.pimeys.fr Git - bots/historien.git/blob - historien.py
On réagit si le siècle est bon.
[bots/historien.git] / historien.py
1 #!/usr/bin/python
2 # -*- coding:utf8 -*-
3
4 # Codé par 20-100 le 25/05/12
5
6 # Un bot IRC qui pose des questions d'histoire
7
8 import irclib
9 import ircbot
10 import threading
11 import random
12 import time
13 import pickle
14 import re
15 from cast_as_date import *
16
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"]
24
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
34
35 config_score_file="scores.pickle"
36
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 :°",
41 u"Héhé, try again",
42 u"Non, j'ai pas envie",
43 u"Peut-être quand toi tu la fermeras, et encore…"]
44
45 config_level2=[]
46 config_level3=[]
47
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])
53
54 config_quit_messages=[u"%s : %s quitte le serveur IRC"]
55
56 config_leave_messages=[u"%s : %s quitte le channel"]
57
58 class UnicodeBotError(Exception):
59 pass
60 def bot_unicode(chain):
61 try:
62 unicode(chain,"utf8")
63 except UnicodeDecodeError:
64 raise UnicodeBotError
65
66 def log(serveur,channel,auteur=None,message=None):
67 f=open(get_config_logfile(serveur),"a")
68 if auteur==message==None:
69 # alors c'est que c'est pas un channel mais juste une ligne de log
70 chain="%s %s"%(time.strftime("%F %T"),channel)
71 else:
72 chain="%s [%s:%s] %s"%(time.strftime("%F %T"),channel,auteur,message)
73 f.write(chain+"\n")
74 if config_debug_stdout:
75 print chain
76 f.close()
77
78
79 config_score_annee=1
80 config_score_mois=3
81 config_score_jour=4
82
83 config_noscore=["[20-100]","[20-100]_"] # parce que 20-100 est nul en histoire
84
85 class GoodCentury(Exception):
86 pass
87
88 def reussi(message,answer,auteur):
89 if auteur in config_level3:
90 return answer in message
91 if auteur in config_level2:
92 return answer in message
93 else:
94 try:
95 date=cast_as_date(message.lower().strip())
96 except ThisIsNotADate:
97 return False
98 realdate=map(lambda x:int(x), answer.split('/'))
99 realdate.reverse()
100 score=0
101 if date[0]==realdate[0]:
102 score=config_score_annee
103 if date[1]==realdate[1]:
104 score+=config_score_mois
105 if date[2]==realdate[2]:
106 score+=config_score_jour
107 elif date[0]/100 == realdate[0]/100:
108 raise GoodCentury
109 return score
110
111 def is_something(chain,matches,avant=u".*(?:^| )",apres=u"(?:$|\.| |,|;).*",case_sensitive=False,debug=False):
112 if case_sensitive:
113 chain=unicode(chain,"utf8")
114 else:
115 chain=unicode(chain,"utf8").lower()
116 allmatches="("+"|".join(matches)+")"
117 reg=(avant+allmatches+apres).lower()
118 o=re.match(reg,chain)
119 return o
120
121 def is_tag(chain):
122 return is_something(chain,config_tag_triggers)
123
124 class RefuseError(Exception):
125 pass
126
127 class Historien(ircbot.SingleServerIRCBot):
128 def __init__(self,serveur,debug=False):
129 temporary_pseudo=config_pseudo+str(random.randrange(10000,100000))
130 ircbot.SingleServerIRCBot.__init__(self, [(serveur, 6667)],
131 temporary_pseudo,"Un bot irc qui a au moins l'agreg d'histoire", 10)
132 self.debug=debug
133 self.serveur=serveur
134 self.overops=config_overops
135 self.ops=self.overops+config_ops
136 self.chanlist=config_chanlist
137 self.stay_channels=config_stay_channels
138 self.play_channels=config_play_channels
139 self.play_status={i:[0] for i in self.play_channels}
140 self.quiet_channels=[]
141
142 def give_me_my_pseudo(self,serv):
143 serv.privmsg("NickServ","RECOVER %s %s"%(config_pseudo,config_password))
144 serv.privmsg("NickServ","RELEASE %s %s"%(config_pseudo,config_password))
145 time.sleep(0.3)
146 serv.nick(config_pseudo)
147
148 def on_welcome(self, serv, ev):
149 self.serv=serv # ça serv ira :)
150 self.give_me_my_pseudo(serv)
151 serv.privmsg("NickServ","identify %s"%(config_password))
152 log(self.serveur,"Connected")
153 if self.debug:
154 self.chanlist=["#bot"]
155 self.play_channels=["#bot"]
156 for c in self.chanlist:
157 log(self.serveur,"JOIN %s"%(c))
158 serv.join(c)
159 for c in self.play_channels:
160 token=time.time()-3600
161 self.play_status[c]=[0,token]
162 serv.execute_delayed(random.randrange(ttrig),self.start_enigme,(serv,c,token))
163
164 def start_enigme(self,serv,channel,token=None):
165 if self.play_status[channel][0]==0 and channel in self.play_channels:
166 ok="skip"
167 if token==self.play_status[channel][-1]:
168 ok="do_it"
169 if token==None:
170 if time.time() > self.play_status[channel][-1]+config_time_incompressible:
171 ok="do_it"
172 else:
173 ok="refuse"
174 if ok=="do_it":
175 date,evenement=self.get_enigme()
176 log(self.serveur,channel,u"$Date$".encode("utf8"),("%s : %s"%(date, evenement)).encode("utf8"))
177 serv.privmsg(channel,evenement.encode("utf8"))
178 token=time.time()
179 self.play_status[channel]=[1,date,evenement,token]
180 serv.execute_delayed(random.randrange(ttrig*3,ttrig*5),self.give_indice,(serv,channel,token))
181 elif ok=="refuse":
182 raise RefuseError
183 def give_indice(self,serv,channel,token):
184 if self.play_status[channel][0]==1:
185 if token==None:
186 # c'est donc que l'indice a été demandé
187 if self.play_status[channel][-1]+config_time_incompressible_clue<time.time():
188 token=self.play_status[channel][-1]
189 if self.play_status[channel][-1]==token:
190 date=self.play_status[channel][1]
191 indice=date[:5]
192 serv.privmsg(channel,"indice : %s"%(indice).encode("utf8"))
193 self.play_status[channel][0]=2
194 serv.execute_delayed(random.randrange(ttrig*1,ttrig*3),self.give_answer,(serv,channel,token))
195 def give_answer(self,serv,channel,token):
196 if self.play_status[channel][0]==2 and self.play_status[channel][-1]==token:
197 date=self.play_status[channel][1]
198 serv.privmsg(channel,"C'était le %s"%(date).encode("utf8"))
199 token=time.time()
200 self.play_status[channel]=[0,token]
201 serv.execute_delayed(random.randrange(Ttrig*5,Ttrig*10),self.start_enigme,(serv,channel,token))
202
203 def get_enigme(self):
204 # on récupère les dates
205 f=open(config_source_file)
206 l=f.readlines()
207 f.close()
208 l=[i.split(" : ",2) for i in l]
209 dates={int(i[0]):i[1:] for i in l}
210 # on va chercher combien de fois elles ont été jouées
211 played_file=get_config_played_file(self.serveur)
212 f=open(played_file)
213 t=f.read()
214 f.close()
215 l=re.findall("(.*):(.*)",t)
216 played={int(i[0]):int(i[1]) for i in l}
217 # on récupère le nombre d'occurrences le plus faible
218 mini=min(played.values())
219 # on choisit un id dans ceux qui ont ce nombre d'occurences
220 id_choisi=random.choice([k for k,v in played.items() if v==mini])
221 date,evenement=dates[id_choisi]
222 evenement=evenement.replace("\n","")
223 # on incrémente la choisie
224 played[id_choisi]+=1
225 # on enregistre le played_file
226 f=open(played_file,"w")
227 f.write("\n".join(["%-4s : %s"%(k,v) for k,v in played.items()]))
228 f.close()
229 return map(lambda x:x.decode("utf8"), [date,evenement])
230
231 def pourmoi(self, serv, message):
232 pseudo=self.nick
233 size=len(pseudo)
234 if message[:size]==pseudo and len(message)>size and message[size]==":":
235 return (True,message[size+1:].strip(" "))
236 else:
237 return (False,message)
238
239 def on_privmsg(self, serv, ev):
240 message=ev.arguments()[0]
241 auteur = irclib.nm_to_n(ev.source())
242 try:
243 test=bot_unicode(message)
244 except UnicodeBotError:
245 serv.privmsg(auteur,
246 "Euh, tu fais de la merde avec ton encodage là, j'ai failli crasher…")
247 return
248 message=message.split()
249 cmd=message[0].lower()
250 notunderstood=False
251 if cmd=="help":
252 helpmsg_default="""Liste des commandes :
253 HELP Affiche ce message d'aide
254 SCORE Affiche ton score (SCORE TRANSFERT <pseudo> [<n>] pour transférer des points)
255 SCORES Affiche les scores"""
256 helpmsg_ops="""
257 JOIN Faire rejoindre un channel (sans paramètres, donne la liste des chans actuels)
258 LEAVE Faire quitter un channel
259 PLAY Passe un channel en mode "jouer"
260 NOPLAY Passe un channel en mode "ne pas jouer"
261 QUIET Se taire sur un channel
262 NOQUIET Opposé de QUIET"""
263 helpmsg_overops="""
264 SCORES {DEL|ADD|SUB} Tu veux un dessin ?
265 SAY Fais envoyer un message sur un chan ou à une personne
266 STAY Ignorera les prochains LEAVE pour un chan
267 NOSTAY Opposé de STAY
268 STATUS Montre l'état courant
269 DIE Mourir"""
270 helpmsg=helpmsg_default
271 if auteur in self.ops:
272 helpmsg+=helpmsg_ops
273 if auteur in self.overops:
274 helpmsg+=helpmsg_overops
275 for ligne in helpmsg.split("\n"):
276 serv.privmsg(auteur,ligne)
277 elif cmd=="join":
278 if auteur in self.ops:
279 if len(message)>1:
280 if message[1] in self.chanlist:
281 serv.privmsg(auteur,"Je suis déjà sur %s"%(message[1]))
282 else:
283 serv.join(message[1])
284 self.chanlist.append(message[1])
285 serv.privmsg(auteur,"Channels : "+" ".join(self.chanlist))
286 log(self.serveur,"priv",auteur," ".join(message))
287 else:
288 serv.privmsg(auteur,"Channels : "+" ".join(self.chanlist))
289 else:
290 notunderstood=True
291 elif cmd=="leave":
292 if auteur in self.ops and len(message)>1:
293 if message[1] in self.chanlist:
294 if not (message[1] in self.stay_channels) or auteur in self.overops:
295 self.quitter(message[1]," ".join(message[2:]))
296 self.chanlist.remove(message[1])
297 log(self.serveur,"priv",auteur," ".join(message)+"[successful]")
298 else:
299 serv.privmsg(auteur,"Non, je reste !")
300 log(self.serveur,"priv",auteur," ".join(message)+"[failed]")
301 else:
302 serv.privmsg(auteur,"Je ne suis pas sur %s"%(message[1]))
303 else:
304 notunderstood=True
305 elif cmd=="stay":
306 if auteur in self.overops:
307 if len(message)>1:
308 if message[1] in self.stay_channels:
309 serv.privmsg(auteur,"Je stay déjà sur %s."%(message[1]))
310 log(self.serveur,"priv",auteur," ".join(message)+"[failed]")
311 else:
312 self.stay_channels.append(message[1])
313 serv.privmsg(auteur,"Stay channels : "+" ".join(self.stay_channels))
314 log(self.serveur,"priv",auteur," ".join(message)+"[successful]")
315 else:
316 serv.privmsg(auteur,"Stay channels : "+" ".join(self.stay_channels))
317 else:
318 notunderstood=True
319 elif cmd=="nostay":
320 if auteur in self.overops:
321 if len(message)>1:
322 if message[1] in self.stay_channels:
323 self.stay_channels.remove(message[1])
324 serv.privmsg(auteur,"Stay channels : "+" ".join(self.stay_channels))
325 log(self.serveur,"priv",auteur," ".join(message)+"[successful]")
326 else:
327 serv.privmsg(auteur,"Je ne stay pas sur %s."%(message[1]))
328 log(self.serveur,"priv",auteur," ".join(message)+"[failed]")
329 else:
330 notunderstood=True
331 elif cmd=="play":
332 if auteur in self.ops:
333 if len(message)>1:
334 if message[1] in self.play_channels:
335 serv.privmsg(auteur,"Je play déjà sur %s."%(message[1]))
336 log(self.serveur,"priv",auteur," ".join(message)+"[failed]")
337 else:
338 self.play_channels.append(message[1])
339 self.play_status[message[1]]=[0,time.time()-3600]
340 serv.privmsg(auteur,"Play channels : "+" ".join(self.play_channels))
341 log(self.serveur,"priv",auteur," ".join(message)+"[successful]")
342 else:
343 serv.privmsg(auteur,"Play channels : "+" ".join(self.play_channels))
344 else:
345 notunderstood=True
346 elif cmd=="noplay":
347 if auteur in self.ops:
348 if len(message)>1:
349 if message[1] in self.play_channels:
350 self.play_channels.remove(message[1])
351 serv.privmsg(auteur,"Play channels : "+" ".join(self.play_channels))
352 log(self.serveur,"priv",auteur," ".join(message)+"[successful]")
353 else:
354 serv.privmsg(auteur,"Je ne play pas sur %s."%(message[1]))
355 log(self.serveur,"priv",auteur," ".join(message)+"[failed]")
356 else:
357 notunderstood=True
358 elif cmd=="quiet":
359 if auteur in self.ops:
360 if len(message)>1:
361 if message[1] in self.quiet_channels:
362 serv.privmsg(auteur,"Je me la ferme déjà sur %s"%(message[1]))
363 log(self.serveur,"priv",auteur," ".join(message)+"[failed]")
364 else:
365 self.quiet_channels.append(message[1])
366 serv.privmsg(auteur,"Quiet channels : "+" ".join(self.quiet_channels))
367 log(self.serveur,"priv",auteur," ".join(message)+"[successful]")
368 else:
369 serv.privmsg(auteur,"Quiet channels : "+" ".join(self.quiet_channels))
370 else:
371 notunderstood=True
372 elif cmd=="noquiet":
373 if auteur in self.ops:
374 if len(message)>1:
375 if message[1] in self.quiet_channels:
376 self.quiet_channels.remove(message[1])
377 serv.privmsg(auteur,"Quiet channels : "+" ".join(self.quiet_channels))
378 log(self.serveur,"priv",auteur," ".join(message)+"[successful]")
379 else:
380 serv.privmsg(auteur,"Je ne me la ferme pas sur %s."%(message[1]))
381 log(self.serveur,"priv",auteur," ".join(message)+"[failed]")
382 else:
383 notunderstood=True
384 elif cmd in ["states","status"]:
385 if auteur in self.overops:
386 for k in self.play_status.keys():
387 serv.privmsg(auteur,(u"%s : %s"%(k," | ".join([unicode(i) for i in self.play_status[k]]))).encode("utf8") )
388 elif cmd=="say":
389 if auteur in self.overops and len(message)>2:
390 serv.privmsg(message[1]," ".join(message[2:]))
391 log(self.serveur,"priv",auteur," ".join(message))
392 elif len(message)<=2:
393 serv.privmsg(auteur,"Syntaxe : SAY <channel> <message>")
394 else:
395 notunderstood=True
396 elif cmd=="die":
397 if auteur in self.overops:
398 log(self.serveur,"priv",auteur," ".join(message)+"[successful]")
399 self.mourir()
400 elif cmd=="score":
401 if len(message)>1:
402 if len(message) in [3,4] and message[1].lower()=="transfert":
403 scores=self.get_scores()
404 de,to=auteur,message[2]
405 value=scores.get(de,0)
406 if len(message)==4:
407 try:
408 asked=int(message[3])
409 except ValueError:
410 serv.privmsg(auteur,"Syntaxe : SCORE TRANSFERT <pseudo> [<n>]")
411 return
412 else:
413 asked=value
414 if value==0:
415 serv.privmsg(auteur,"Vous n'avez pas de points")
416 return
417 elif asked<=0:
418 serv.privmsg(auteur,"Bien tenté…")
419 return
420 elif asked>value:
421 serv.privmsg(auteur,"Vous n'avez que %s points"%(value))
422 return
423 else:
424 self.add_score(de,-asked)
425 self.add_score(to,asked)
426 serv.privmsg(auteur,"Transfert de %s points de %s à %s"%(asked,de,to))
427 else:
428 serv.privmsg(auteur,"Syntaxe : SCORE TRANSFERT <pseudo> [<n>]")
429 else:
430 serv.privmsg(auteur,"Votre score : %s"%(self.get_scores().get(auteur,0)) )
431 elif cmd=="scores":
432 if len(message)==1:
433 scores=self.get_scores().items()
434 # trie par score
435 scores.sort(lambda x,y:cmp(x[1],y[1]))
436 scores.reverse()
437 serv.privmsg(auteur,"Scores by score : "+" ; ".join(["%s %s"%(i[0],i[1]) for i in scores]))
438 # trie par pseudo
439 scores.sort(lambda x,y:cmp(x[0].lower(),y[0].lower()))
440 serv.privmsg(auteur,"Scores by pseudo : "+" ; ".join(["%s %s"%(i[0],i[1]) for i in scores]))
441 elif auteur in self.overops:
442 souscmd=message[1].lower()
443 if souscmd=="del":
444 if len(message)==3:
445 todelete=message[2]
446 scores=self.get_scores()
447 if scores.has_key(todelete):
448 del scores[todelete]
449 self.save_scores(scores)
450 serv.privmsg(auteur,"Score de %s supprimé"%(todelete))
451 else:
452 serv.privmsg(auteur,"Ce score n'existe pas : %s"%(todelete))
453 else:
454 serv.privmsg(auteur,"Syntaxe : SCORES DEL <pseudo>")
455 elif souscmd in ["add","sub"]:
456 if len(message)==4:
457 toadd,val=message[2],message[3]
458 try:
459 val=int(val)
460 except ValueError:
461 serv.privmsg(auteur,"Syntaxe : SCORES {ADD|SUB} <pseudo> <n>")
462 return
463 if souscmd=="sub":
464 val=-val
465 self.add_score(toadd,val)
466 serv.privmsg(auteur,"Done")
467 else:
468 serv.privmsg(auteur,"Syntaxe : SCORES {ADD|SUB} <pseudo> <n>")
469 else:
470 serv.privmsg(auteur,"Syntaxe : SCORES {DEL|ADD|SUB} <pseudo> [<n>]")
471 else:
472 notunderstood=True
473 else:
474 notunderstood=True
475 if notunderstood:
476 serv.privmsg(auteur,"Je n'ai pas compris. Essaye HELP…")
477
478 def on_pubmsg(self, serv, ev):
479 auteur = irclib.nm_to_n(ev.source())
480 canal = ev.target()
481 message = ev.arguments()[0]
482 try:
483 test=bot_unicode(message)
484 except UnicodeBotError:
485 if not canal in self.quiet_channels:
486 serv.privmsg(canal,
487 "%s: Euh, tu fais de la merde avec ton encodage là, j'ai failli crasher…"%(auteur))
488 return
489 tryother=False
490 pour_moi,message=self.pourmoi(serv,message)
491 if pour_moi and message.split()!=[]:
492 cmd=message.split()[0].lower()
493 try:
494 args=" ".join(message.split()[1:])
495 except:
496 args=""
497 if cmd in ["meurs","die","crève"]:
498 if auteur in self.overops:
499 self.mourir()
500 log(self.serveur,canal,auteur,message+"[successful]")
501 else:
502 serv.privmsg(canal,"%s: crève !"%(auteur))
503 log(self.serveur,canal,auteur,message+"[failed]")
504 if cmd in ["meur", "meurt","meurre","meurres"] and not canal in self.quiet_channels:
505 serv.privmsg(canal,'%s: Mourir, impératif, 2ème personne du singulier : "meurs" (de rien)'%(auteur))
506 if cmd in ["part","leave","dégage"]:
507 if auteur in self.ops and (not (canal in self.stay_channels)
508 or auteur in self.overops):
509 self.quitter(canal)
510 log(self.serveur,canal,auteur,message+"[successful]")
511 self.chanlist.remove(canal)
512 else:
513 serv.privmsg(canal,"%s: Non, je reste !"%(auteur))
514 log(self.serveur,canal,auteur,message+"[failed]")
515
516 if cmd in ["deviens","pseudo"]:
517 if auteur in self.ops:
518 become=args
519 serv.nick(become)
520 log(self.serveur,canal,auteur,message+"[successful]")
521 if cmd in ["coucou"] and not canal in self.quiet_channels:
522 serv.privmsg(canal,"%s: coucou"%(auteur))
523 if cmd in ["ping"] and not canal in self.quiet_channels:
524 serv.privmsg(canal,"%s: pong"%(auteur))
525 if cmd in ["date","dates","histoire","énigme","enigme","encore"]:
526 if canal in self.play_channels:
527 if self.play_status.get(canal,[-1])[0]==0:
528 try:
529 self.start_enigme(serv,canal)
530 except RefuseError:
531 serv.privmsg(canal,"%s: Je peux souffler une minute ?"%(auteur))
532 else:
533 serv.privmsg(canal,("%s: Rappel : %s"%(auteur,self.play_status[canal][2])).encode("utf8") )
534 else:
535 serv.privmsg(canal,"%s: pas ici…"%(auteur))
536 if cmd in ["score","!score"]:
537 serv.privmsg(auteur,"Votre score : %s"%(self.get_scores().get(auteur,0)) )
538 if cmd in ["scores","!scores"]:
539 scores=self.get_scores().items()
540 # trie par score
541 scores.sort(lambda x,y:cmp(x[1],y[1]))
542 scores.reverse()
543 serv.privmsg(auteur,"Scores by score : "+" ; ".join(["%s %s"%(i[0],i[1]) for i in scores]))
544 # trie par pseudo
545 scores.sort(lambda x,y:cmp(x[0].lower(),y[0].lower()))
546 serv.privmsg(auteur,"Scores by pseudo : "+" ; ".join(["%s %s"%(i[0],i[1]) for i in scores]))
547 if cmd=="indice" and canal in self.play_channels:
548 self.give_indice(serv,canal,None)
549 if is_tag(message) and not canal in self.quiet_channels:
550 if auteur in self.ops:
551 action=random.choice(config_tag_actions)
552 serv.action(canal,action.encode("utf8"))
553 self.quiet_channels.append(canal)
554 else:
555 answer=random.choice(config_tag_answers)
556 for ligne in answer.split("\n"):
557 serv.privmsg(canal,"%s: %s"%(auteur,ligne.encode("utf8")))
558 else:
559 tryother=True
560 else:
561 tryother=True
562 if tryother:
563 if self.play_status.get(canal,[-1])[0] in [1,2]:
564 answer=self.play_status[canal][1]
565 try:
566 score_obtenu=reussi(message.decode("utf8"),answer,auteur)
567 except GoodCentury:
568 serv.privmsg(canal,"%s: C'est le bon siècle, mais pas la bonne année, cherche encore ;)"%(auteur))
569 return
570 if score_obtenu:
571 if self.play_status[canal][0]==1:
572 bonusmsg=u" [+bonus_mois"*(score_obtenu>config_score_annee)+u"+bonus_jour"*(score_obtenu>config_score_annee+config_score_mois)+u"]"
573 else:
574 bonusmsg=""
575 score_obtenu=1
576 serv.privmsg(canal,(u"%s: bravo ! (C'était le %s)%s"%(auteur,answer,bonusmsg)).encode("utf8"))
577 log(self.serveur,canal,auteur+"$win",message)
578 if auteur in config_noscore:
579 score_obtenu=0
580 self.add_score(auteur,score_obtenu)
581 token=time.time()
582 self.play_status[canal]=[0,token]
583 serv.execute_delayed(random.randrange(Ttrig*5,Ttrig*10),self.start_enigme,(serv,canal,token))
584
585 def on_kick(self,serv,ev):
586 auteur = irclib.nm_to_n(ev.source())
587 channel = ev.target()
588 victime = ev.arguments()[0]
589 raison = ev.arguments()[1]
590 if victime==self.nick:
591 log(self.serveur,"%s kické par %s (raison : %s)" %(victime,auteur,raison))
592 time.sleep(5)
593 serv.join(channel)
594 # on ne dit rien au rejoin
595 #l1,l2=config_kick_answers,config_kick_actions
596 #n1,n2=len(l1),len(l2)
597 #i=random.randrange(n1+n2)
598 #if i>=n1:
599 # serv.action(channel,l2[i-n1].format(auteur).encode("utf8"))
600 #else:
601 # serv.privmsg(channel,l1[i].format(auteur).encode("utf8"))
602
603 def quitter(self,chan,leave_message=None):
604 if leave_message==None:
605 leave_message=random.choice(config_leave_messages)
606 try:
607 leave_message=leave_message%(time.strftime("le %d/%m/%Y à %T").decode("utf8"),self.nick)
608 except:
609 pass
610 self.serv.part(chan,message=leave_message.encode("utf8"))
611
612 def mourir(self):
613 quit_message=random.choice(config_quit_messages)
614 try:
615 quit_message=quit_message%(time.strftime("le %d/%m/%Y à %T").decode("utf8"),self.nick)
616 except:
617 pass
618 self.die(msg=quit_message.encode("utf8"))
619
620 def get_scores(self):
621 f=open(config_score_file)
622 scores=pickle.load(f)
623 f.close()
624 return scores
625
626 def add_score(self,pseudo,value):
627 scores=self.get_scores()
628 if scores.has_key(pseudo):
629 scores[pseudo]+=value
630 else:
631 scores[pseudo]=value
632 self.save_scores(scores)
633
634 def save_scores(self,scores):
635 f=open(config_score_file,"w")
636 pickle.dump(scores,f)
637 f.close()
638
639 def _getnick(self):
640 return self.serv.get_nickname()
641 nick = property(_getnick)
642
643 if __name__=="__main__":
644 import sys
645 if len(sys.argv)==1:
646 print "Usage : historien.py <serveur> [--debug]"
647 exit(1)
648 serveur=sys.argv[1]
649 if "debug" in sys.argv or "--debug" in sys.argv:
650 debug=True
651 else:
652 debug=False
653 serveurs={"a♡":"acoeur.crans.org","acoeur":"acoeur.crans.org","acoeur.crans.org":"acoeur.crans.org",
654 "irc":"irc.crans.org","crans":"irc.crans.org","irc.crans.org":"irc.crans.org"}
655 try:
656 serveur=serveurs[serveur]
657 except KeyError:
658 print "Server Unknown : %s"%(serveur)
659 exit(404)
660 historien=Historien(serveur,debug)
661 historien.start()