]> gitweb.pimeys.fr Git - bots/historien.git/blob - historien.py
Des évènements foireux
[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 # le 0 est le flag "bon siècle" n' pas encore été dit
180 self.play_status[channel]=[1,date,evenement,0,token]
181 serv.execute_delayed(random.randrange(ttrig*3,ttrig*5),self.give_indice,(serv,channel,token))
182 elif ok=="refuse":
183 raise RefuseError
184 def give_indice(self,serv,channel,token):
185 if self.play_status[channel][0]==1:
186 if token==None:
187 # c'est donc que l'indice a été demandé
188 if self.play_status[channel][-1]+config_time_incompressible_clue<time.time():
189 token=self.play_status[channel][-1]
190 if self.play_status[channel][-1]==token:
191 date=self.play_status[channel][1]
192 indice=date[:5]
193 serv.privmsg(channel,"indice : %s"%(indice).encode("utf8"))
194 self.play_status[channel][0]=2
195 serv.execute_delayed(random.randrange(ttrig*1,ttrig*3),self.give_answer,(serv,channel,token))
196 def give_answer(self,serv,channel,token):
197 if self.play_status[channel][0]==2 and self.play_status[channel][-1]==token:
198 date=self.play_status[channel][1]
199 serv.privmsg(channel,"C'était le %s"%(date).encode("utf8"))
200 token=time.time()
201 self.play_status[channel]=[0,token]
202 serv.execute_delayed(random.randrange(Ttrig*5,Ttrig*10),self.start_enigme,(serv,channel,token))
203
204 def get_enigme(self):
205 # on récupère les dates
206 f=open(config_source_file)
207 l=f.readlines()
208 f.close()
209 l=[i.split(" : ",2) for i in l]
210 dates={int(i[0]):i[1:] for i in l}
211 # on va chercher combien de fois elles ont été jouées
212 played_file=get_config_played_file(self.serveur)
213 f=open(played_file)
214 t=f.read()
215 f.close()
216 l=re.findall("(.*):(.*)",t)
217 played={int(i[0]):int(i[1]) for i in l}
218 # on récupère le nombre d'occurrences le plus faible
219 mini=min(played.values())
220 # on choisit un id dans ceux qui ont ce nombre d'occurences
221 id_choisi=random.choice([k for k,v in played.items() if v==mini])
222 date,evenement=dates[id_choisi]
223 evenement=evenement.replace("\n","")
224 # on incrémente la choisie
225 played[id_choisi]+=1
226 # on enregistre le played_file
227 f=open(played_file,"w")
228 f.write("\n".join(["%-4s : %s"%(k,v) for k,v in played.items()]))
229 f.close()
230 return map(lambda x:x.decode("utf8"), [date,evenement])
231
232 def pourmoi(self, serv, message):
233 pseudo=self.nick
234 size=len(pseudo)
235 if message[:size]==pseudo and len(message)>size and message[size]==":":
236 return (True,message[size+1:].strip(" "))
237 else:
238 return (False,message)
239
240 def on_privmsg(self, serv, ev):
241 message=ev.arguments()[0]
242 auteur = irclib.nm_to_n(ev.source())
243 try:
244 test=bot_unicode(message)
245 except UnicodeBotError:
246 serv.privmsg(auteur,
247 "Euh, tu fais de la merde avec ton encodage là, j'ai failli crasher…")
248 return
249 message=message.split()
250 cmd=message[0].lower()
251 notunderstood=False
252 if cmd=="help":
253 helpmsg_default="""Liste des commandes :
254 HELP Affiche ce message d'aide
255 SCORE Affiche ton score (SCORE TRANSFERT <pseudo> [<n>] pour transférer des points)
256 SCORES Affiche les scores"""
257 helpmsg_ops="""
258 JOIN Faire rejoindre un channel (sans paramètres, donne la liste des chans actuels)
259 LEAVE Faire quitter un channel
260 PLAY Passe un channel en mode "jouer"
261 NOPLAY Passe un channel en mode "ne pas jouer"
262 QUIET Se taire sur un channel
263 NOQUIET Opposé de QUIET"""
264 helpmsg_overops="""
265 SCORES {DEL|ADD|SUB} Tu veux un dessin ?
266 SAY Fais envoyer un message sur un chan ou à une personne
267 STAY Ignorera les prochains LEAVE pour un chan
268 NOSTAY Opposé de STAY
269 STATUS Montre l'état courant
270 DIE Mourir"""
271 helpmsg=helpmsg_default
272 if auteur in self.ops:
273 helpmsg+=helpmsg_ops
274 if auteur in self.overops:
275 helpmsg+=helpmsg_overops
276 for ligne in helpmsg.split("\n"):
277 serv.privmsg(auteur,ligne)
278 elif cmd=="join":
279 if auteur in self.ops:
280 if len(message)>1:
281 if message[1] in self.chanlist:
282 serv.privmsg(auteur,"Je suis déjà sur %s"%(message[1]))
283 else:
284 serv.join(message[1])
285 self.chanlist.append(message[1])
286 serv.privmsg(auteur,"Channels : "+" ".join(self.chanlist))
287 log(self.serveur,"priv",auteur," ".join(message))
288 else:
289 serv.privmsg(auteur,"Channels : "+" ".join(self.chanlist))
290 else:
291 notunderstood=True
292 elif cmd=="leave":
293 if auteur in self.ops and len(message)>1:
294 if message[1] in self.chanlist:
295 if not (message[1] in self.stay_channels) or auteur in self.overops:
296 self.quitter(message[1]," ".join(message[2:]))
297 self.chanlist.remove(message[1])
298 log(self.serveur,"priv",auteur," ".join(message)+"[successful]")
299 else:
300 serv.privmsg(auteur,"Non, je reste !")
301 log(self.serveur,"priv",auteur," ".join(message)+"[failed]")
302 else:
303 serv.privmsg(auteur,"Je ne suis pas sur %s"%(message[1]))
304 else:
305 notunderstood=True
306 elif cmd=="stay":
307 if auteur in self.overops:
308 if len(message)>1:
309 if message[1] in self.stay_channels:
310 serv.privmsg(auteur,"Je stay déjà sur %s."%(message[1]))
311 log(self.serveur,"priv",auteur," ".join(message)+"[failed]")
312 else:
313 self.stay_channels.append(message[1])
314 serv.privmsg(auteur,"Stay channels : "+" ".join(self.stay_channels))
315 log(self.serveur,"priv",auteur," ".join(message)+"[successful]")
316 else:
317 serv.privmsg(auteur,"Stay channels : "+" ".join(self.stay_channels))
318 else:
319 notunderstood=True
320 elif cmd=="nostay":
321 if auteur in self.overops:
322 if len(message)>1:
323 if message[1] in self.stay_channels:
324 self.stay_channels.remove(message[1])
325 serv.privmsg(auteur,"Stay channels : "+" ".join(self.stay_channels))
326 log(self.serveur,"priv",auteur," ".join(message)+"[successful]")
327 else:
328 serv.privmsg(auteur,"Je ne stay pas sur %s."%(message[1]))
329 log(self.serveur,"priv",auteur," ".join(message)+"[failed]")
330 else:
331 notunderstood=True
332 elif cmd=="play":
333 if auteur in self.ops:
334 if len(message)>1:
335 if message[1] in self.play_channels:
336 serv.privmsg(auteur,"Je play déjà sur %s."%(message[1]))
337 log(self.serveur,"priv",auteur," ".join(message)+"[failed]")
338 else:
339 self.play_channels.append(message[1])
340 self.play_status[message[1]]=[0,time.time()-3600]
341 serv.privmsg(auteur,"Play channels : "+" ".join(self.play_channels))
342 log(self.serveur,"priv",auteur," ".join(message)+"[successful]")
343 else:
344 serv.privmsg(auteur,"Play channels : "+" ".join(self.play_channels))
345 else:
346 notunderstood=True
347 elif cmd=="noplay":
348 if auteur in self.ops:
349 if len(message)>1:
350 if message[1] in self.play_channels:
351 self.play_channels.remove(message[1])
352 serv.privmsg(auteur,"Play channels : "+" ".join(self.play_channels))
353 log(self.serveur,"priv",auteur," ".join(message)+"[successful]")
354 else:
355 serv.privmsg(auteur,"Je ne play pas sur %s."%(message[1]))
356 log(self.serveur,"priv",auteur," ".join(message)+"[failed]")
357 else:
358 notunderstood=True
359 elif cmd=="quiet":
360 if auteur in self.ops:
361 if len(message)>1:
362 if message[1] in self.quiet_channels:
363 serv.privmsg(auteur,"Je me la ferme déjà sur %s"%(message[1]))
364 log(self.serveur,"priv",auteur," ".join(message)+"[failed]")
365 else:
366 self.quiet_channels.append(message[1])
367 serv.privmsg(auteur,"Quiet channels : "+" ".join(self.quiet_channels))
368 log(self.serveur,"priv",auteur," ".join(message)+"[successful]")
369 else:
370 serv.privmsg(auteur,"Quiet channels : "+" ".join(self.quiet_channels))
371 else:
372 notunderstood=True
373 elif cmd=="noquiet":
374 if auteur in self.ops:
375 if len(message)>1:
376 if message[1] in self.quiet_channels:
377 self.quiet_channels.remove(message[1])
378 serv.privmsg(auteur,"Quiet channels : "+" ".join(self.quiet_channels))
379 log(self.serveur,"priv",auteur," ".join(message)+"[successful]")
380 else:
381 serv.privmsg(auteur,"Je ne me la ferme pas sur %s."%(message[1]))
382 log(self.serveur,"priv",auteur," ".join(message)+"[failed]")
383 else:
384 notunderstood=True
385 elif cmd in ["states","status"]:
386 if auteur in self.overops:
387 for k in self.play_status.keys():
388 serv.privmsg(auteur,(u"%s : %s"%(k," | ".join([unicode(i) for i in self.play_status[k]]))).encode("utf8") )
389 elif cmd=="say":
390 if auteur in self.overops and len(message)>2:
391 serv.privmsg(message[1]," ".join(message[2:]))
392 log(self.serveur,"priv",auteur," ".join(message))
393 elif len(message)<=2:
394 serv.privmsg(auteur,"Syntaxe : SAY <channel> <message>")
395 else:
396 notunderstood=True
397 elif cmd=="die":
398 if auteur in self.overops:
399 log(self.serveur,"priv",auteur," ".join(message)+"[successful]")
400 self.mourir()
401 elif cmd=="score":
402 if len(message)>1:
403 if len(message) in [3,4] and message[1].lower()=="transfert":
404 scores=self.get_scores()
405 de,to=auteur,message[2]
406 value=scores.get(de,0)
407 if len(message)==4:
408 try:
409 asked=int(message[3])
410 except ValueError:
411 serv.privmsg(auteur,"Syntaxe : SCORE TRANSFERT <pseudo> [<n>]")
412 return
413 else:
414 asked=value
415 if value==0:
416 serv.privmsg(auteur,"Vous n'avez pas de points")
417 return
418 elif asked<=0:
419 serv.privmsg(auteur,"Bien tenté…")
420 return
421 elif asked>value:
422 serv.privmsg(auteur,"Vous n'avez que %s points"%(value))
423 return
424 else:
425 self.add_score(de,-asked)
426 self.add_score(to,asked)
427 serv.privmsg(auteur,"Transfert de %s points de %s à %s"%(asked,de,to))
428 else:
429 serv.privmsg(auteur,"Syntaxe : SCORE TRANSFERT <pseudo> [<n>]")
430 else:
431 serv.privmsg(auteur,"Votre score : %s"%(self.get_scores().get(auteur,0)) )
432 elif cmd=="scores":
433 if len(message)==1:
434 scores=self.get_scores().items()
435 # trie par score
436 scores.sort(lambda x,y:cmp(x[1],y[1]))
437 scores.reverse()
438 serv.privmsg(auteur,"Scores by score : "+" ; ".join(["%s %s"%(i[0],i[1]) for i in scores]))
439 # trie par pseudo
440 scores.sort(lambda x,y:cmp(x[0].lower(),y[0].lower()))
441 serv.privmsg(auteur,"Scores by pseudo : "+" ; ".join(["%s %s"%(i[0],i[1]) for i in scores]))
442 elif auteur in self.overops:
443 souscmd=message[1].lower()
444 if souscmd=="del":
445 if len(message)==3:
446 todelete=message[2]
447 scores=self.get_scores()
448 if scores.has_key(todelete):
449 del scores[todelete]
450 self.save_scores(scores)
451 serv.privmsg(auteur,"Score de %s supprimé"%(todelete))
452 else:
453 serv.privmsg(auteur,"Ce score n'existe pas : %s"%(todelete))
454 else:
455 serv.privmsg(auteur,"Syntaxe : SCORES DEL <pseudo>")
456 elif souscmd in ["add","sub"]:
457 if len(message)==4:
458 toadd,val=message[2],message[3]
459 try:
460 val=int(val)
461 except ValueError:
462 serv.privmsg(auteur,"Syntaxe : SCORES {ADD|SUB} <pseudo> <n>")
463 return
464 if souscmd=="sub":
465 val=-val
466 self.add_score(toadd,val)
467 serv.privmsg(auteur,"Done")
468 else:
469 serv.privmsg(auteur,"Syntaxe : SCORES {ADD|SUB} <pseudo> <n>")
470 else:
471 serv.privmsg(auteur,"Syntaxe : SCORES {DEL|ADD|SUB} <pseudo> [<n>]")
472 else:
473 notunderstood=True
474 else:
475 notunderstood=True
476 if notunderstood:
477 serv.privmsg(auteur,"Je n'ai pas compris. Essaye HELP…")
478
479 def on_pubmsg(self, serv, ev):
480 auteur = irclib.nm_to_n(ev.source())
481 canal = ev.target()
482 message = ev.arguments()[0]
483 try:
484 test=bot_unicode(message)
485 except UnicodeBotError:
486 if not canal in self.quiet_channels:
487 serv.privmsg(canal,
488 "%s: Euh, tu fais de la merde avec ton encodage là, j'ai failli crasher…"%(auteur))
489 return
490 tryother=False
491 pour_moi,message=self.pourmoi(serv,message)
492 if pour_moi and message.split()!=[]:
493 cmd=message.split()[0].lower()
494 try:
495 args=" ".join(message.split()[1:])
496 except:
497 args=""
498 if cmd in ["meurs","die","crève"]:
499 if auteur in self.overops:
500 self.mourir()
501 log(self.serveur,canal,auteur,message+"[successful]")
502 else:
503 serv.privmsg(canal,"%s: crève !"%(auteur))
504 log(self.serveur,canal,auteur,message+"[failed]")
505 if cmd in ["meur", "meurt","meurre","meurres"] and not canal in self.quiet_channels:
506 serv.privmsg(canal,'%s: Mourir, impératif, 2ème personne du singulier : "meurs" (de rien)'%(auteur))
507 if cmd in ["part","leave","dégage"]:
508 if auteur in self.ops and (not (canal in self.stay_channels)
509 or auteur in self.overops):
510 self.quitter(canal)
511 log(self.serveur,canal,auteur,message+"[successful]")
512 self.chanlist.remove(canal)
513 else:
514 serv.privmsg(canal,"%s: Non, je reste !"%(auteur))
515 log(self.serveur,canal,auteur,message+"[failed]")
516
517 if cmd in ["deviens","pseudo"]:
518 if auteur in self.ops:
519 become=args
520 serv.nick(become)
521 log(self.serveur,canal,auteur,message+"[successful]")
522 if cmd in ["coucou"] and not canal in self.quiet_channels:
523 serv.privmsg(canal,"%s: coucou"%(auteur))
524 if cmd in ["ping"] and not canal in self.quiet_channels:
525 serv.privmsg(canal,"%s: pong"%(auteur))
526 if cmd in ["date","dates","histoire","énigme","enigme","encore"]:
527 if canal in self.play_channels:
528 if self.play_status.get(canal,[-1])[0]==0:
529 try:
530 self.start_enigme(serv,canal)
531 except RefuseError:
532 serv.privmsg(canal,"%s: Je peux souffler une minute ?"%(auteur))
533 else:
534 serv.privmsg(canal,("%s: Rappel : %s"%(auteur,self.play_status[canal][2])).encode("utf8") )
535 else:
536 serv.privmsg(canal,"%s: pas ici…"%(auteur))
537 if cmd in ["score","!score"]:
538 serv.privmsg(auteur,"Votre score : %s"%(self.get_scores().get(auteur,0)) )
539 if cmd in ["scores","!scores"]:
540 scores=self.get_scores().items()
541 # trie par score
542 scores.sort(lambda x,y:cmp(x[1],y[1]))
543 scores.reverse()
544 serv.privmsg(auteur,"Scores by score : "+" ; ".join(["%s %s"%(i[0],i[1]) for i in scores]))
545 # trie par pseudo
546 scores.sort(lambda x,y:cmp(x[0].lower(),y[0].lower()))
547 serv.privmsg(auteur,"Scores by pseudo : "+" ; ".join(["%s %s"%(i[0],i[1]) for i in scores]))
548 if cmd=="indice" and canal in self.play_channels:
549 self.give_indice(serv,canal,None)
550 if is_tag(message) and not canal in self.quiet_channels:
551 if auteur in self.ops:
552 action=random.choice(config_tag_actions)
553 serv.action(canal,action.encode("utf8"))
554 self.quiet_channels.append(canal)
555 else:
556 answer=random.choice(config_tag_answers)
557 for ligne in answer.split("\n"):
558 serv.privmsg(canal,"%s: %s"%(auteur,ligne.encode("utf8")))
559 else:
560 tryother=True
561 else:
562 tryother=True
563 if tryother:
564 if self.play_status.get(canal,[-1])[0] in [1,2]:
565 answer=self.play_status[canal][1]
566 flag_century=self.play_status[canal][3]
567 try:
568 score_obtenu=reussi(message.decode("utf8"),answer,auteur)
569 except GoodCentury:
570 if not flag_century:
571 serv.privmsg(canal,"%s: C'est le bon siècle, mais pas la bonne année, cherche encore ;)"%(auteur))
572 self.play_status[canal][3]=1
573 return
574 if score_obtenu:
575 if self.play_status[canal][0]==1:
576 bonusmsg=u" [+bonus_mois"*(score_obtenu>config_score_annee)+u"+bonus_jour"*(score_obtenu>config_score_annee+config_score_mois)+u"]"
577 else:
578 bonusmsg=""
579 score_obtenu=1
580 serv.privmsg(canal,(u"%s: bravo ! (C'était le %s)%s"%(auteur,answer,bonusmsg)).encode("utf8"))
581 log(self.serveur,canal,auteur+"$win",message)
582 if auteur in config_noscore:
583 score_obtenu=0
584 self.add_score(auteur,score_obtenu)
585 token=time.time()
586 self.play_status[canal]=[0,token]
587 serv.execute_delayed(random.randrange(Ttrig*5,Ttrig*10),self.start_enigme,(serv,canal,token))
588
589 def on_kick(self,serv,ev):
590 auteur = irclib.nm_to_n(ev.source())
591 channel = ev.target()
592 victime = ev.arguments()[0]
593 raison = ev.arguments()[1]
594 if victime==self.nick:
595 log(self.serveur,"%s kické de %s par %s (raison : %s)" %(victime,channel,auteur,raison))
596 time.sleep(5)
597 serv.join(channel)
598 # on ne dit rien au rejoin
599 #l1,l2=config_kick_answers,config_kick_actions
600 #n1,n2=len(l1),len(l2)
601 #i=random.randrange(n1+n2)
602 #if i>=n1:
603 # serv.action(channel,l2[i-n1].format(auteur).encode("utf8"))
604 #else:
605 # serv.privmsg(channel,l1[i].format(auteur).encode("utf8"))
606
607 def quitter(self,chan,leave_message=None):
608 if leave_message==None:
609 leave_message=random.choice(config_leave_messages)
610 try:
611 leave_message=leave_message%(time.strftime("le %d/%m/%Y à %T").decode("utf8"),self.nick)
612 except:
613 pass
614 self.serv.part(chan,message=leave_message.encode("utf8"))
615
616 def mourir(self):
617 quit_message=random.choice(config_quit_messages)
618 try:
619 quit_message=quit_message%(time.strftime("le %d/%m/%Y à %T").decode("utf8"),self.nick)
620 except:
621 pass
622 self.die(msg=quit_message.encode("utf8"))
623
624 def get_scores(self):
625 f=open(config_score_file)
626 scores=pickle.load(f)
627 f.close()
628 return scores
629
630 def add_score(self,pseudo,value):
631 scores=self.get_scores()
632 if scores.has_key(pseudo):
633 scores[pseudo]+=value
634 else:
635 scores[pseudo]=value
636 self.save_scores(scores)
637
638 def save_scores(self,scores):
639 f=open(config_score_file,"w")
640 pickle.dump(scores,f)
641 f.close()
642
643 def _getnick(self):
644 return self.serv.get_nickname()
645 nick = property(_getnick)
646
647 if __name__=="__main__":
648 import sys
649 if len(sys.argv)==1:
650 print "Usage : historien.py <serveur> [--debug]"
651 exit(1)
652 serveur=sys.argv[1]
653 if "debug" in sys.argv or "--debug" in sys.argv:
654 debug=True
655 else:
656 debug=False
657 serveurs={"a♡":"acoeur.crans.org","acoeur":"acoeur.crans.org","acoeur.crans.org":"acoeur.crans.org",
658 "irc":"irc.crans.org","crans":"irc.crans.org","irc.crans.org":"irc.crans.org"}
659 try:
660 serveur=serveurs[serveur]
661 except KeyError:
662 print "Server Unknown : %s"%(serveur)
663 exit(404)
664 historien=Historien(serveur,debug)
665 historien.start()