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 class UnicodeBotError(Exception):
60 def bot_unicode(chain
):
63 except UnicodeDecodeError:
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
)
72 chain
="%s [%s:%s] %s"%(time
.strftime("%F %T"),channel
,auteur
,message
)
74 if config_debug_stdout
:
83 config_noscore
=["[20-100]","[20-100]_"] # parce que 20-100 est nul en histoire
85 def reussi(message
,answer
,auteur
):
86 if auteur
in config_level3
:
87 return answer
in message
88 if auteur
in config_level2
:
89 return answer
in message
92 date
=cast_as_date(message
.lower().strip())
93 except ThisIsNotADate
:
95 realdate
=map(lambda x
:int(x
), answer
.split('/'))
98 if date
[0]==realdate
[0]:
99 score
=config_score_annee
100 if date
[1]==realdate
[1]:
101 score
+=config_score_mois
102 if date
[2]==realdate
[2]:
103 score
+=config_score_jour
106 def is_something(chain
,matches
,avant
=u
".*(?:^| )",apres
=u
"(?:$|\.| |,|;).*",case_sensitive
=False,debug
=False):
108 chain
=unicode(chain
,"utf8")
110 chain
=unicode(chain
,"utf8").lower()
111 allmatches
="("+"|".join(matches
)+")"
112 reg
=(avant
+allmatches
+apres
).lower()
113 o
=re
.match(reg
,chain
)
117 return is_something(chain
,config_tag_triggers
)
119 class RefuseError(Exception):
122 class Historien(ircbot
.SingleServerIRCBot
):
123 def __init__(self
,serveur
,debug
=False):
124 temporary_pseudo
=config_pseudo
+str(random
.randrange(10000,100000))
125 ircbot
.SingleServerIRCBot
.__init
__(self
, [(serveur
, 6667)],
126 temporary_pseudo
,"Un bot irc qui a au moins l'agreg d'histoire", 10)
129 self
.overops
=config_overops
130 self
.ops
=self
.overops
+config_ops
131 self
.chanlist
=config_chanlist
132 self
.stay_channels
=config_stay_channels
133 self
.play_channels
=config_play_channels
134 self
.play_status
={i
:[0] for i
in self
.play_channels
}
135 self
.quiet_channels
=[]
137 def give_me_my_pseudo(self
,serv
):
138 serv
.privmsg("NickServ","RECOVER %s %s"%(config_pseudo
,config_password
))
139 serv
.privmsg("NickServ","RELEASE %s %s"%(config_pseudo
,config_password
))
141 serv
.nick(config_pseudo
)
143 def on_welcome(self
, serv
, ev
):
144 self
.serv
=serv
# ça serv ira :)
145 self
.give_me_my_pseudo(serv
)
146 serv
.privmsg("NickServ","identify %s"%(config_password))
147 log(self
.serveur
,"Connected")
149 self
.chanlist
=["#bot"]
150 self
.play_channels
=["#bot"]
151 for c
in self
.chanlist
:
152 log(self
.serveur
,"JOIN %s"%(c))
154 for c
in self
.play_channels
:
155 token
=time
.time()-3600
156 self
.play_status
[c
]=[0,token
]
157 serv
.execute_delayed(random
.randrange(ttrig
),self
.start_enigme
,(serv
,c
,token
))
159 def start_enigme(self
,serv
,channel
,token
=None):
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 date
,evenement
=self
.get_enigme()
171 log(self
.serveur
,channel
,u
"$Date$".encode("utf8"),("%s : %s"%(date
, evenement
)).encode("utf8"))
172 serv
.privmsg(channel
,evenement
.encode("utf8"))
174 self
.play_status
[channel
]=[1,date
,evenement
,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 date
=self
.play_status
[channel
][1]
187 serv
.privmsg(channel
,"indice : %s"%(indice).encode("utf8"))
188 self
.play_status
[channel
][0]=2
189 serv
.execute_delayed(random
.randrange(ttrig
*1,ttrig
*3),self
.give_answer
,(serv
,channel
,token
))
190 def give_answer(self
,serv
,channel
,token
):
191 if self
.play_status
[channel
][0]==2 and self
.play_status
[channel
][-1]==token
:
192 date
=self
.play_status
[channel
][1]
193 serv
.privmsg(channel
,"C'était le %s"%(date).encode("utf8"))
195 self
.play_status
[channel
]=[0,token
]
196 serv
.execute_delayed(random
.randrange(Ttrig
*5,Ttrig
*10),self
.start_enigme
,(serv
,channel
,token
))
198 def get_enigme(self
):
199 # on récupère les dates
200 f
=open(config_source_file
)
203 l
=[i
.split(" : ",2) for i
in l
]
204 dates
={int(i
[0]):i
[1:] for i
in l
}
205 # on va chercher combien de fois elles ont été jouées
206 played_file
=get_config_played_file(self
.serveur
)
210 l
=re
.findall("(.*):(.*)",t
)
211 played
={int(i
[0]):int(i
[1]) for i
in l
}
212 # on récupère le nombre d'occurrences le plus faible
213 mini
=min(played
.values())
214 # on choisit un id dans ceux qui ont ce nombre d'occurences
215 id_choisi
=random
.choice([k
for k
,v
in played
.items() if v
==mini
])
216 date
,evenement
=dates
[id_choisi
]
217 evenement
=evenement
.replace("\n","")
218 # on incrémente la choisie
220 # on enregistre le played_file
221 f
=open(played_file
,"w")
222 f
.write("\n".join(["%-4s : %s"%(k
,v
) for k
,v
in played
.items()]))
224 return map(lambda x
:x
.decode("utf8"), [date
,evenement
])
226 def pourmoi(self
, serv
, message
):
229 if message
[:size
]==pseudo
and len(message
)>size
and message
[size
]==":":
230 return (True,message
[size
+1:].strip(" "))
232 return (False,message
)
234 def on_privmsg(self
, serv
, ev
):
235 message
=ev
.arguments()[0]
236 auteur
= irclib
.nm_to_n(ev
.source())
238 test
=bot_unicode(message
)
239 except UnicodeBotError
:
241 "Euh, tu fais de la merde avec ton encodage là, j'ai failli crasher…")
243 message
=message
.split()
244 cmd
=message
[0].lower()
247 helpmsg_default
="""Liste des commandes :
248 HELP Affiche ce message d'aide
249 SCORE Affiche ton score (SCORE TRANSFERT <pseudo> [<n>] pour transférer des points)
250 SCORES Affiche les scores"""
252 JOIN Faire rejoindre un channel (sans paramètres, donne la liste des chans actuels)
253 LEAVE Faire quitter un channel
254 PLAY Passe un channel en mode "jouer"
255 NOPLAY Passe un channel en mode "ne pas jouer"
256 QUIET Se taire sur un channel
257 NOQUIET Opposé de QUIET"""
259 SCORES {DEL|ADD|SUB} Tu veux un dessin ?
260 SAY Fais envoyer un message sur un chan ou à une personne
261 STAY Ignorera les prochains LEAVE pour un chan
262 NOSTAY Opposé de STAY
263 STATUS Montre l'état courant
265 helpmsg
=helpmsg_default
266 if auteur
in self
.ops
:
268 if auteur
in self
.overops
:
269 helpmsg
+=helpmsg_overops
270 for ligne
in helpmsg
.split("\n"):
271 serv
.privmsg(auteur
,ligne
)
273 if auteur
in self
.ops
:
275 if message
[1] in self
.chanlist
:
276 serv
.privmsg(auteur
,"Je suis déjà sur %s"%(message
[1]))
278 serv
.join(message
[1])
279 self
.chanlist
.append(message
[1])
280 serv
.privmsg(auteur
,"Channels : "+" ".join(self
.chanlist
))
281 log(self
.serveur
,"priv",auteur
," ".join(message
))
283 serv
.privmsg(auteur
,"Channels : "+" ".join(self
.chanlist
))
287 if auteur
in self
.ops
and len(message
)>1:
288 if message
[1] in self
.chanlist
:
289 if not (message
[1] in self
.stay_channels
) or auteur
in self
.overops
:
290 self
.quitter(message
[1]," ".join(message
[2:]))
291 self
.chanlist
.remove(message
[1])
292 log(self
.serveur
,"priv",auteur
," ".join(message
)+"[successful]")
294 serv
.privmsg(auteur
,"Non, je reste !")
295 log(self
.serveur
,"priv",auteur
," ".join(message
)+"[failed]")
297 serv
.privmsg(auteur
,"Je ne suis pas sur %s"%(message
[1]))
301 if auteur
in self
.overops
:
303 if message
[1] in self
.stay_channels
:
304 serv
.privmsg(auteur
,"Je stay déjà sur %s."%(message
[1]))
305 log(self
.serveur
,"priv",auteur
," ".join(message
)+"[failed]")
307 self
.stay_channels
.append(message
[1])
308 serv
.privmsg(auteur
,"Stay channels : "+" ".join(self
.stay_channels
))
309 log(self
.serveur
,"priv",auteur
," ".join(message
)+"[successful]")
311 serv
.privmsg(auteur
,"Stay channels : "+" ".join(self
.stay_channels
))
315 if auteur
in self
.overops
:
317 if message
[1] in self
.stay_channels
:
318 self
.stay_channels
.remove(message
[1])
319 serv
.privmsg(auteur
,"Stay channels : "+" ".join(self
.stay_channels
))
320 log(self
.serveur
,"priv",auteur
," ".join(message
)+"[successful]")
322 serv
.privmsg(auteur
,"Je ne stay pas sur %s."%(message
[1]))
323 log(self
.serveur
,"priv",auteur
," ".join(message
)+"[failed]")
327 if auteur
in self
.ops
:
329 if message
[1] in self
.play_channels
:
330 serv
.privmsg(auteur
,"Je play déjà sur %s."%(message
[1]))
331 log(self
.serveur
,"priv",auteur
," ".join(message
)+"[failed]")
333 self
.play_channels
.append(message
[1])
334 self
.play_status
[message
[1]]=[0,time
.time()-3600]
335 serv
.privmsg(auteur
,"Play channels : "+" ".join(self
.play_channels
))
336 log(self
.serveur
,"priv",auteur
," ".join(message
)+"[successful]")
338 serv
.privmsg(auteur
,"Play channels : "+" ".join(self
.play_channels
))
342 if auteur
in self
.ops
:
344 if message
[1] in self
.play_channels
:
345 self
.play_channels
.remove(message
[1])
346 serv
.privmsg(auteur
,"Play channels : "+" ".join(self
.play_channels
))
347 log(self
.serveur
,"priv",auteur
," ".join(message
)+"[successful]")
349 serv
.privmsg(auteur
,"Je ne play pas sur %s."%(message
[1]))
350 log(self
.serveur
,"priv",auteur
," ".join(message
)+"[failed]")
354 if auteur
in self
.ops
:
356 if message
[1] in self
.quiet_channels
:
357 serv
.privmsg(auteur
,"Je me la ferme déjà sur %s"%(message
[1]))
358 log(self
.serveur
,"priv",auteur
," ".join(message
)+"[failed]")
360 self
.quiet_channels
.append(message
[1])
361 serv
.privmsg(auteur
,"Quiet channels : "+" ".join(self
.quiet_channels
))
362 log(self
.serveur
,"priv",auteur
," ".join(message
)+"[successful]")
364 serv
.privmsg(auteur
,"Quiet channels : "+" ".join(self
.quiet_channels
))
368 if auteur
in self
.ops
:
370 if message
[1] in self
.quiet_channels
:
371 self
.quiet_channels
.remove(message
[1])
372 serv
.privmsg(auteur
,"Quiet channels : "+" ".join(self
.quiet_channels
))
373 log(self
.serveur
,"priv",auteur
," ".join(message
)+"[successful]")
375 serv
.privmsg(auteur
,"Je ne me la ferme pas sur %s."%(message
[1]))
376 log(self
.serveur
,"priv",auteur
," ".join(message
)+"[failed]")
379 elif cmd
in ["states","status"]:
380 if auteur
in self
.overops
:
381 for k
in self
.play_status
.keys():
382 serv
.privmsg(auteur
,(u
"%s : %s"%(k
," | ".join([unicode(i
) for i
in self
.play_status
[k
]]))).encode("utf8") )
384 if auteur
in self
.overops
and len(message
)>2:
385 serv
.privmsg(message
[1]," ".join(message
[2:]))
386 log(self
.serveur
,"priv",auteur
," ".join(message
))
387 elif len(message
)<=2:
388 serv
.privmsg(auteur
,"Syntaxe : SAY <channel> <message>")
392 if auteur
in self
.overops
:
393 log(self
.serveur
,"priv",auteur
," ".join(message
)+"[successful]")
397 if len(message
) in [3,4] and message
[1].lower()=="transfert":
398 scores
=self
.get_scores()
399 de
,to
=auteur
,message
[2]
400 value
=scores
.get(de
,0)
403 asked
=int(message
[3])
405 serv
.privmsg(auteur
,"Syntaxe : SCORE TRANSFERT <pseudo> [<n>]")
410 serv
.privmsg(auteur
,"Vous n'avez pas de points")
413 serv
.privmsg(auteur
,"Bien tenté…")
416 serv
.privmsg(auteur
,"Vous n'avez que %s points"%(value))
419 self
.add_score(de
,-asked
)
420 self
.add_score(to
,asked
)
421 serv
.privmsg(auteur
,"Transfert de %s points de %s à %s"%(asked
,de
,to
))
423 serv
.privmsg(auteur
,"Syntaxe : SCORE TRANSFERT <pseudo> [<n>]")
425 serv
.privmsg(auteur
,"Votre score : %s"%(self
.get_scores().get(auteur
,0)) )
428 scores
=self
.get_scores().items()
430 scores
.sort(lambda x
,y
:cmp(x
[1],y
[1]))
432 serv
.privmsg(auteur
,"Scores by score : "+" ; ".join(["%s %s"%(i
[0],i
[1]) for i
in scores
]))
434 scores
.sort(lambda x
,y
:cmp(x
[0].lower(),y
[0].lower()))
435 serv
.privmsg(auteur
,"Scores by pseudo : "+" ; ".join(["%s %s"%(i
[0],i
[1]) for i
in scores
]))
436 elif auteur
in self
.overops
:
437 souscmd
=message
[1].lower()
441 scores
=self
.get_scores()
442 if scores
.has_key(todelete
):
444 self
.save_scores(scores
)
445 serv
.privmsg(auteur
,"Score de %s supprimé"%(todelete))
447 serv
.privmsg(auteur
,"Ce score n'existe pas : %s"%(todelete))
449 serv
.privmsg(auteur
,"Syntaxe : SCORES DEL <pseudo>")
450 elif souscmd
in ["add","sub"]:
452 toadd
,val
=message
[2],message
[3]
456 serv
.privmsg(auteur
,"Syntaxe : SCORES {ADD|SUB} <pseudo> <n>")
460 self
.add_score(toadd
,val
)
461 serv
.privmsg(auteur
,"Done")
463 serv
.privmsg(auteur
,"Syntaxe : SCORES {ADD|SUB} <pseudo> <n>")
465 serv
.privmsg(auteur
,"Syntaxe : SCORES {DEL|ADD|SUB} <pseudo> [<n>]")
471 serv
.privmsg(auteur
,"Je n'ai pas compris. Essaye HELP…")
473 def on_pubmsg(self
, serv
, ev
):
474 auteur
= irclib
.nm_to_n(ev
.source())
476 message
= ev
.arguments()[0]
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 ["date","dates","histoire","é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
][2])).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")))
558 if self
.play_status
.get(canal
,[-1])[0] in [1,2]:
559 answer
=self
.play_status
[canal
][1]
560 score_obtenu
=reussi(message
.decode("utf8"),answer
,auteur
)
562 if self
.play_status
[canal
][0]==1:
563 bonusmsg
=u
" [+bonus_mois"*(score_obtenu
>config_score_annee
)+u
"+bonus_jour"*(score_obtenu
>config_score_annee
+config_score_mois
)+u
"]"
567 serv
.privmsg(canal
,(u
"%s: bravo ! (C'était le %s)%s"%(auteur
,answer
,bonusmsg
)).encode("utf8"))
568 log(self
.serveur
,canal
,auteur
+"$win",message
)
569 if auteur
in config_noscore
:
571 self
.add_score(auteur
,score_obtenu
)
573 self
.play_status
[canal
]=[0,token
]
574 serv
.execute_delayed(random
.randrange(Ttrig
*5,Ttrig
*10),self
.start_enigme
,(serv
,canal
,token
))
576 def on_kick(self
,serv
,ev
):
577 auteur
= irclib
.nm_to_n(ev
.source())
578 channel
= ev
.target()
579 victime
= ev
.arguments()[0]
580 raison
= ev
.arguments()[1]
581 if victime
==self
.nick
:
582 log(self
.serveur
,"%s kické par %s (raison : %s)" %(victime
,auteur
,raison
))
585 # on ne dit rien au rejoin
586 #l1,l2=config_kick_answers,config_kick_actions
587 #n1,n2=len(l1),len(l2)
588 #i=random.randrange(n1+n2)
590 # serv.action(channel,l2[i-n1].format(auteur).encode("utf8"))
592 # serv.privmsg(channel,l1[i].format(auteur).encode("utf8"))
594 def quitter(self
,chan
,leave_message
=None):
595 if leave_message
==None:
596 leave_message
=random
.choice(config_leave_messages
)
598 leave_message
=leave_message
%(time
.strftime("le %d/%m/%Y à %T").decode("utf8"),self
.nick
)
601 self
.serv
.part(chan
,message
=leave_message
.encode("utf8"))
604 quit_message
=random
.choice(config_quit_messages
)
606 quit_message
=quit_message
%(time
.strftime("le %d/%m/%Y à %T").decode("utf8"),self
.nick
)
609 self
.die(msg
=quit_message
.encode("utf8"))
611 def get_scores(self
):
612 f
=open(config_score_file
)
613 scores
=pickle
.load(f
)
617 def add_score(self
,pseudo
,value
):
618 scores
=self
.get_scores()
619 if scores
.has_key(pseudo
):
620 scores
[pseudo
]+=value
623 self
.save_scores(scores
)
625 def save_scores(self
,scores
):
626 f
=open(config_score_file
,"w")
627 pickle
.dump(scores
,f
)
631 return self
.serv
.get_nickname()
632 nick
= property(_getnick
)
634 if __name__
=="__main__":
637 print "Usage : historien.py <serveur> [--debug]"
640 if "debug" in sys
.argv
or "--debug" in sys
.argv
:
644 serveurs
={"a♡":"acoeur.crans.org","acoeur":"acoeur.crans.org","acoeur.crans.org":"acoeur.crans.org",
645 "irc":"irc.crans.org","crans":"irc.crans.org","irc.crans.org":"irc.crans.org"}
647 serveur
=serveurs
[serveur
]
649 print "Server Unknown : %s"%(serveur)
651 historien
=Historien(serveur
,debug
)