]> gitweb.pimeys.fr Git - bots/hung.git/blob - hung.py
c022105f9db7894f4825e846fed7fe0fc31a2eab
[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 ["score","scores","!score","!scores"]:
392 self.send_scores(serv,auteur)
393 if cmd in ["meur", "meurt","meurre","meurres"] and not canal in self.quiet_channels:
394 serv.privmsg(canal,'%s: Mourir, impératif, 2ème personne du singulier : "meurs" (de rien)'%(auteur))
395 if is_tag(message) and not canal in self.quiet_channels:
396 if auteur in self.ops:
397 action=random.choice(config.tag_actions)
398 serv.action(canal,action.encode("utf8"))
399 self.quiet_channels.append(canal)
400 else:
401 answer=random.choice(config.tag_answers)
402 for ligne in answer.split("\n"):
403 serv.privmsg(canal,"%s: %s"%(auteur,ligne.encode("utf8")))
404 # on essaye de voir si le mot fourni matche la partie en cours
405 mot = message
406 if canal in self.play_channels and self.play_status[canal][0]!=None and is_mot(mot, self.play_status[canal][0]):
407 # on a trouvé le mot
408 # on regarde combien de lettre il manquait
409 manquait = sum([not lettre[1] for lettre in self.play_status[canal][0]])
410 self.add_score({auteur: manquait})
411 if self.play_status[canal][2].has_key(auteur):
412 self.play_status[canal][2][auteur]+=manquait
413 else:
414 self.play_status[canal][2][auteur]=manquait
415 self.gagne(serv, canal, bonus=auteur, bonusvalue=manquait)
416 return
417 elif (cmd in list("azertyuiopqsdfghjklmwxcvbn") and canal in self.play_channels
418 and self.play_status.has_key(canal) and self.play_status[canal]!=[None,None,None]):
419 giv_let=cmd.upper()
420 liste=self.play_status[canal][0]
421 listeapres=[(lettre[0],lettre[1] or lettre[0]==giv_let) for lettre in liste]
422 if liste!=listeapres:
423 nbtrouvees=(sum([lettre[1] for lettre in listeapres if not lettre[0] in "'-()"])
424 - sum([lettre[1] for lettre in liste if not lettre[0] in "'-()"]))
425 if self.play_status[canal][2].has_key(auteur):
426 self.play_status[canal][2][auteur]+= nbtrouvees
427 else:
428 self.play_status[canal][2][auteur] = nbtrouvees
429 self.play_status[canal][0]=listeapres
430 self.affiche_mot(serv, canal, begin="%s placé"%(giv_let))
431 else:
432 if not giv_let in self.tried_letters[canal]:
433 # On perd une chance
434 self.lives[canal] -= 1
435 if self.lives[canal] > 0:
436 serv.privmsg(canal, "Pas de %s. Plus que %s chances…" % (giv_let, self.lives[canal]))
437 if self.lives[canal] == 0:
438 serv.privmsg(canal, "Pas de %s." % (giv_let))
439 self.perd(serv, canal)
440 return
441 self.tried_letters[canal].add(giv_let)
442 if all([lettre[1] for lettre in listeapres]):
443 self.gagne(serv, canal)
444
445 else:
446 pass
447
448
449 def on_action(self, serv, ev):
450 action = ev.arguments()[0]
451 auteur = irclib.nm_to_n(ev.source())
452 channel = ev.target()
453
454
455 def on_kick(self,serv,ev):
456 auteur = irclib.nm_to_n(ev.source())
457 channel = ev.target()
458 victime = ev.arguments()[0]
459 raison = ev.arguments()[1]
460 if victime==self.nick:
461 log(self.serveur,"%s kické de %s par %s (raison : %s)" %(victime,channel,auteur,raison))
462 time.sleep(5)
463 serv.join(channel)
464 # on ne dit rien au rejoin
465 #l1,l2=config.kick_answers,config.kick_actions
466 #n1,n2=len(l1),len(l2)
467 #i=random.randrange(n1+n2)
468 #if i>=n1:
469 # serv.action(channel,l2[i-n1].format(auteur).encode("utf8"))
470 #else:
471 # serv.privmsg(channel,l1[i].format(auteur).encode("utf8"))
472
473 def _getnick(self):
474 return self.serv.get_nickname()
475 nick = property(_getnick)
476
477 def quitter(self,chan,leave_message=None):
478 if leave_message==None:
479 leave_message=random.choice(config.leave_messages)
480 self.serv.part(chan,message=leave_message.encode("utf8"))
481
482 def mourir(self):
483 quit_message=random.choice(config.quit_messages)
484 self.die(msg=quit_message.encode("utf8"))
485
486 def get_scores(self):
487 f=open(config.scores_file)
488 scores=pickle.load(f)
489 f.close()
490 return scores
491 def save_scores(self,scores):
492 f=open(config.scores_file,'w')
493 pickle.dump(scores,f)
494 f.close()
495 def add_score(self,dico):
496 scores=self.get_scores()
497 for k,v in dico.items():
498 if scores.has_key(k):
499 scores[k]+=v
500 else:
501 scores[k]=v
502 self.save_scores(scores)
503 def send_scores(self, serv, destinataire):
504 scores=self.get_scores()
505 scores=scores.items()
506 scores.sort(lambda x,y:cmp(x[1],y[1]))
507 scores.reverse()
508 serv.privmsg(destinataire,"Scores by score : "+" ; ".join(["%s %s"%(k,v) for (k,v) in scores]) )
509 scores.sort(lambda x,y:cmp(x[0].lower(),y[0].lower()))
510 serv.privmsg(destinataire,"Scores by pseudo : "+" ; ".join(["%s %s"%(k,v) for (k,v) in scores]) )
511
512 def gagne(self, serv, canal, bonus=None, bonusvalue=2):
513 serv.privmsg(canal,"Bravo !")
514 realword = self.reveal_word(serv, canal)
515 nlettre=float(len([l for l in realword if not l in config.non_guess_chars]))
516 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()]
517 contribs_score={pseudo:int(10*contrib/nlettre) for pseudo,contrib in self.play_status[canal][2].items()}
518 self.add_score(contribs_score)
519 serv.privmsg(canal,"Contributions : %s"%(" ".join(contribs)) )
520 self.play_status[canal]=[None,None,None]
521
522 def reveal_word(self, serv, canal):
523 realword="".join([lettre[0] for lettre in self.play_status[canal][0]])
524 serv.privmsg(canal, "C'était %s." % (realword))
525 definition = self.play_status[canal][1]
526 serv.privmsg(canal,definition)
527 return realword
528
529 def perd(self, serv, canal):
530 serv.privmsg(canal,"Pendu !")
531 self.reveal_word(serv, canal)
532 self.play_status[canal]=[None,None,None]
533
534 def reload(self, auteur=None):
535 reload(config)
536 if auteur in [None, "SIGHUP"]:
537 towrite = "Config reloaded" + " (SIGHUP received)"*(auteur == "SIGHUP")
538 for to in config.report_bugs_to:
539 self.serv.privmsg(to, towrite)
540 log(self.serveur, towrite)
541 else:
542 self.serv.privmsg(auteur,"Config reloaded")
543
544 def start_as_daemon(self, outfile):
545 sys.stderr = Logger(outfile)
546 self.start()
547
548
549 class Logger(object):
550 """Pour écrire ailleurs que sur stdout"""
551 def __init__(self, filename="hung.full.log"):
552 self.filename = filename
553
554 def write(self, message):
555 f = open(self.filename, "a")
556 f.write(message)
557 f.close()
558
559
560 if __name__=="__main__":
561 import sys
562 if len(sys.argv)==1:
563 print "Usage : hung.py <serveur> [--debug] [--no-output] [--daemon [--pidfile]] [--outfile]"
564 print " --outfile sans --no-output ni --daemon n'a aucun effet"
565 exit(1)
566 serveur=sys.argv[1]
567 if "--daemon" in sys.argv:
568 thisfile = os.path.realpath(__file__)
569 thisdirectory = thisfile.rsplit("/", 1)[0]
570 os.chdir(thisdirectory)
571 daemon = True
572 else:
573 daemon = False
574 if "debug" in sys.argv or "--debug" in sys.argv:
575 debug=True
576 else:
577 debug=False
578 if "--no-output" in sys.argv or "--daemon" in sys.argv:
579 outfile = "/var/log/bots/hung.full.log"
580 for arg in sys.argv:
581 arg = arg.split("=")
582 if arg[0].strip('-') in ["out", "outfile", "logfile"]:
583 outfile = arg[1]
584 sys.stdout = Logger(outfile)
585 serveurs={"a♡":"acoeur.crans.org","acoeur":"acoeur.crans.org","acoeur.crans.org":"acoeur.crans.org",
586 "irc":"irc.crans.org","crans":"irc.crans.org","irc.crans.org":"irc.crans.org",
587 "localhost":"localhost"}
588 try:
589 serveur=serveurs[serveur]
590 except KeyError:
591 print "Server Unknown : %s"%(serveur)
592 exit(404)
593 hung=Hung(serveur,debug)
594 # Si on reçoit un SIGHUP, on reload la config
595 def sighup_handler(signum, frame):
596 hung.reload("SIGHUP")
597 signal.signal(signal.SIGHUP, sighup_handler)
598 if daemon:
599 child_pid = os.fork()
600 if child_pid == 0:
601 os.setsid()
602 hung.start_as_daemon(outfile)
603 else:
604 # on enregistre le pid de hung
605 pidfile = "/var/run/bots/hung.pid"
606 for arg in sys.argv:
607 arg = arg.split("=")
608 if arg[0].strip('-') in ["pidfile"]:
609 pidfile = arg[1]
610 f = open(pidfile, "w")
611 f.write("%s\n" % child_pid)
612 f.close()
613 else:
614 hung.start()
615