]>
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
:
46 class UnicodeBotError ( Exception ):
48 def bot_unicode ( chain
):
51 except UnicodeDecodeError as exc
:
54 def remplace_accents ( chaine
):
56 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" }
57 for avant
, apres
in remplacements
. items ():
58 chaine
= chaine
. replace ( avant
, apres
)
61 def is_something ( chain
, matches
, avant
= u
".*(?:^| )" , apres
= u
"(?:$|\.| |,|;).*" , case_sensitive
= False , debug
= False ):
63 chain
= unicode ( chain
, "utf8" )
65 chain
= unicode ( chain
, "utf8" ). lower ()
66 allmatches
= "(" + "|" . join ( matches
)+ ")"
67 reg
=( avant
+ allmatches
+ apres
). lower ()
72 return is_something ( chain
, config
. tag_triggers
)
74 def is_mot ( mot
, liste
):
75 real_word
= "" . join ([ lettre
[ 0 ] for lettre
in liste
])
76 real_word
= real_word
. decode ( "utf8" ). lower ()
77 mot
= remplace_accents ( mot
. decode ( "utf8" ))
80 class Hung ( ircbot
. SingleServerIRCBot
):
81 def __init__ ( self
, serveur
, debug
= False ):
82 temporary_pseudo
= config
. irc_pseudo
+ str ( random
. randrange ( 10000 , 100000 ))
83 ircbot
. SingleServerIRCBot
.__ init
__ ( self
, [( serveur
, 6667 )],
84 temporary_pseudo
, "Bot irc pour jouer au pendu" , 10 )
87 self
. overops
= config
. overops
88 self
. ops
= self
. overops
+ config
. ops
89 self
. report_bugs_to
= config
. report_bugs_to
90 self
. chanlist
= config
. chanlist
91 self
. stay_channels
= config
. stay_channels
92 self
. play_channels
= config
. play_channels
93 self
. play_status
={ i
:[ None , None , None ] for i
in self
. play_channels
}
96 self
. quiet_channels
= config
. quiet_channels
99 def give_me_my_pseudo ( self
, serv
):
100 serv
. privmsg ( "NickServ" , "RECOVER %s %s " %( config
. irc_pseudo
, config
. irc_password
))
101 serv
. privmsg ( "NickServ" , "RELEASE %s %s " %( config
. irc_pseudo
, config
. irc_password
))
103 serv
. nick ( config
. irc_pseudo
)
105 def on_welcome ( self
, serv
, ev
):
106 self
. serv
= serv
# ça serv ira :)
107 self
. give_me_my_pseudo ( serv
)
108 serv
. privmsg ( "NickServ" , "IDENTIFY %s " %( config
. irc_password
))
109 log ( self
. serveur
, "Connected" )
111 self
. chanlist
=[ "#bot" ]
112 self
. play_channels
=[ "#bot" ]
113 for c
in self
. chanlist
:
114 log ( self
. serveur
, "JOIN %s " %(c))
117 def pourmoi ( self
, serv
, message
):
118 """renvoie (False,lemessage) ou (True, le message amputé de "pseudo: ")"""
119 pseudo
= serv
. get_nickname ()
121 if message
[: size
]== pseudo
and len ( message
)> size
and message
[ size
]== ":" :
122 return ( True , message
[ size
+ 1 :]. lstrip ( " " ))
124 return ( False , message
)
126 def on_privmsg ( self
, serv
, ev
):
127 message
= ev
. arguments ()[ 0 ]
128 auteur
= irclib
. nm_to_n ( ev
. source ())
130 test
= bot_unicode ( message
)
131 except UnicodeBotError
:
132 if config
. utf8_trigger
:
133 serv
. privmsg ( auteur
, random
. choice ( config
. utf8_fail_answers
). encode ( "utf8" ))
135 message
= message
. split ()
136 cmd
= message
[ 0 ]. lower ()
139 helpmsg_default
= """Liste des commandes :
140 HELP Affiche ce message d'aide
141 SCORE Affiche ton score
142 SCORES Affiche les scores"""
144 JOIN Faire rejoindre un channel (sans paramètres, donne la liste des chans actuels)
145 LEAVE Faire quitter un channel
146 PLAY Passe un channel en mode "jouer"
147 NOPLAY Passe un channel en mode "ne pas jouer"
148 QUIET Se taire sur un channel
149 NOQUIET Opposé de QUIET
150 RELOAD Recharge la config"""
152 SAY Fais envoyer un message sur un chan ou à une personne
153 DO Me fait faire une action sur un chan
154 STAY Ignorera les prochains LEAVE pour un chan
155 NOSTAY Opposé de STAY
156 STATUS Montre l'état courant
158 helpmsg
= helpmsg_default
159 if auteur
in self
. ops
:
161 if auteur
in self
. overops
:
162 helpmsg
+= helpmsg_overops
163 for ligne
in helpmsg
. split ( " \n " ):
164 serv
. privmsg ( auteur
, ligne
)
166 if auteur
in self
. ops
:
168 if message
[ 1 ] in self
. chanlist
:
169 serv
. privmsg ( auteur
, "Je suis déjà sur %s " %( message
[ 1 ]))
171 serv
. join ( message
[ 1 ])
172 self
. chanlist
. append ( message
[ 1 ])
173 serv
. privmsg ( auteur
, "Channels : " + " " . join ( self
. chanlist
))
174 log ( self
. serveur
, "priv" , auteur
, " " . join ( message
))
176 serv
. privmsg ( auteur
, "Channels : " + " " . join ( self
. chanlist
))
180 if auteur
in self
. ops
and len ( message
)> 1 :
181 if message
[ 1 ] in self
. chanlist
:
182 if not ( message
[ 1 ] in self
. stay_channels
) or auteur
in self
. overops
:
183 self
. quitter ( message
[ 1 ], " " . join ( message
[ 2 :]))
184 self
. chanlist
. remove ( message
[ 1 ])
185 log ( self
. serveur
, "priv" , auteur
, " " . join ( message
)+ "[successful]" )
187 serv
. privmsg ( auteur
, "Non, je reste !" )
188 log ( self
. serveur
, "priv" , auteur
, " " . join ( message
)+ "[failed]" )
190 serv
. privmsg ( auteur
, "Je ne suis pas sur %s " %( message
[ 1 ]))
194 if auteur
in self
. ops
:
196 if message
[ 1 ] in self
. play_channels
:
198 self
. start_partie ( serv
, message
[ 1 ], " " . join ( message
[ 2 :]))
200 serv
. privmsg ( auteur
, "Je play déjà sur %s ." %( message
[ 1 ]))
201 log ( self
. serveur
, "priv" , auteur
, " " . join ( message
)+ "[failed]" )
203 self
. play_channels
. append ( message
[ 1 ])
204 self
. play_status
[ message
[ 1 ]]=[ None , None , None ]
205 serv
. privmsg ( auteur
, "Play channels : " + " " . join ( self
. play_channels
))
206 log ( self
. serveur
, "priv" , auteur
, " " . join ( message
)+ "[successful]" )
208 serv
. privmsg ( auteur
, "Play channels : " + " " . join ( self
. play_channels
))
212 if auteur
in self
. ops
:
214 if message
[ 1 ] in self
. play_channels
:
215 self
. play_channels
. remove ( message
[ 1 ])
216 serv
. privmsg ( auteur
, "Play channels : " + " " . join ( self
. play_channels
))
217 log ( self
. serveur
, "priv" , auteur
, " " . join ( message
)+ "[successful]" )
219 serv
. privmsg ( auteur
, "Je ne play pas sur %s ." %( message
[ 1 ]))
220 log ( self
. serveur
, "priv" , auteur
, " " . join ( message
)+ "[failed]" )
224 if auteur
in self
. overops
:
226 if message
[ 1 ] in self
. stay_channels
:
227 log ( self
. serveur
, "priv" , auteur
, " " . join ( message
)+ "[failed]" )
228 serv
. privmsg ( auteur
, "Je stay déjà sur %s ." %( message
[ 1 ]))
230 log ( self
. serveur
, "priv" , auteur
, " " . join ( message
)+ "[successful]" )
231 self
. stay_channels
. append ( message
[ 1 ])
232 serv
. privmsg ( auteur
, "Stay channels : " + " " . join ( self
. stay_channels
))
234 serv
. privmsg ( auteur
, "Stay channels : " + " " . join ( self
. stay_channels
))
238 if auteur
in self
. overops
:
240 if message
[ 1 ] in self
. stay_channels
:
241 log ( self
. serveur
, "priv" , auteur
, " " . join ( message
)+ "[successful]" )
242 self
. stay_channels
. remove ( message
[ 1 ])
243 serv
. privmsg ( auteur
, "Stay channels : " + " " . join ( self
. stay_channels
))
245 log ( self
. serveur
, "priv" , auteur
, " " . join ( message
)+ "[failed]" )
246 serv
. privmsg ( auteur
, "Je ne stay pas sur %s ." %( message
[ 1 ]))
250 elif cmd
in [ "states" , "status" ]:
251 if auteur
in self
. overops
:
252 for k
in self
. play_status
. keys ():
253 if self
. play_status
[ k
]==[ None , None , None ]:
254 serv
. privmsg ( auteur
, "None" )
256 serv
. privmsg ( auteur
, " %s : %s ( %s ) [ %s ]" %( k
, "" . join ([ str ( i
[ 0 ]) for i
in self
. play_status
[ k
][ 0 ]])
257 , self
. play_status
[ k
][ 1 ], self
. play_status
[ k
][ 2 ]))
259 if auteur
in self
. overops
:
260 log ( self
. serveur
, "priv" , auteur
, " " . join ( message
)+ "[successful]" )
265 if auteur
in self
. ops
:
267 if message
[ 1 ] in self
. quiet_channels
:
268 serv
. privmsg ( auteur
, "Je me la ferme déjà sur %s " %( message
[ 1 ]))
269 log ( self
. serveur
, "priv" , auteur
, " " . join ( message
)+ "[failed]" )
271 self
. quiet_channels
. append ( message
[ 1 ])
272 serv
. privmsg ( auteur
, "Quiet channels : " + " " . join ( self
. quiet_channels
))
273 log ( self
. serveur
, "priv" , auteur
, " " . join ( message
)+ "[successful]" )
275 serv
. privmsg ( auteur
, "Quiet channels : " + " " . join ( self
. quiet_channels
))
279 if auteur
in self
. ops
:
281 if message
[ 1 ] in self
. quiet_channels
:
282 self
. quiet_channels
. remove ( message
[ 1 ])
283 serv
. privmsg ( auteur
, "Quiet channels : " + " " . join ( self
. quiet_channels
))
284 log ( self
. serveur
, "priv" , auteur
, " " . join ( message
)+ "[successful]" )
286 serv
. privmsg ( auteur
, "Je ne me la ferme pas sur %s ." %( message
[ 1 ]))
287 log ( self
. serveur
, "priv" , auteur
, " " . join ( message
)+ "[failed]" )
291 if auteur
in self
. ops
:
293 log ( self
. serveur
, "priv" , auteur
, " " . join ( message
)+ "[successful]" )
297 if auteur
in self
. overops
and len ( message
)> 2 :
298 serv
. privmsg ( message
[ 1 ], " " . join ( message
[ 2 :]))
299 log ( self
. serveur
, "priv" , auteur
, " " . join ( message
))
300 elif len ( message
)<= 2 :
301 serv
. privmsg ( auteur
, "Syntaxe : SAY <channel> <message>" )
305 if auteur
in self
. overops
and len ( message
)> 2 :
306 serv
. action ( message
[ 1 ], " " . join ( message
[ 2 :]))
307 log ( self
. serveur
, "priv" , auteur
, " " . join ( message
))
308 elif len ( message
)<= 2 :
309 serv
. privmsg ( auteur
, "Syntaxe : DO <channel> <action>" )
312 elif cmd
in [ "score" , "scores" ]:
313 self
. send_scores ( serv
, auteur
)
317 serv
. privmsg ( auteur
, "Je n'ai pas compris. Essaye HELP…" )
319 def affiche_mot ( self
, serv
, canal
, begin
= "Mot courant" ):
320 if self
. play_status
. has_key ( canal
):
321 mot
= self
. play_status
[ canal
][ 0 ]
322 obfuskated
= " " . join ([ lettre
[ 0 ] if lettre
[ 1 ] else "_" for lettre
in mot
])
323 serv
. privmsg ( canal
, " %s : %s " %( begin
, obfuskated
))
325 def start_partie ( self
, serv
, canal
, mot
= None ):
327 mots
=[ mot
. strip () for mot
in open ( config
. dico_mots
). readlines ()]
328 defs
=[ defi
. strip () for defi
in open ( config
. dico_defs
). readlines ()]
329 indice
= random
. randrange ( 0 , len ( mots
))
330 mot
, definition
= mots
[ indice
], defs
[ indice
]
332 definition
= "(custom word)"
333 # ' et - sont considérés comme déjà devinés
334 mot
= [( lettre
, lettre
in config
. non_guess_chars
) for lettre
in list ( mot
)]
335 self
. play_status
[ canal
]=[ mot
, definition
,{}]
336 self
. tried_letters
[ canal
] = set ()
337 self
. lives
[ canal
] = config
. lives
338 self
. affiche_mot ( serv
, canal
, begin
= "Devinez" )
340 def on_pubmsg ( self
, serv
, ev
):
341 auteur
= irclib
. nm_to_n ( ev
. source ())
343 message
= ev
. arguments ()[ 0 ]
345 test
= bot_unicode ( message
)
346 except UnicodeBotError
:
347 if config
. utf8_trigger
and not canal
in self
. quiet_channels
:
348 serv
. privmsg ( canal
, ( u
" %s : %s " %( auteur
, random
. choice ( config
. utf8_fail_answers
))). encode ( "utf8" ))
350 pour_moi
, message
= self
. pourmoi ( serv
, message
)
351 if pour_moi
and message
. split ()!=[]:
352 cmd
= message
. split ()[ 0 ]. lower ()
354 args
= " " . join ( message
. split ()[ 1 :])
357 if cmd
in [ "meurs" , "die" , "crève" ]:
358 if auteur
in self
. overops
:
359 log ( self
. serveur
, canal
, auteur
, message
+ "[successful]" )
362 serv
. privmsg ( canal
, " %s : crève !" %(auteur))
363 log ( self
. serveur
, canal
, auteur
, message
+ "[failed]" )
364 elif cmd
== "reload" :
365 if auteur
in self
. ops
:
366 log ( self
. serveur
, canal
, auteur
, message
+ "[successful]" )
368 elif cmd
in [ "part" , "leave" , "dégage" ]:
369 if auteur
in self
. ops
and ( not ( canal
in self
. stay_channels
)
370 or auteur
in self
. overops
):
372 log ( self
. serveur
, canal
, auteur
, message
+ "[successful]" )
373 if canal
in self
. chanlist
:
374 self
. chanlist
. remove ( canal
)
376 serv
. privmsg ( canal
, " %s : Non, je reste !" %(auteur))
377 log ( self
. serveur
, canal
, auteur
, message
+ "[failed]" )
378 elif cmd
in [ "play" , "jeu" , "encore" , "again" , "partie" , "pendu" , "game" , "mot" , "go" , "allez" ]:
379 if not canal
in self
. quiet_channels
and canal
in self
. play_channels
:
380 if self
. play_status
. has_key ( canal
):
381 if self
. play_status
[ canal
]==[ None , None , None ]:
382 self
. start_partie ( serv
, canal
)
384 self
. affiche_mot ( serv
, canal
, begin
= " %s : Rappel" %(auteur))
386 self
. play_status
[ canal
]=[ None , None , None ]
387 self
. start_partie ( serv
, canal
)
388 elif not canal
in self
. play_channels
:
389 serv
. privmsg ( canal
, " %s : pas ici…" %(auteur))
390 elif ( cmd
in list ( "azertyuiopqsdfghjklmwxcvbn" ) and canal
in self
. play_channels
391 and self
. play_status
. has_key ( canal
) and self
. play_status
[ canal
]!=[ None , None , None ]):
393 liste
= self
. play_status
[ canal
][ 0 ]
394 listeapres
=[( lettre
[ 0 ], lettre
[ 1 ] or lettre
[ 0 ]== giv_let
) for lettre
in liste
]
395 if liste
!= listeapres
:
396 nbtrouvees
=( sum ([ lettre
[ 1 ] for lettre
in listeapres
if not lettre
[ 0 ] in "'-()" ])
397 - sum ([ lettre
[ 1 ] for lettre
in liste
if not lettre
[ 0 ] in "'-()" ]))
398 if self
. play_status
[ canal
][ 2 ]. has_key ( auteur
):
399 self
. play_status
[ canal
][ 2 ][ auteur
]+= nbtrouvees
401 self
. play_status
[ canal
][ 2 ][ auteur
] = nbtrouvees
402 self
. play_status
[ canal
][ 0 ]= listeapres
403 self
. affiche_mot ( serv
, canal
, begin
= " %s placé" %(giv_let))
405 if not giv_let
in self
. tried_letters
[ canal
]:
407 self
. lives
[ canal
] -= 1
408 if self
. lives
[ canal
] > 0 :
409 serv
. privmsg ( canal
, "Pas de %s . Plus que %s chances…" % ( giv_let
, self
. lives
[ canal
]))
410 if self
. lives
[ canal
] == 0 :
411 serv
. privmsg ( canal
, "Pas de %s ." % ( giv_let
))
412 self
. perd ( serv
, canal
)
414 self
. tried_letters
[ canal
]. add ( giv_let
)
415 if all ([ lettre
[ 1 ] for lettre
in listeapres
]):
416 self
. gagne ( serv
, canal
)
418 elif cmd
in [ "score" , "scores" , "!score" , "!scores" ]:
419 self
. send_scores ( serv
, auteur
)
420 if cmd
in [ "meur" , "meurt" , "meurre" , "meurres" ] and not canal
in self
. quiet_channels
:
421 serv
. privmsg ( canal
, ' %s : Mourir, impératif, 2ème personne du singulier : "meurs" (de rien)' %(auteur))
422 if is_tag ( message
) and not canal
in self
. quiet_channels
:
423 if auteur
in self
. ops
:
424 action
= random
. choice ( config
. tag_actions
)
425 serv
. action ( canal
, action
. encode ( "utf8" ))
426 self
. quiet_channels
. append ( canal
)
428 answer
= random
. choice ( config
. tag_answers
)
429 for ligne
in answer
. split ( " \n " ):
430 serv
. privmsg ( canal
, " %s : %s " %( auteur
, ligne
. encode ( "utf8" )))
431 # on essaye de voir si le mot fourni matche la partie en cours
433 if canal
in self
. play_channels
and self
. play_status
[ canal
][ 0 ]!= None and is_mot ( mot
, self
. play_status
[ canal
][ 0 ]):
435 # on regarde combien de lettre il manquait
436 manquait
= sum ([ not lettre
[ 1 ] for lettre
in self
. play_status
[ canal
][ 0 ]])
437 self
. add_score ({ auteur
: manquait
})
438 if self
. play_status
[ canal
][ 2 ]. has_key ( auteur
):
439 self
. play_status
[ canal
][ 2 ][ auteur
]+= manquait
441 self
. play_status
[ canal
][ 2 ][ auteur
]= manquait
442 self
. gagne ( serv
, canal
, bonus
= auteur
, bonusvalue
= manquait
)
447 def on_action ( self
, serv
, ev
):
448 action
= ev
. arguments ()[ 0 ]
449 auteur
= irclib
. nm_to_n ( ev
. source ())
450 channel
= ev
. target ()
453 def on_kick ( self
, serv
, ev
):
454 auteur
= irclib
. nm_to_n ( ev
. source ())
455 channel
= ev
. target ()
456 victime
= ev
. arguments ()[ 0 ]
457 raison
= ev
. arguments ()[ 1 ]
458 if victime
== self
. nick
:
459 log ( self
. serveur
, " %s kické de %s par %s (raison : %s )" %( victime
, channel
, auteur
, raison
))
462 # on ne dit rien au rejoin
463 #l1,l2=config.kick_answers,config.kick_actions
464 #n1,n2=len(l1),len(l2)
465 #i=random.randrange(n1+n2)
467 # serv.action(channel,l2[i-n1].format(auteur).encode("utf8"))
469 # serv.privmsg(channel,l1[i].format(auteur).encode("utf8"))
472 return self
. serv
. get_nickname ()
473 nick
= property ( _getnick
)
475 def quitter ( self
, chan
, leave_message
= None ):
476 if leave_message
== None :
477 leave_message
= random
. choice ( config
. leave_messages
)
478 self
. serv
. part ( chan
, message
= leave_message
. encode ( "utf8" ))
481 quit_message
= random
. choice ( config
. quit_messages
)
482 self
. die ( msg
= quit_message
. encode ( "utf8" ))
484 def get_scores ( self
):
485 f
= open ( config
. scores_file
)
486 scores
= pickle
. load ( f
)
489 def save_scores ( self
, scores
):
490 f
= open ( config
. scores_file
, 'w' )
491 pickle
. dump ( scores
, f
)
493 def add_score ( self
, dico
):
494 scores
= self
. get_scores ()
495 for k
, v
in dico
. items ():
496 if scores
. has_key ( k
):
500 self
. save_scores ( scores
)
501 def send_scores ( self
, serv
, destinataire
):
502 scores
= self
. get_scores ()
503 scores
= scores
. items ()
504 scores
. sort ( lambda x
, y
: cmp ( x
[ 1 ], y
[ 1 ]))
506 serv
. privmsg ( destinataire
, "Scores by score : " + " ; " . join ([ " %s %s " %( k
, v
) for ( k
, v
) in scores
]) )
507 scores
. sort ( lambda x
, y
: cmp ( x
[ 0 ]. lower (), y
[ 0 ]. lower ()))
508 serv
. privmsg ( destinataire
, "Scores by pseudo : " + " ; " . join ([ " %s %s " %( k
, v
) for ( k
, v
) in scores
]) )
510 def gagne ( self
, serv
, canal
, bonus
= None , bonusvalue
= 2 ):
511 serv
. privmsg ( canal
, "Bravo !" )
512 realword
= self
. reveal_word ( serv
, canal
)
513 nlettre
= float ( len ( realword
. replace ( "'" , "" ). replace ( "-" , "" )))
514 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 ()]
515 contribs_score
={ pseudo
: int ( 10 * contrib
/ nlettre
) for pseudo
, contrib
in self
. play_status
[ canal
][ 2 ]. items ()}
516 self
. add_score ( contribs_score
)
517 serv
. privmsg ( canal
, "Contributions : %s " %( " " . join ( contribs
)) )
518 self
. play_status
[ canal
]=[ None , None , None ]
520 def reveal_word ( self
, serv
, canal
):
521 realword
= "" . join ([ lettre
[ 0 ] for lettre
in self
. play_status
[ canal
][ 0 ]])
522 serv
. privmsg ( canal
, "C'était %s ." % ( realword
))
523 definition
= self
. play_status
[ canal
][ 1 ]
524 serv
. privmsg ( canal
, definition
)
527 def perd ( self
, serv
, canal
):
528 serv
. privmsg ( canal
, "Pendu !" )
529 self
. reveal_word ( serv
, canal
)
530 self
. play_status
[ canal
]=[ None , None , None ]
532 def reload ( self
, auteur
= None ):
534 if auteur
in [ None , "SIGHUP" ]:
535 towrite
= "Config reloaded" + " (SIGHUP received)" *( auteur
== "SIGHUP" )
536 for to
in config
. report_bugs_to
:
537 self
. serv
. privmsg ( to
, towrite
)
538 log ( self
. serveur
, towrite
)
540 self
. serv
. privmsg ( auteur
, "Config reloaded" )
542 def start_as_daemon ( self
, outfile
):
543 sys
. stderr
= Logger ( outfile
)
547 class Logger ( object ):
548 """Pour écrire ailleurs que sur stdout"""
549 def __init__ ( self
, filename
= "hung.full.log" ):
550 self
. filename
= filename
552 def write ( self
, message
):
553 f
= open ( self
. filename
, "a" )
558 if __name__
== "__main__" :
561 print "Usage : hung.py <serveur> [--debug] [--no-output] [--daemon [--pidfile]] [--outfile]"
562 print " --outfile sans --no-output ni --daemon n'a aucun effet"
565 if "--daemon" in sys
. argv
:
566 thisfile
= os
. path
. realpath ( __file__
)
567 thisdirectory
= thisfile
. rsplit ( "/" , 1 )[ 0 ]
568 os
. chdir ( thisdirectory
)
572 if "debug" in sys
. argv
or "--debug" in sys
. argv
:
576 if "--no-output" in sys
. argv
or "--daemon" in sys
. argv
:
577 outfile
= "/var/log/bots/hung.full.log"
580 if arg
[ 0 ]. strip ( '-' ) in [ "out" , "outfile" , "logfile" ]:
582 sys
. stdout
= Logger ( outfile
)
583 serveurs
={ "a♡" : "acoeur.crans.org" , "acoeur" : "acoeur.crans.org" , "acoeur.crans.org" : "acoeur.crans.org" ,
584 "irc" : "irc.crans.org" , "crans" : "irc.crans.org" , "irc.crans.org" : "irc.crans.org" ,
585 "localhost" : "localhost" }
587 serveur
= serveurs
[ serveur
]
589 print "Server Unknown : %s " %(serveur)
591 hung
= Hung ( serveur
, debug
)
592 # Si on reçoit un SIGHUP, on reload la config
593 def sighup_handler ( signum
, frame
):
594 hung
. reload ( "SIGHUP" )
595 signal
. signal ( signal
. SIGHUP
, sighup_handler
)
597 child_pid
= os
. fork ()
600 hung
. start_as_daemon ( outfile
)
602 # on enregistre le pid de hung
603 pidfile
= "/var/run/bots/hung.pid"
606 if arg
[ 0 ]. strip ( '-' ) in [ "pidfile" ]:
608 f
= open ( pidfile
, "w" )
609 f
. write ( " %s \n " % child_pid
)