]> gitweb.pimeys.fr Git - bots/hung.git/blob - hung.py
2e0355bbd4287891a8c661e5a88069491a818068
[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 if len(message) > 2:
198 self.start_partie(serv, message[1], " ".join(message[2:]))
199 else:
200 serv.privmsg(auteur,"Je play déjà sur %s."%(message[1]))
201 log(self.serveur,"priv",auteur," ".join(message)+"[failed]")
202 else:
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]")
207 else:
208 serv.privmsg(auteur,"Play channels : "+" ".join(self.play_channels))
209 else:
210 notunderstood=True
211 elif cmd=="noplay":
212 if auteur in self.ops:
213 if len(message)>1:
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]")
218 else:
219 serv.privmsg(auteur,"Je ne play pas sur %s."%(message[1]))
220 log(self.serveur,"priv",auteur," ".join(message)+"[failed]")
221 else:
222 notunderstood=True
223 elif cmd=="stay":
224 if auteur in self.overops:
225 if len(message)>1:
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]))
229 else:
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))
233 else:
234 serv.privmsg(auteur,"Stay channels : "+" ".join(self.stay_channels))
235 else:
236 notunderstood=True
237 elif cmd=="nostay":
238 if auteur in self.overops:
239 if len(message)>1:
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))
244 else:
245 log(self.serveur,"priv",auteur," ".join(message)+"[failed]")
246 serv.privmsg(auteur,"Je ne stay pas sur %s."%(message[1]))
247
248 else:
249 notunderstood=True
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")
255 else:
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]))
258 elif cmd=="die":
259 if auteur in self.overops:
260 log(self.serveur,"priv",auteur," ".join(message)+"[successful]")
261 self.mourir()
262 else:
263 notunderstood=True
264 elif cmd=="quiet":
265 if auteur in self.ops:
266 if len(message)>1:
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]")
270 else:
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]")
274 else:
275 serv.privmsg(auteur,"Quiet channels : "+" ".join(self.quiet_channels))
276 else:
277 notunderstood=True
278 elif cmd=="noquiet":
279 if auteur in self.ops:
280 if len(message)>1:
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]")
285 else:
286 serv.privmsg(auteur,"Je ne me la ferme pas sur %s."%(message[1]))
287 log(self.serveur,"priv",auteur," ".join(message)+"[failed]")
288 else:
289 notunderstood=True
290 elif cmd=="reload":
291 if auteur in self.ops:
292 self.reload(auteur)
293 log(self.serveur,"priv",auteur," ".join(message)+"[successful]")
294 else:
295 notunderstood=True
296 elif cmd=="say":
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>")
302 else:
303 notunderstood=True
304 elif cmd=="do":
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>")
310 else:
311 notunderstood=True
312 elif cmd in ["score","scores"]:
313 self.send_scores(serv,auteur)
314 else:
315 notunderstood=True
316 if notunderstood:
317 serv.privmsg(auteur,"Je n'ai pas compris. Essaye HELP…")
318
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))
324
325 def start_partie(self, serv, canal, mot=None):
326 if mot is 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]
331 else:
332 definition = "(custom word)"
333 # ' et - sont considérés comme déjà devinés
334 mot = mot.upper()
335 mot = [(lettre,lettre in config.non_guess_chars) for lettre in list(mot)]
336 self.play_status[canal]=[mot,definition,{}]
337 self.tried_letters[canal] = set ()
338 self.lives[canal] = config.lives
339 self.affiche_mot(serv, canal, begin="Devinez")
340
341 def on_pubmsg(self, serv, ev):
342 auteur = irclib.nm_to_n(ev.source())
343 canal = ev.target()
344 message = ev.arguments()[0]
345 try:
346 test=bot_unicode(message)
347 except UnicodeBotError:
348 if config.utf8_trigger and not canal in self.quiet_channels:
349 serv.privmsg(canal, (u"%s: %s"%(auteur,random.choice(config.utf8_fail_answers))).encode("utf8"))
350 return
351 pour_moi,message=self.pourmoi(serv,message)
352 if pour_moi and message.split()!=[]:
353 cmd=message.split()[0].lower()
354 try:
355 args=" ".join(message.split()[1:])
356 except:
357 args=""
358 if cmd in ["meurs","die","crève"]:
359 if auteur in self.overops:
360 log(self.serveur,canal,auteur,message+"[successful]")
361 self.mourir()
362 else:
363 serv.privmsg(canal,"%s: crève !"%(auteur))
364 log(self.serveur,canal,auteur,message+"[failed]")
365 elif cmd == "reload":
366 if auteur in self.ops:
367 log(self.serveur, canal, auteur, message+"[successful]")
368 self.reload(canal)
369 elif cmd in ["part","leave","dégage"]:
370 if auteur in self.ops and (not (canal in self.stay_channels)
371 or auteur in self.overops):
372 self.quitter(canal)
373 log(self.serveur,canal,auteur,message+"[successful]")
374 if canal in self.chanlist:
375 self.chanlist.remove(canal)
376 else:
377 serv.privmsg(canal,"%s: Non, je reste !"%(auteur))
378 log(self.serveur,canal,auteur,message+"[failed]")
379 elif cmd in ["play","jeu","encore","again","partie","pendu","game","mot","go","allez"]:
380 if not canal in self.quiet_channels and canal in self.play_channels:
381 if self.play_status.has_key(canal):
382 if self.play_status[canal]==[None,None,None]:
383 self.start_partie(serv, canal)
384 else:
385 self.affiche_mot(serv, canal, begin="%s: Rappel"%(auteur))
386 else:
387 self.play_status[canal]=[None,None,None]
388 self.start_partie(serv, canal)
389 elif not canal in self.play_channels:
390 serv.privmsg(canal,"%s: pas ici…"%(auteur))
391 elif (cmd in list("azertyuiopqsdfghjklmwxcvbn") and canal in self.play_channels
392 and self.play_status.has_key(canal) and self.play_status[canal]!=[None,None,None]):
393 giv_let=cmd.upper()
394 liste=self.play_status[canal][0]
395 listeapres=[(lettre[0],lettre[1] or lettre[0]==giv_let) for lettre in liste]
396 if liste!=listeapres:
397 nbtrouvees=(sum([lettre[1] for lettre in listeapres if not lettre[0] in "'-()"])
398 - sum([lettre[1] for lettre in liste if not lettre[0] in "'-()"]))
399 if self.play_status[canal][2].has_key(auteur):
400 self.play_status[canal][2][auteur]+= nbtrouvees
401 else:
402 self.play_status[canal][2][auteur] = nbtrouvees
403 self.play_status[canal][0]=listeapres
404 self.affiche_mot(serv, canal, begin="%s placé"%(giv_let))
405 else:
406 if not giv_let in self.tried_letters[canal]:
407 # On perd une chance
408 self.lives[canal] -= 1
409 if self.lives[canal] > 0:
410 serv.privmsg(canal, "Pas de %s. Plus que %s chances…" % (giv_let, self.lives[canal]))
411 if self.lives[canal] == 0:
412 serv.privmsg(canal, "Pas de %s." % (giv_let))
413 self.perd(serv, canal)
414 return
415 self.tried_letters[canal].add(giv_let)
416 if all([lettre[1] for lettre in listeapres]):
417 self.gagne(serv, canal)
418
419 elif cmd in ["score","scores","!score","!scores"]:
420 self.send_scores(serv,auteur)
421 if cmd in ["meur", "meurt","meurre","meurres"] and not canal in self.quiet_channels:
422 serv.privmsg(canal,'%s: Mourir, impératif, 2ème personne du singulier : "meurs" (de rien)'%(auteur))
423 if is_tag(message) and not canal in self.quiet_channels:
424 if auteur in self.ops:
425 action=random.choice(config.tag_actions)
426 serv.action(canal,action.encode("utf8"))
427 self.quiet_channels.append(canal)
428 else:
429 answer=random.choice(config.tag_answers)
430 for ligne in answer.split("\n"):
431 serv.privmsg(canal,"%s: %s"%(auteur,ligne.encode("utf8")))
432 # on essaye de voir si le mot fourni matche la partie en cours
433 mot = cmd
434 if canal in self.play_channels and self.play_status[canal][0]!=None and is_mot(mot, self.play_status[canal][0]):
435 # on a trouvé le mot
436 # on regarde combien de lettre il manquait
437 manquait = sum([not lettre[1] for lettre in self.play_status[canal][0]])
438 self.add_score({auteur: manquait})
439 if self.play_status[canal][2].has_key(auteur):
440 self.play_status[canal][2][auteur]+=manquait
441 else:
442 self.play_status[canal][2][auteur]=manquait
443 self.gagne(serv, canal, bonus=auteur, bonusvalue=manquait)
444 else:
445 pass
446
447
448 def on_action(self, serv, ev):
449 action = ev.arguments()[0]
450 auteur = irclib.nm_to_n(ev.source())
451 channel = ev.target()
452
453
454 def on_kick(self,serv,ev):
455 auteur = irclib.nm_to_n(ev.source())
456 channel = ev.target()
457 victime = ev.arguments()[0]
458 raison = ev.arguments()[1]
459 if victime==self.nick:
460 log(self.serveur,"%s kické de %s par %s (raison : %s)" %(victime,channel,auteur,raison))
461 time.sleep(5)
462 serv.join(channel)
463 # on ne dit rien au rejoin
464 #l1,l2=config.kick_answers,config.kick_actions
465 #n1,n2=len(l1),len(l2)
466 #i=random.randrange(n1+n2)
467 #if i>=n1:
468 # serv.action(channel,l2[i-n1].format(auteur).encode("utf8"))
469 #else:
470 # serv.privmsg(channel,l1[i].format(auteur).encode("utf8"))
471
472 def _getnick(self):
473 return self.serv.get_nickname()
474 nick = property(_getnick)
475
476 def quitter(self,chan,leave_message=None):
477 if leave_message==None:
478 leave_message=random.choice(config.leave_messages)
479 self.serv.part(chan,message=leave_message.encode("utf8"))
480
481 def mourir(self):
482 quit_message=random.choice(config.quit_messages)
483 self.die(msg=quit_message.encode("utf8"))
484
485 def get_scores(self):
486 f=open(config.scores_file)
487 scores=pickle.load(f)
488 f.close()
489 return scores
490 def save_scores(self,scores):
491 f=open(config.scores_file,'w')
492 pickle.dump(scores,f)
493 f.close()
494 def add_score(self,dico):
495 scores=self.get_scores()
496 for k,v in dico.items():
497 if scores.has_key(k):
498 scores[k]+=v
499 else:
500 scores[k]=v
501 self.save_scores(scores)
502 def send_scores(self, serv, destinataire):
503 scores=self.get_scores()
504 scores=scores.items()
505 scores.sort(lambda x,y:cmp(x[1],y[1]))
506 scores.reverse()
507 serv.privmsg(destinataire,"Scores by score : "+" ; ".join(["%s %s"%(k,v) for (k,v) in scores]) )
508 scores.sort(lambda x,y:cmp(x[0].lower(),y[0].lower()))
509 serv.privmsg(destinataire,"Scores by pseudo : "+" ; ".join(["%s %s"%(k,v) for (k,v) in scores]) )
510
511 def gagne(self, serv, canal, bonus=None, bonusvalue=2):
512 serv.privmsg(canal,"Bravo !")
513 realword = self.reveal_word(serv, canal)
514 nlettre=float(len(realword.replace("'","").replace("-","")))
515 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()]
516 contribs_score={pseudo:int(10*contrib/nlettre) for pseudo,contrib in self.play_status[canal][2].items()}
517 self.add_score(contribs_score)
518 serv.privmsg(canal,"Contributions : %s"%(" ".join(contribs)) )
519 self.play_status[canal]=[None,None,None]
520
521 def reveal_word(self, serv, canal):
522 realword="".join([lettre[0] for lettre in self.play_status[canal][0]])
523 serv.privmsg(canal, "C'était %s." % (realword))
524 definition = self.play_status[canal][1]
525 serv.privmsg(canal,definition)
526 return realword
527
528 def perd(self, serv, canal):
529 serv.privmsg(canal,"Pendu !")
530 self.reveal_word(serv, canal)
531 self.play_status[canal]=[None,None,None]
532
533 def reload(self, auteur=None):
534 reload(config)
535 if auteur in [None, "SIGHUP"]:
536 towrite = "Config reloaded" + " (SIGHUP received)"*(auteur == "SIGHUP")
537 for to in config.report_bugs_to:
538 self.serv.privmsg(to, towrite)
539 log(self.serveur, towrite)
540 else:
541 self.serv.privmsg(auteur,"Config reloaded")
542
543 def start_as_daemon(self, outfile):
544 sys.stderr = Logger(outfile)
545 self.start()
546
547
548 class Logger(object):
549 """Pour écrire ailleurs que sur stdout"""
550 def __init__(self, filename="hung.full.log"):
551 self.filename = filename
552
553 def write(self, message):
554 f = open(self.filename, "a")
555 f.write(message)
556 f.close()
557
558
559 if __name__=="__main__":
560 import sys
561 if len(sys.argv)==1:
562 print "Usage : hung.py <serveur> [--debug] [--no-output] [--daemon [--pidfile]] [--outfile]"
563 print " --outfile sans --no-output ni --daemon n'a aucun effet"
564 exit(1)
565 serveur=sys.argv[1]
566 if "--daemon" in sys.argv:
567 thisfile = os.path.realpath(__file__)
568 thisdirectory = thisfile.rsplit("/", 1)[0]
569 os.chdir(thisdirectory)
570 daemon = True
571 else:
572 daemon = False
573 if "debug" in sys.argv or "--debug" in sys.argv:
574 debug=True
575 else:
576 debug=False
577 if "--no-output" in sys.argv or "--daemon" in sys.argv:
578 outfile = "/var/log/bots/hung.full.log"
579 for arg in sys.argv:
580 arg = arg.split("=")
581 if arg[0].strip('-') in ["out", "outfile", "logfile"]:
582 outfile = arg[1]
583 sys.stdout = Logger(outfile)
584 serveurs={"a♡":"acoeur.crans.org","acoeur":"acoeur.crans.org","acoeur.crans.org":"acoeur.crans.org",
585 "irc":"irc.crans.org","crans":"irc.crans.org","irc.crans.org":"irc.crans.org",
586 "localhost":"localhost"}
587 try:
588 serveur=serveurs[serveur]
589 except KeyError:
590 print "Server Unknown : %s"%(serveur)
591 exit(404)
592 hung=Hung(serveur,debug)
593 # Si on reçoit un SIGHUP, on reload la config
594 def sighup_handler(signum, frame):
595 hung.reload("SIGHUP")
596 signal.signal(signal.SIGHUP, sighup_handler)
597 if daemon:
598 child_pid = os.fork()
599 if child_pid == 0:
600 os.setsid()
601 hung.start_as_daemon(outfile)
602 else:
603 # on enregistre le pid de hung
604 pidfile = "/var/run/bots/hung.pid"
605 for arg in sys.argv:
606 arg = arg.split("=")
607 if arg[0].strip('-') in ["pidfile"]:
608 pidfile = arg[1]
609 f = open(pidfile, "w")
610 f.write("%s\n" % child_pid)
611 f.close()
612 else:
613 hung.start()
614