]> gitweb.pimeys.fr Git - bots/hung.git/blob - hung.py
On peut perdre
[bots/hung.git] / hung.py
1 #!/usr/bin/python
2 # -*- coding:utf8 -*-
3
4 # Codé par 20-100 le 23/04/12
5
6 # Un bot IRC qui joue au pendu
7
8 import threading
9 import random
10 import time
11 import socket, ssl, json
12 import pickle
13 import re
14 import os
15 import signal
16 import sys
17 from commands import getstatusoutput as ex
18
19 # Oui, j'ai recodé ma version d'irclib pour pouvoir rattrapper les SIGHUP
20 sys.path.insert(0, "/home/vincent/scripts/python-myirclib")
21 import irclib
22 import ircbot
23
24 import sys
25
26 # Fichier de conf
27 import config
28
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])
32
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)
38 else:
39 chain="%s [%s:%s] %s"%(time.strftime("%F %T"),channel,auteur,message)
40 f.write(chain+"\n")
41 if config.debug_stdout:
42 print chain
43 f.close()
44
45
46 class UnicodeBotError(Exception):
47 pass
48 def bot_unicode(chain):
49 try:
50 unicode(chain,"utf8")
51 except UnicodeDecodeError as exc:
52 raise UnicodeBotError
53
54 def remplace_accents(chaine):
55 chaine=chaine.lower()
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)
59 return chaine
60
61 def is_something(chain,matches,avant=u".*(?:^| )",apres=u"(?:$|\.| |,|;).*",case_sensitive=False,debug=False):
62 if case_sensitive:
63 chain=unicode(chain,"utf8")
64 else:
65 chain=unicode(chain,"utf8").lower()
66 allmatches="("+"|".join(matches)+")"
67 reg=(avant+allmatches+apres).lower()
68 o=re.match(reg,chain)
69 return o
70
71 def is_tag(chain):
72 return is_something(chain,config.tag_triggers)
73
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"))
78 return mot==real_word
79
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)
85 self.debug=debug
86 self.serveur=serveur
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}
94 self.lives={}
95 self.tried_letters={}
96 self.quiet_channels=config.quiet_channels
97
98
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))
102 time.sleep(0.3)
103 serv.nick(config.irc_pseudo)
104
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")
110 if self.debug:
111 self.chanlist=["#bot"]
112 self.play_channels=["#bot"]
113 for c in self.chanlist:
114 log(self.serveur,"JOIN %s"%(c))
115 serv.join(c)
116
117 def pourmoi(self, serv, message):
118 """renvoie (False,lemessage) ou (True, le message amputé de "pseudo: ")"""
119 pseudo=serv.get_nickname()
120 size=len(pseudo)
121 if message[:size]==pseudo and len(message)>size and message[size]==":":
122 return (True,message[size+1:].lstrip(" "))
123 else:
124 return (False,message)
125
126 def on_privmsg(self, serv, ev):
127 message=ev.arguments()[0]
128 auteur = irclib.nm_to_n(ev.source())
129 try:
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"))
134 return
135 message=message.split()
136 cmd=message[0].lower()
137 notunderstood=False
138 if cmd=="help":
139 helpmsg_default="""Liste des commandes :
140 HELP Affiche ce message d'aide
141 SCORE Affiche ton score
142 SCORES Affiche les scores"""
143 helpmsg_ops="""
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"""
151 helpmsg_overops="""
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
157 DIE Mourir"""
158 helpmsg=helpmsg_default
159 if auteur in self.ops:
160 helpmsg+=helpmsg_ops
161 if auteur in self.overops:
162 helpmsg+=helpmsg_overops
163 for ligne in helpmsg.split("\n"):
164 serv.privmsg(auteur,ligne)
165 elif cmd=="join":
166 if auteur in self.ops:
167 if len(message)>1:
168 if message[1] in self.chanlist:
169 serv.privmsg(auteur,"Je suis déjà sur %s"%(message[1]))
170 else:
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))
175 else:
176 serv.privmsg(auteur,"Channels : "+" ".join(self.chanlist))
177 else:
178 notunderstood=True
179 elif cmd=="leave":
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]")
186 else:
187 serv.privmsg(auteur,"Non, je reste !")
188 log(self.serveur,"priv",auteur," ".join(message)+"[failed]")
189 else:
190 serv.privmsg(auteur,"Je ne suis pas sur %s"%(message[1]))
191 else:
192 notunderstood=True
193 elif cmd=="play":
194 if auteur in self.ops:
195 if len(message)>1:
196 if message[1] in self.play_channels:
197 serv.privmsg(auteur,"Je play déjà sur %s."%(message[1]))
198 log(self.serveur,"priv",auteur," ".join(message)+"[failed]")
199 else:
200 self.play_channels.append(message[1])
201 self.play_status[message[1]]=[None,None,None]
202 serv.privmsg(auteur,"Play channels : "+" ".join(self.play_channels))
203 log(self.serveur,"priv",auteur," ".join(message)+"[successful]")
204 else:
205 serv.privmsg(auteur,"Play channels : "+" ".join(self.play_channels))
206 else:
207 notunderstood=True
208 elif cmd=="noplay":
209 if auteur in self.ops:
210 if len(message)>1:
211 if message[1] in self.play_channels:
212 self.play_channels.remove(message[1])
213 serv.privmsg(auteur,"Play channels : "+" ".join(self.play_channels))
214 log(self.serveur,"priv",auteur," ".join(message)+"[successful]")
215 else:
216 serv.privmsg(auteur,"Je ne play pas sur %s."%(message[1]))
217 log(self.serveur,"priv",auteur," ".join(message)+"[failed]")
218 else:
219 notunderstood=True
220 elif cmd=="stay":
221 if auteur in self.overops:
222 if len(message)>1:
223 if message[1] in self.stay_channels:
224 log(self.serveur,"priv",auteur," ".join(message)+"[failed]")
225 serv.privmsg(auteur,"Je stay déjà sur %s."%(message[1]))
226 else:
227 log(self.serveur,"priv",auteur," ".join(message)+"[successful]")
228 self.stay_channels.append(message[1])
229 serv.privmsg(auteur,"Stay channels : "+" ".join(self.stay_channels))
230 else:
231 serv.privmsg(auteur,"Stay channels : "+" ".join(self.stay_channels))
232 else:
233 notunderstood=True
234 elif cmd=="nostay":
235 if auteur in self.overops:
236 if len(message)>1:
237 if message[1] in self.stay_channels:
238 log(self.serveur,"priv",auteur," ".join(message)+"[successful]")
239 self.stay_channels.remove(message[1])
240 serv.privmsg(auteur,"Stay channels : "+" ".join(self.stay_channels))
241 else:
242 log(self.serveur,"priv",auteur," ".join(message)+"[failed]")
243 serv.privmsg(auteur,"Je ne stay pas sur %s."%(message[1]))
244
245 else:
246 notunderstood=True
247 elif cmd in ["states","status"]:
248 if auteur in self.overops:
249 for k in self.play_status.keys():
250 if self.play_status[k]==[None,None,None]:
251 serv.privmsg(auteur,"None")
252 else:
253 serv.privmsg(auteur,"%s : %s (%s) [%s]"%(k,"".join([str(i[0]) for i in self.play_status[k][0]])
254 ,self.play_status[k][1], self.play_status[k][2]))
255 elif cmd=="die":
256 if auteur in self.overops:
257 log(self.serveur,"priv",auteur," ".join(message)+"[successful]")
258 self.mourir()
259 else:
260 notunderstood=True
261 elif cmd=="quiet":
262 if auteur in self.ops:
263 if len(message)>1:
264 if message[1] in self.quiet_channels:
265 serv.privmsg(auteur,"Je me la ferme déjà sur %s"%(message[1]))
266 log(self.serveur,"priv",auteur," ".join(message)+"[failed]")
267 else:
268 self.quiet_channels.append(message[1])
269 serv.privmsg(auteur,"Quiet channels : "+" ".join(self.quiet_channels))
270 log(self.serveur,"priv",auteur," ".join(message)+"[successful]")
271 else:
272 serv.privmsg(auteur,"Quiet channels : "+" ".join(self.quiet_channels))
273 else:
274 notunderstood=True
275 elif cmd=="noquiet":
276 if auteur in self.ops:
277 if len(message)>1:
278 if message[1] in self.quiet_channels:
279 self.quiet_channels.remove(message[1])
280 serv.privmsg(auteur,"Quiet channels : "+" ".join(self.quiet_channels))
281 log(self.serveur,"priv",auteur," ".join(message)+"[successful]")
282 else:
283 serv.privmsg(auteur,"Je ne me la ferme pas sur %s."%(message[1]))
284 log(self.serveur,"priv",auteur," ".join(message)+"[failed]")
285 else:
286 notunderstood=True
287 elif cmd=="reload":
288 if auteur in self.ops:
289 self.reload(auteur)
290 log(self.serveur,"priv",auteur," ".join(message)+"[successful]")
291 else:
292 notunderstood=True
293 elif cmd=="say":
294 if auteur in self.overops and len(message)>2:
295 serv.privmsg(message[1]," ".join(message[2:]))
296 log(self.serveur,"priv",auteur," ".join(message))
297 elif len(message)<=2:
298 serv.privmsg(auteur,"Syntaxe : SAY <channel> <message>")
299 else:
300 notunderstood=True
301 elif cmd=="do":
302 if auteur in self.overops and len(message)>2:
303 serv.action(message[1]," ".join(message[2:]))
304 log(self.serveur,"priv",auteur," ".join(message))
305 elif len(message)<=2:
306 serv.privmsg(auteur,"Syntaxe : DO <channel> <action>")
307 else:
308 notunderstood=True
309 elif cmd in ["score","scores"]:
310 self.send_scores(serv,auteur)
311 else:
312 notunderstood=True
313 if notunderstood:
314 serv.privmsg(auteur,"Je n'ai pas compris. Essaye HELP…")
315
316 def affiche_mot(self, serv, canal, begin="Mot courant"):
317 if self.play_status.has_key(canal):
318 mot = self.play_status[canal][0]
319 obfuskated=" ".join([lettre[0] if lettre[1] else "_" for lettre in mot])
320 serv.privmsg(canal,"%s : %s"%(begin,obfuskated))
321
322 def start_partie(self, serv, canal):
323 mots=[mot.strip() for mot in open(config.dico_mots).readlines()]
324 defs=[defi.strip() for defi in open(config.dico_defs).readlines()]
325 indice = random.randrange(0,len(mots))
326 mot,definition=mots[indice],defs[indice]
327 # ' et - sont considérés comme déjà devinés
328 mot = [(lettre,lettre in "'-()") for lettre in list(mot)]
329 self.play_status[canal]=[mot,definition,{}]
330 self.tried_letters[canal] = set ()
331 self.lives[canal] = config.lives
332 self.affiche_mot(serv, canal, begin="Devinez")
333
334 def on_pubmsg(self, serv, ev):
335 auteur = irclib.nm_to_n(ev.source())
336 canal = ev.target()
337 message = ev.arguments()[0]
338 try:
339 test=bot_unicode(message)
340 except UnicodeBotError:
341 if config.utf8_trigger and not canal in self.quiet_channels:
342 serv.privmsg(canal, (u"%s: %s"%(auteur,random.choice(config.utf8_fail_answers))).encode("utf8"))
343 return
344 pour_moi,message=self.pourmoi(serv,message)
345 if pour_moi and message.split()!=[]:
346 cmd=message.split()[0].lower()
347 try:
348 args=" ".join(message.split()[1:])
349 except:
350 args=""
351 if cmd in ["meurs","die","crève"]:
352 if auteur in self.overops:
353 log(self.serveur,canal,auteur,message+"[successful]")
354 self.mourir()
355 else:
356 serv.privmsg(canal,"%s: crève !"%(auteur))
357 log(self.serveur,canal,auteur,message+"[failed]")
358 elif cmd == "reload":
359 if auteur in self.ops:
360 log(self.serveur, canal, auteur, message+"[successful]")
361 self.reload(canal)
362 elif cmd in ["part","leave","dégage"]:
363 if auteur in self.ops and (not (canal in self.stay_channels)
364 or auteur in self.overops):
365 self.quitter(canal)
366 log(self.serveur,canal,auteur,message+"[successful]")
367 if canal in self.chanlist:
368 self.chanlist.remove(canal)
369 else:
370 serv.privmsg(canal,"%s: Non, je reste !"%(auteur))
371 log(self.serveur,canal,auteur,message+"[failed]")
372 elif cmd in ["play","jeu","encore","again","partie","pendu","game","mot","go","allez"]:
373 if not canal in self.quiet_channels and canal in self.play_channels:
374 if self.play_status.has_key(canal):
375 if self.play_status[canal]==[None,None,None]:
376 self.start_partie(serv, canal)
377 else:
378 self.affiche_mot(serv, canal, begin="%s: Rappel"%(auteur))
379 else:
380 self.play_status[canal]=[None,None,None]
381 self.start_partie(serv, canal)
382 elif not canal in self.play_channels:
383 serv.privmsg(canal,"%s: pas ici…"%(auteur))
384 elif (cmd in list("azertyuiopqsdfghjklmwxcvbn") and canal in self.play_channels
385 and self.play_status.has_key(canal) and self.play_status[canal]!=[None,None,None]):
386 giv_let=cmd.upper()
387 liste=self.play_status[canal][0]
388 listeapres=[(lettre[0],lettre[1] or lettre[0]==giv_let) for lettre in liste]
389 if liste!=listeapres:
390 nbtrouvees=(sum([lettre[1] for lettre in listeapres if not lettre[0] in "'-()"])
391 - sum([lettre[1] for lettre in liste if not lettre[0] in "'-()"]))
392 if self.play_status[canal][2].has_key(auteur):
393 self.play_status[canal][2][auteur]+= nbtrouvees
394 else:
395 self.play_status[canal][2][auteur] = nbtrouvees
396 self.play_status[canal][0]=listeapres
397 self.affiche_mot(serv, canal, begin="%s placé"%(giv_let))
398 else:
399 if not giv_let in self.tried_letters[canal]:
400 # On perd une chance
401 self.lives[canal] -= 1
402 if self.lives[canal] > 0:
403 serv.privmsg(canal, "Pas de %s. Plus que %s chances…" % (giv_let, self.lives[canal]))
404 if self.lives[canal] == 0:
405 serv.privmsg(canal, "Pas de %s." % (giv_let))
406 self.perd(serv, canal)
407 return
408 self.tried_letters[canal].add(giv_let)
409 if all([lettre[1] for lettre in listeapres]):
410 self.gagne(serv, canal)
411
412 elif cmd in ["score","scores","!score","!scores"]:
413 self.send_scores(serv,auteur)
414 if cmd in ["meur", "meurt","meurre","meurres"] and not canal in self.quiet_channels:
415 serv.privmsg(canal,'%s: Mourir, impératif, 2ème personne du singulier : "meurs" (de rien)'%(auteur))
416 if is_tag(message) and not canal in self.quiet_channels:
417 if auteur in self.ops:
418 action=random.choice(config.tag_actions)
419 serv.action(canal,action.encode("utf8"))
420 self.quiet_channels.append(canal)
421 else:
422 answer=random.choice(config.tag_answers)
423 for ligne in answer.split("\n"):
424 serv.privmsg(canal,"%s: %s"%(auteur,ligne.encode("utf8")))
425 # on essaye de voir si le mot fourni matche la partie en cours
426 mot = cmd
427 if self.play_status[canal][0]!=None and is_mot(mot, self.play_status[canal][0]):
428 # on a trouvé le mot
429 # on regarde combien de lettre il manquait
430 manquait = sum([not lettre[1] for lettre in self.play_status[canal][0]])
431 self.add_score({auteur: manquait})
432 if self.play_status[canal][2].has_key(auteur):
433 self.play_status[canal][2][auteur]+=manquait
434 else:
435 self.play_status[canal][2][auteur]=manquait
436 self.gagne(serv, canal, bonus=auteur, bonusvalue=manquait)
437 else:
438 pass
439
440
441 def on_action(self, serv, ev):
442 action = ev.arguments()[0]
443 auteur = irclib.nm_to_n(ev.source())
444 channel = ev.target()
445
446
447 def on_kick(self,serv,ev):
448 auteur = irclib.nm_to_n(ev.source())
449 channel = ev.target()
450 victime = ev.arguments()[0]
451 raison = ev.arguments()[1]
452 if victime==self.nick:
453 log(self.serveur,"%s kické de %s par %s (raison : %s)" %(victime,channel,auteur,raison))
454 time.sleep(5)
455 serv.join(channel)
456 # on ne dit rien au rejoin
457 #l1,l2=config.kick_answers,config.kick_actions
458 #n1,n2=len(l1),len(l2)
459 #i=random.randrange(n1+n2)
460 #if i>=n1:
461 # serv.action(channel,l2[i-n1].format(auteur).encode("utf8"))
462 #else:
463 # serv.privmsg(channel,l1[i].format(auteur).encode("utf8"))
464
465 def _getnick(self):
466 return self.serv.get_nickname()
467 nick = property(_getnick)
468
469 def quitter(self,chan,leave_message=None):
470 if leave_message==None:
471 leave_message=random.choice(config.leave_messages)
472 self.serv.part(chan,message=leave_message.encode("utf8"))
473
474 def mourir(self):
475 quit_message=random.choice(config.quit_messages)
476 self.die(msg=quit_message.encode("utf8"))
477
478 def get_scores(self):
479 f=open(config.scores_file)
480 scores=pickle.load(f)
481 f.close()
482 return scores
483 def save_scores(self,scores):
484 f=open(config.scores_file,'w')
485 pickle.dump(scores,f)
486 f.close()
487 def add_score(self,dico):
488 scores=self.get_scores()
489 for k,v in dico.items():
490 if scores.has_key(k):
491 scores[k]+=v
492 else:
493 scores[k]=v
494 self.save_scores(scores)
495 def send_scores(self, serv, destinataire):
496 scores=self.get_scores()
497 scores=scores.items()
498 scores.sort(lambda x,y:cmp(x[1],y[1]))
499 scores.reverse()
500 serv.privmsg(destinataire,"Scores by score : "+" ; ".join(["%s %s"%(k,v) for (k,v) in scores]) )
501 scores.sort(lambda x,y:cmp(x[0].lower(),y[0].lower()))
502 serv.privmsg(destinataire,"Scores by pseudo : "+" ; ".join(["%s %s"%(k,v) for (k,v) in scores]) )
503
504 def gagne(self, serv, canal, bonus=None, bonusvalue=2):
505 serv.privmsg(canal,"Bravo !")
506 realword = self.reveal_word(serv, canal)
507 nlettre=float(len(realword.replace("'","").replace("-","")))
508 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()]
509 contribs_score={pseudo:int(10*contrib/nlettre) for pseudo,contrib in self.play_status[canal][2].items()}
510 self.add_score(contribs_score)
511 serv.privmsg(canal,"Contributions : %s"%(" ".join(contribs)) )
512 self.play_status[canal]=[None,None,None]
513
514 def reveal_word(self, serv, canal):
515 realword="".join([lettre[0] for lettre in self.play_status[canal][0]])
516 serv.privmsg(canal, "C'était %s." % (realword))
517 definition = self.play_status[canal][1]
518 serv.privmsg(canal,definition)
519 return realword
520
521 def perd(self, serv, canal):
522 serv.privmsg(canal,"Pendu !")
523 self.reveal_word(serv, canal)
524 self.play_status[canal]=[None,None,None]
525
526 def reload(self, auteur=None):
527 reload(config)
528 if auteur in [None, "SIGHUP"]:
529 towrite = "Config reloaded" + " (SIGHUP received)"*(auteur == "SIGHUP")
530 for to in config.report_bugs_to:
531 self.serv.privmsg(to, towrite)
532 log(self.serveur, towrite)
533 else:
534 self.serv.privmsg(auteur,"Config reloaded")
535
536 def start_as_daemon(self, outfile):
537 sys.stderr = Logger(outfile)
538 self.start()
539
540
541 class Logger(object):
542 """Pour écrire ailleurs que sur stdout"""
543 def __init__(self, filename="hung.full.log"):
544 self.filename = filename
545
546 def write(self, message):
547 f = open(self.filename, "a")
548 f.write(message)
549 f.close()
550
551
552 if __name__=="__main__":
553 import sys
554 if len(sys.argv)==1:
555 print "Usage : hung.py <serveur> [--debug] [--no-output] [--daemon [--pidfile]] [--outfile]"
556 print " --outfile sans --no-output ni --daemon n'a aucun effet"
557 exit(1)
558 serveur=sys.argv[1]
559 if "--daemon" in sys.argv:
560 thisfile = os.path.realpath(__file__)
561 thisdirectory = thisfile.rsplit("/", 1)[0]
562 os.chdir(thisdirectory)
563 daemon = True
564 else:
565 daemon = False
566 if "debug" in sys.argv or "--debug" in sys.argv:
567 debug=True
568 else:
569 debug=False
570 if "--no-output" in sys.argv or "--daemon" in sys.argv:
571 outfile = "/var/log/bots/hung.full.log"
572 for arg in sys.argv:
573 arg = arg.split("=")
574 if arg[0].strip('-') in ["out", "outfile", "logfile"]:
575 outfile = arg[1]
576 sys.stdout = Logger(outfile)
577 serveurs={"a♡":"acoeur.crans.org","acoeur":"acoeur.crans.org","acoeur.crans.org":"acoeur.crans.org",
578 "irc":"irc.crans.org","crans":"irc.crans.org","irc.crans.org":"irc.crans.org",
579 "localhost":"localhost"}
580 try:
581 serveur=serveurs[serveur]
582 except KeyError:
583 print "Server Unknown : %s"%(serveur)
584 exit(404)
585 hung=Hung(serveur,debug)
586 # Si on reçoit un SIGHUP, on reload la config
587 def sighup_handler(signum, frame):
588 hung.reload("SIGHUP")
589 signal.signal(signal.SIGHUP, sighup_handler)
590 if daemon:
591 child_pid = os.fork()
592 if child_pid == 0:
593 os.setsid()
594 hung.start_as_daemon(outfile)
595 else:
596 # on enregistre le pid de hung
597 pidfile = "/var/run/bots/hung.pid"
598 for arg in sys.argv:
599 arg = arg.split("=")
600 if arg[0].strip('-') in ["pidfile"]:
601 pidfile = arg[1]
602 f = open(pidfile, "w")
603 f.write("%s\n" % child_pid)
604 f.close()
605 else:
606 hung.start()
607