]>
gitweb.pimeys.fr Git - bots/hung.git/blob - hung.py
4 # Codé par 20-100 le 23/04/12
6 # Un bot IRC qui joue au pendu
11 import socket
, ssl
, json
17 from commands
import getstatusoutput
as ex
19 # Oui, j'ai recodé ma version d'irclib pour pouvoir rattrapper les SIGHUP
20 sys
. path
. insert ( 0 , "/home/vincent/scripts/python-myirclib" )
29 def get_config_logfile ( serveur
):
30 serveurs
={ "acoeur.crans.org" : "acoeur" , "irc.crans.org" : "crans" , "localhost" : "localhost" }
31 return config
. logfile_template
%( serveurs
[ serveur
])
33 def log ( serveur
, channel
, auteur
= None , message
= None ):
34 f
= open ( get_config_logfile ( serveur
), "a" )
35 if auteur
== message
== None :
36 # alors c'est que c'est pas un channel mais juste une ligne de log
37 chain
= " %s %s " %( time
. strftime ( " %F %T" ), channel
)
39 chain
= " %s [ %s : %s ] %s " %( time
. strftime ( " %F %T" ), channel
, auteur
, message
)
41 if config
. debug_stdout
:
45 def ignore_event ( serv
, ev
):
46 """Retourne ``True`` si il faut ignorer cet évènement."""
47 for ( blackmask
, exceptmask
) in config
. blacklisted_masks
:
48 usermask
= ev
. source ()
49 if exceptmask
is None :
52 exceptit
= bool ( irclib
. mask_matches ( usermask
, exceptmask
))
53 blackit
= bool ( irclib
. mask_matches ( usermask
, blackmask
))
54 if blackit
and not exceptit
:
57 class UnicodeBotError ( Exception ):
59 def bot_unicode ( chain
):
62 except UnicodeDecodeError as exc
:
65 def remplace_accents ( chaine
):
67 remplacements
= { u
"á" : u
"a" , u
"à" : u
"a" , u
"â" : u
"a" , u
"ä" : u
"a" , u
"é" : u
"e" , u
"è" : u
"e" , u
"ê" : u
"e" , u
"ë" : u
"e" , u
"í" : u
"i" , u
"ì" : u
"i" , u
"î" : u
"i" , u
"ï" : u
"i" , u
"ó" : u
"o" , u
"ò" : u
"o" , u
"ô" : u
"o" , u
"ö" : u
"o" , u
"ú" : u
"u" , u
"ù" : u
"u" , u
"û" : u
"u" , u
"ü" : u
"u" , u
"ý" : u
"y" , u
"ỳ" : u
"y" , u
"ŷ" : u
"y" , u
"ÿ" : u
"y" , u
"œ" : u
"oe" , u
"æ" : u
"ae" }
68 for avant
, apres
in remplacements
. items ():
69 chaine
= chaine
. replace ( avant
, apres
)
72 def is_something ( chain
, matches
, avant
= u
".*(?:^| )" , apres
= u
"(?:$|\.| |,|;).*" , case_sensitive
= False , debug
= False ):
74 chain
= unicode ( chain
, "utf8" )
76 chain
= unicode ( chain
, "utf8" ). lower ()
77 allmatches
= "(" + "|" . join ( matches
)+ ")"
78 reg
=( avant
+ allmatches
+ apres
). lower ()
83 return is_something ( chain
, config
. tag_triggers
)
85 def is_mot ( mot
, liste
):
86 real_word
= "" . join ([ lettre
[ 0 ] for lettre
in liste
])
87 real_word
= real_word
. decode ( "utf8" ). lower ()
88 mot
= remplace_accents ( mot
. decode ( "utf8" ))
89 return mot
. startswith ( real_word
)
91 class Hung ( ircbot
. SingleServerIRCBot
):
92 def __init__ ( self
, serveur
, debug
= False ):
93 temporary_pseudo
= config
. irc_pseudo
+ str ( random
. randrange ( 10000 , 100000 ))
94 ircbot
. SingleServerIRCBot
.__ init
__ ( self
, [( serveur
, 6667 )],
95 temporary_pseudo
, "Bot irc pour jouer au pendu" , 10 )
98 self
. overops
= config
. overops
99 self
. ops
= self
. overops
+ config
. ops
100 self
. report_bugs_to
= config
. report_bugs_to
101 self
. chanlist
= config
. chanlist
102 self
. stay_channels
= config
. stay_channels
103 self
. play_channels
= config
. play_channels
104 self
. play_status
={ i
:[ None , None , None ] for i
in self
. play_channels
}
106 self
. tried_letters
={}
107 self
. quiet_channels
= config
. quiet_channels
110 def give_me_my_pseudo ( self
, serv
):
111 serv
. privmsg ( "NickServ" , "RECOVER %s %s " %( config
. irc_pseudo
, config
. irc_password
))
112 serv
. privmsg ( "NickServ" , "RELEASE %s %s " %( config
. irc_pseudo
, config
. irc_password
))
114 serv
. nick ( config
. irc_pseudo
)
116 def on_welcome ( self
, serv
, ev
):
117 self
. serv
= serv
# ça serv ira :)
118 self
. give_me_my_pseudo ( serv
)
119 serv
. privmsg ( "NickServ" , "IDENTIFY %s " %( config
. irc_password
))
120 log ( self
. serveur
, "Connected" )
122 self
. chanlist
=[ "#bot" ]
123 self
. play_channels
=[ "#bot" ]
124 for c
in self
. chanlist
:
125 log ( self
. serveur
, "JOIN %s " %(c))
128 def pourmoi ( self
, serv
, message
):
129 """renvoie (False,lemessage) ou (True, le message amputé de "pseudo: ")"""
130 pseudo
= serv
. get_nickname ()
132 if message
[: size
]== pseudo
and len ( message
)> size
and message
[ size
]== ":" :
133 return ( True , message
[ size
+ 1 :]. lstrip ( " " ))
135 return ( False , message
)
137 def on_privmsg ( self
, serv
, ev
):
138 if ignore_event ( serv
, ev
):
140 message
= ev
. arguments ()[ 0 ]
141 auteur
= irclib
. nm_to_n ( ev
. source ())
143 test
= bot_unicode ( message
)
144 except UnicodeBotError
:
145 if config
. utf8_trigger
:
146 serv
. privmsg ( auteur
, random
. choice ( config
. utf8_fail_answers
). encode ( "utf8" ))
148 message
= message
. split ()
149 cmd
= message
[ 0 ]. lower ()
152 helpmsg_default
= """Liste des commandes :
153 HELP Affiche ce message d'aide
154 SCORE Affiche ton score
155 SCORES Affiche les scores"""
157 JOIN Faire rejoindre un channel (sans paramètres, donne la liste des chans actuels)
158 LEAVE Faire quitter un channel
159 PLAY Passe un channel en mode "jouer"
160 NOPLAY Passe un channel en mode "ne pas jouer"
161 QUIET Se taire sur un channel
162 NOQUIET Opposé de QUIET
163 RELOAD Recharge la config"""
165 SAY Fais envoyer un message sur un chan ou à une personne
166 DO Me fait faire une action sur un chan
167 STAY Ignorera les prochains LEAVE pour un chan
168 NOSTAY Opposé de STAY
169 STATUS Montre l'état courant
171 helpmsg
= helpmsg_default
172 if auteur
in self
. ops
:
174 if auteur
in self
. overops
:
175 helpmsg
+= helpmsg_overops
176 for ligne
in helpmsg
. split ( " \n " ):
177 serv
. privmsg ( auteur
, ligne
)
179 if auteur
in self
. ops
:
181 if message
[ 1 ] in self
. chanlist
:
182 serv
. privmsg ( auteur
, "Je suis déjà sur %s " %( message
[ 1 ]))
184 serv
. join ( message
[ 1 ])
185 self
. chanlist
. append ( message
[ 1 ])
186 serv
. privmsg ( auteur
, "Channels : " + " " . join ( self
. chanlist
))
187 log ( self
. serveur
, "priv" , auteur
, " " . join ( message
))
189 serv
. privmsg ( auteur
, "Channels : " + " " . join ( self
. chanlist
))
193 if auteur
in self
. ops
and len ( message
)> 1 :
194 if message
[ 1 ] in self
. chanlist
:
195 if not ( message
[ 1 ] in self
. stay_channels
) or auteur
in self
. overops
:
196 self
. quitter ( message
[ 1 ], " " . join ( message
[ 2 :]))
197 self
. chanlist
. remove ( message
[ 1 ])
198 log ( self
. serveur
, "priv" , auteur
, " " . join ( message
)+ "[successful]" )
200 serv
. privmsg ( auteur
, "Non, je reste !" )
201 log ( self
. serveur
, "priv" , auteur
, " " . join ( message
)+ "[failed]" )
203 serv
. privmsg ( auteur
, "Je ne suis pas sur %s " %( message
[ 1 ]))
207 if auteur
in self
. ops
:
209 if message
[ 1 ] in self
. play_channels
:
211 self
. start_partie ( serv
, message
[ 1 ], " " . join ( message
[ 2 :]))
213 serv
. privmsg ( auteur
, "Je play déjà sur %s ." %( message
[ 1 ]))
214 log ( self
. serveur
, "priv" , auteur
, " " . join ( message
)+ "[failed]" )
216 self
. play_channels
. append ( message
[ 1 ])
217 self
. play_status
[ message
[ 1 ]]=[ None , None , None ]
218 serv
. privmsg ( auteur
, "Play channels : " + " " . join ( self
. play_channels
))
219 log ( self
. serveur
, "priv" , auteur
, " " . join ( message
)+ "[successful]" )
221 serv
. privmsg ( auteur
, "Play channels : " + " " . join ( self
. play_channels
))
225 if auteur
in self
. ops
:
227 if message
[ 1 ] in self
. play_channels
:
228 self
. play_channels
. remove ( message
[ 1 ])
229 serv
. privmsg ( auteur
, "Play channels : " + " " . join ( self
. play_channels
))
230 log ( self
. serveur
, "priv" , auteur
, " " . join ( message
)+ "[successful]" )
232 serv
. privmsg ( auteur
, "Je ne play pas sur %s ." %( message
[ 1 ]))
233 log ( self
. serveur
, "priv" , auteur
, " " . join ( message
)+ "[failed]" )
237 if auteur
in self
. overops
:
239 if message
[ 1 ] in self
. stay_channels
:
240 log ( self
. serveur
, "priv" , auteur
, " " . join ( message
)+ "[failed]" )
241 serv
. privmsg ( auteur
, "Je stay déjà sur %s ." %( message
[ 1 ]))
243 log ( self
. serveur
, "priv" , auteur
, " " . join ( message
)+ "[successful]" )
244 self
. stay_channels
. append ( message
[ 1 ])
245 serv
. privmsg ( auteur
, "Stay channels : " + " " . join ( self
. stay_channels
))
247 serv
. privmsg ( auteur
, "Stay channels : " + " " . join ( self
. stay_channels
))
251 if auteur
in self
. overops
:
253 if message
[ 1 ] in self
. stay_channels
:
254 log ( self
. serveur
, "priv" , auteur
, " " . join ( message
)+ "[successful]" )
255 self
. stay_channels
. remove ( message
[ 1 ])
256 serv
. privmsg ( auteur
, "Stay channels : " + " " . join ( self
. stay_channels
))
258 log ( self
. serveur
, "priv" , auteur
, " " . join ( message
)+ "[failed]" )
259 serv
. privmsg ( auteur
, "Je ne stay pas sur %s ." %( message
[ 1 ]))
263 elif cmd
in [ "states" , "status" ]:
264 if auteur
in self
. overops
:
265 for k
in self
. play_status
. keys ():
266 if self
. play_status
[ k
]==[ None , None , None ]:
267 serv
. privmsg ( auteur
, "None" )
269 serv
. privmsg ( auteur
, " %s : %s ( %s ) [ %s ]" %( k
, "" . join ([ str ( i
[ 0 ]) for i
in self
. play_status
[ k
][ 0 ]])
270 , self
. play_status
[ k
][ 1 ], self
. play_status
[ k
][ 2 ]))
272 if auteur
in self
. overops
:
273 log ( self
. serveur
, "priv" , auteur
, " " . join ( message
)+ "[successful]" )
278 if auteur
in self
. ops
:
280 if message
[ 1 ] in self
. quiet_channels
:
281 serv
. privmsg ( auteur
, "Je me la ferme déjà sur %s " %( message
[ 1 ]))
282 log ( self
. serveur
, "priv" , auteur
, " " . join ( message
)+ "[failed]" )
284 self
. quiet_channels
. append ( message
[ 1 ])
285 serv
. privmsg ( auteur
, "Quiet channels : " + " " . join ( self
. quiet_channels
))
286 log ( self
. serveur
, "priv" , auteur
, " " . join ( message
)+ "[successful]" )
288 serv
. privmsg ( auteur
, "Quiet channels : " + " " . join ( self
. quiet_channels
))
292 if auteur
in self
. ops
:
294 if message
[ 1 ] in self
. quiet_channels
:
295 self
. quiet_channels
. remove ( message
[ 1 ])
296 serv
. privmsg ( auteur
, "Quiet channels : " + " " . join ( self
. quiet_channels
))
297 log ( self
. serveur
, "priv" , auteur
, " " . join ( message
)+ "[successful]" )
299 serv
. privmsg ( auteur
, "Je ne me la ferme pas sur %s ." %( message
[ 1 ]))
300 log ( self
. serveur
, "priv" , auteur
, " " . join ( message
)+ "[failed]" )
304 if auteur
in self
. ops
:
306 log ( self
. serveur
, "priv" , auteur
, " " . join ( message
)+ "[successful]" )
310 if auteur
in self
. overops
and len ( message
)> 2 :
311 serv
. privmsg ( message
[ 1 ], " " . join ( message
[ 2 :]))
312 log ( self
. serveur
, "priv" , auteur
, " " . join ( message
))
313 elif len ( message
)<= 2 :
314 serv
. privmsg ( auteur
, "Syntaxe : SAY <channel> <message>" )
318 if auteur
in self
. overops
and len ( message
)> 2 :
319 serv
. action ( message
[ 1 ], " " . join ( message
[ 2 :]))
320 log ( self
. serveur
, "priv" , auteur
, " " . join ( message
))
321 elif len ( message
)<= 2 :
322 serv
. privmsg ( auteur
, "Syntaxe : DO <channel> <action>" )
325 elif cmd
in [ "score" , "scores" ]:
326 self
. send_scores ( serv
, auteur
)
330 serv
. privmsg ( auteur
, "Je n'ai pas compris. Essaye HELP…" )
332 def affiche_mot ( self
, serv
, canal
, begin
= "Mot courant" ):
333 if self
. play_status
. has_key ( canal
):
334 mot
= self
. play_status
[ canal
][ 0 ]
335 obfuskated
= " " . join ([ lettre
[ 0 ] if lettre
[ 1 ] else "_" for lettre
in mot
])
336 serv
. privmsg ( canal
, " %s : %s " %( begin
, obfuskated
))
338 def start_partie ( self
, serv
, canal
, mot
= None ):
340 mots
=[ mot
. strip () for mot
in open ( config
. dico_mots
). readlines ()]
341 defs
=[ defi
. strip () for defi
in open ( config
. dico_defs
). readlines ()]
342 indice
= random
. randrange ( 0 , len ( mots
))
343 mot
, definition
= mots
[ indice
], defs
[ indice
]
345 definition
= "(custom word)"
346 # ' et - sont considérés comme déjà devinés
348 mot
= [( lettre
, lettre
in config
. non_guess_chars
) for lettre
in list ( mot
)]
349 self
. play_status
[ canal
]=[ mot
, definition
,{}]
350 self
. tried_letters
[ canal
] = set ()
351 self
. lives
[ canal
] = config
. lives
352 self
. affiche_mot ( serv
, canal
, begin
= "Devinez" )
354 def on_pubmsg ( self
, serv
, ev
):
355 if ignore_event ( serv
, ev
):
357 auteur
= irclib
. nm_to_n ( ev
. source ())
359 message
= ev
. arguments ()[ 0 ]
361 test
= bot_unicode ( message
)
362 except UnicodeBotError
:
363 if config
. utf8_trigger
and not canal
in self
. quiet_channels
:
364 serv
. privmsg ( canal
, ( u
" %s : %s " %( auteur
, random
. choice ( config
. utf8_fail_answers
))). encode ( "utf8" ))
366 pour_moi
, message
= self
. pourmoi ( serv
, message
)
367 if pour_moi
and message
. split ()!=[]:
368 cmd
= message
. split ()[ 0 ]. lower ()
370 args
= " " . join ( message
. split ()[ 1 :])
373 if cmd
in [ "meurs" , "die" , "crève" ]:
374 if auteur
in self
. overops
:
375 log ( self
. serveur
, canal
, auteur
, message
+ "[successful]" )
378 serv
. privmsg ( canal
, " %s : crève !" %(auteur))
379 log ( self
. serveur
, canal
, auteur
, message
+ "[failed]" )
380 elif cmd
== "reload" :
381 if auteur
in self
. ops
:
382 log ( self
. serveur
, canal
, auteur
, message
+ "[successful]" )
384 elif cmd
in [ "part" , "leave" , "dégage" ]:
385 if auteur
in self
. ops
and ( not ( canal
in self
. stay_channels
)
386 or auteur
in self
. overops
):
388 log ( self
. serveur
, canal
, auteur
, message
+ "[successful]" )
389 if canal
in self
. chanlist
:
390 self
. chanlist
. remove ( canal
)
392 serv
. privmsg ( canal
, " %s : Non, je reste !" %(auteur))
393 log ( self
. serveur
, canal
, auteur
, message
+ "[failed]" )
394 elif cmd
in [ "play" , "jeu" , "encore" , "again" , "partie" , "pendu" , "game" , "mot" , "go" , "allez" ]:
395 if not canal
in self
. quiet_channels
and canal
in self
. play_channels
:
396 if self
. play_status
. has_key ( canal
):
397 if self
. play_status
[ canal
]==[ None , None , None ]:
398 self
. start_partie ( serv
, canal
)
400 self
. affiche_mot ( serv
, canal
, begin
= " %s : Rappel" %(auteur))
402 self
. play_status
[ canal
]=[ None , None , None ]
403 self
. start_partie ( serv
, canal
)
404 elif not canal
in self
. play_channels
:
405 serv
. privmsg ( canal
, " %s : pas ici…" %(auteur))
406 elif cmd
in [ "score" , "scores" , "!score" , "!scores" ]:
407 self
. send_scores ( serv
, auteur
)
408 if cmd
in [ "meur" , "meurt" , "meurre" , "meurres" ] and not canal
in self
. quiet_channels
:
409 serv
. privmsg ( canal
, ' %s : Mourir, impératif, 2ème personne du singulier : "meurs" (de rien)' %(auteur))
410 if is_tag ( message
) and not canal
in self
. quiet_channels
:
411 if auteur
in self
. ops
:
412 action
= random
. choice ( config
. tag_actions
)
413 serv
. action ( canal
, action
. encode ( "utf8" ))
414 self
. quiet_channels
. append ( canal
)
416 answer
= random
. choice ( config
. tag_answers
)
417 for ligne
in answer
. split ( " \n " ):
418 serv
. privmsg ( canal
, " %s : %s " %( auteur
, ligne
. encode ( "utf8" )))
419 # on essaye de voir si le mot fourni matche la partie en cours
421 if canal
in self
. play_channels
and self
. play_status
[ canal
][ 0 ]!= None and is_mot ( mot
, self
. play_status
[ canal
][ 0 ]):
423 # on regarde combien de lettre il manquait
424 manquait
= sum ([ not lettre
[ 1 ] for lettre
in self
. play_status
[ canal
][ 0 ]])
425 self
. add_score ({ auteur
: manquait
})
426 if self
. play_status
[ canal
][ 2 ]. has_key ( auteur
):
427 self
. play_status
[ canal
][ 2 ][ auteur
]+= manquait
429 self
. play_status
[ canal
][ 2 ][ auteur
]= manquait
430 self
. gagne ( serv
, canal
, bonus
= auteur
, bonusvalue
= manquait
)
432 elif ( cmd
in list ( "azertyuiopqsdfghjklmwxcvbn" ) and canal
in self
. play_channels
433 and self
. play_status
. has_key ( canal
) and self
. play_status
[ canal
]!=[ None , None , None ]):
435 liste
= self
. play_status
[ canal
][ 0 ]
436 listeapres
=[( lettre
[ 0 ], lettre
[ 1 ] or lettre
[ 0 ]== giv_let
) for lettre
in liste
]
437 if liste
!= listeapres
:
438 nbtrouvees
=( sum ([ lettre
[ 1 ] for lettre
in listeapres
if not lettre
[ 0 ] in "'-()" ])
439 - sum ([ lettre
[ 1 ] for lettre
in liste
if not lettre
[ 0 ] in "'-()" ]))
440 if self
. play_status
[ canal
][ 2 ]. has_key ( auteur
):
441 self
. play_status
[ canal
][ 2 ][ auteur
]+= nbtrouvees
443 self
. play_status
[ canal
][ 2 ][ auteur
] = nbtrouvees
444 self
. play_status
[ canal
][ 0 ]= listeapres
445 self
. affiche_mot ( serv
, canal
, begin
= " %s placé" %(giv_let))
447 if not giv_let
in self
. tried_letters
[ canal
]:
449 self
. lives
[ canal
] -= 1
450 if self
. lives
[ canal
] > 0 :
451 serv
. privmsg ( canal
, "Pas de %s . Plus que %s chance %s …" % ( giv_let
, self
. lives
[ canal
], "s" * ( self
. lives
[ canal
] > 1 )))
452 if self
. lives
[ canal
] == 0 :
453 serv
. privmsg ( canal
, "Pas de %s ." % ( giv_let
))
454 self
. perd ( serv
, canal
)
456 self
. tried_letters
[ canal
]. add ( giv_let
)
457 if all ([ lettre
[ 1 ] for lettre
in listeapres
]):
458 self
. gagne ( serv
, canal
)
464 def on_action ( self
, serv
, ev
):
465 if ignore_event ( serv
, ev
):
467 action
= ev
. arguments ()[ 0 ]
468 auteur
= irclib
. nm_to_n ( ev
. source ())
469 channel
= ev
. target ()
472 def on_kick ( self
, serv
, ev
):
473 auteur
= irclib
. nm_to_n ( ev
. source ())
474 channel
= ev
. target ()
475 victime
= ev
. arguments ()[ 0 ]
476 raison
= ev
. arguments ()[ 1 ]
477 if victime
== self
. nick
:
478 log ( self
. serveur
, " %s kické de %s par %s (raison : %s )" %( victime
, channel
, auteur
, raison
))
481 # on ne dit rien au rejoin
482 #l1,l2=config.kick_answers,config.kick_actions
483 #n1,n2=len(l1),len(l2)
484 #i=random.randrange(n1+n2)
486 # serv.action(channel,l2[i-n1].format(auteur).encode("utf8"))
488 # serv.privmsg(channel,l1[i].format(auteur).encode("utf8"))
491 return self
. serv
. get_nickname ()
492 nick
= property ( _getnick
)
494 def quitter ( self
, chan
, leave_message
= None ):
495 if leave_message
== None :
496 leave_message
= random
. choice ( config
. leave_messages
)
497 self
. serv
. part ( chan
, message
= leave_message
. encode ( "utf8" ))
500 quit_message
= random
. choice ( config
. quit_messages
)
501 self
. die ( msg
= quit_message
. encode ( "utf8" ))
503 def get_scores ( self
):
504 f
= open ( config
. scores_file
)
505 scores
= pickle
. load ( f
)
508 def save_scores ( self
, scores
):
509 f
= open ( config
. scores_file
, 'w' )
510 pickle
. dump ( scores
, f
)
512 def add_score ( self
, dico
):
513 scores
= self
. get_scores ()
514 for k
, v
in dico
. items ():
515 if scores
. has_key ( k
):
519 self
. save_scores ( scores
)
520 def send_scores ( self
, serv
, destinataire
):
521 scores
= self
. get_scores ()
522 scores
= scores
. items ()
523 scores
. sort ( lambda x
, y
: cmp ( x
[ 1 ], y
[ 1 ]))
525 serv
. privmsg ( destinataire
, "Scores by score : " + " ; " . join ([ " %s %s " %( k
, v
) for ( k
, v
) in scores
]) )
526 scores
. sort ( lambda x
, y
: cmp ( x
[ 0 ]. lower (), y
[ 0 ]. lower ()))
527 serv
. privmsg ( destinataire
, "Scores by pseudo : " + " ; " . join ([ " %s %s " %( k
, v
) for ( k
, v
) in scores
]) )
529 def gagne ( self
, serv
, canal
, bonus
= None , bonusvalue
= 2 ):
530 serv
. privmsg ( canal
, "Bravo !" )
531 realword
= self
. reveal_word ( serv
, canal
)
532 nlettre
= float ( len ([ l
for l
in realword
if not l
in config
. non_guess_chars
]))
533 contribs
=[ " %s : %s%%%s " %( pseudo
, str ( int ( 100 * contrib
/ nlettre
)),( "+bonus( %s )" %(bonusvalue))*( bonus
== pseudo
)) for pseudo
, contrib
in self
. play_status
[ canal
][ 2 ]. items ()]
534 contribs_score
={ pseudo
: int ( 10.0 * contrib
/ nlettre
)+( bonusvalue
*( bonus
== pseudo
)) for pseudo
, contrib
in self
. play_status
[ canal
][ 2 ]. items ()}
535 self
. add_score ( contribs_score
)
536 serv
. privmsg ( canal
, "Contributions : %s " %( " " . join ( contribs
)) )
537 self
. play_status
[ canal
]=[ None , None , None ]
539 def reveal_word ( self
, serv
, canal
):
540 realword
= "" . join ([ lettre
[ 0 ] for lettre
in self
. play_status
[ canal
][ 0 ]])
541 serv
. privmsg ( canal
, "C'était %s ." % ( realword
))
542 definition
= self
. play_status
[ canal
][ 1 ]
543 serv
. privmsg ( canal
, definition
)
546 def perd ( self
, serv
, canal
):
547 serv
. privmsg ( canal
, "Pendu !" )
548 self
. reveal_word ( serv
, canal
)
549 self
. play_status
[ canal
]=[ None , None , None ]
551 def reload ( self
, auteur
= None ):
553 if auteur
in [ None , "SIGHUP" ]:
554 towrite
= "Config reloaded" + " (SIGHUP received)" *( auteur
== "SIGHUP" )
555 for to
in config
. report_bugs_to
:
556 self
. serv
. privmsg ( to
, towrite
)
557 log ( self
. serveur
, towrite
)
559 self
. serv
. privmsg ( auteur
, "Config reloaded" )
561 def start_as_daemon ( self
, outfile
):
562 sys
. stderr
= Logger ( outfile
)
566 class Logger ( object ):
567 """Pour écrire ailleurs que sur stdout"""
568 def __init__ ( self
, filename
= "hung.full.log" ):
569 self
. filename
= filename
571 def write ( self
, message
):
572 f
= open ( self
. filename
, "a" )
577 if __name__
== "__main__" :
580 print "Usage : hung.py <serveur> [--debug] [--no-output] [--daemon [--pidfile]] [--outfile]"
581 print " --outfile sans --no-output ni --daemon n'a aucun effet"
584 if "--daemon" in sys
. argv
:
585 thisfile
= os
. path
. realpath ( __file__
)
586 thisdirectory
= thisfile
. rsplit ( "/" , 1 )[ 0 ]
587 os
. chdir ( thisdirectory
)
591 if "debug" in sys
. argv
or "--debug" in sys
. argv
:
595 if "--no-output" in sys
. argv
or "--daemon" in sys
. argv
:
596 outfile
= "/var/log/bots/hung.full.log"
599 if arg
[ 0 ]. strip ( '-' ) in [ "out" , "outfile" , "logfile" ]:
601 sys
. stdout
= Logger ( outfile
)
602 serveurs
={ "a♡" : "acoeur.crans.org" , "acoeur" : "acoeur.crans.org" , "acoeur.crans.org" : "acoeur.crans.org" ,
603 "irc" : "irc.crans.org" , "crans" : "irc.crans.org" , "irc.crans.org" : "irc.crans.org" ,
604 "localhost" : "localhost" }
606 serveur
= serveurs
[ serveur
]
608 print "Server Unknown : %s " %(serveur)
610 hung
= Hung ( serveur
, debug
)
611 # Si on reçoit un SIGHUP, on reload la config
612 def sighup_handler ( signum
, frame
):
613 hung
. reload ( "SIGHUP" )
614 signal
. signal ( signal
. SIGHUP
, sighup_handler
)
616 child_pid
= os
. fork ()
619 hung
. start_as_daemon ( outfile
)
621 # on enregistre le pid de hung
622 pidfile
= "/var/run/bots/hung.pid"
625 if arg
[ 0 ]. strip ( '-' ) in [ "pidfile" ]:
627 f
= open ( pidfile
, "w" )
628 f
. write ( " %s \n " % child_pid
)