]>
gitweb.pimeys.fr Git - bots/saturnin.git/blob - saturnin.py
e1ac570c15eeb3a4444da702cc7abbfdc5fd535f
2 # -*- encoding: utf-8 -*-
6 # Un bot IRC pour remplacer le canard.
7 # parce que le canard, c'est le bien et que braice ne pong pas
12 import socket
, ssl
, json
18 from commands
import getstatusoutput
as ex
20 # Oui, j'ai recodé ma version d'irclib pour pouvoir rattrapper les SIGHUP
21 sys
.path
.insert(0, "/home/vincent/scripts/python-myirclib")
25 # on récupère la config
30 def get_config_logfile(serveur
):
31 serveurs
={"acoeur.crans.org":"acoeur","irc.crans.org":"crans"}
32 return config
.logfile_template
%(serveurs
[serveur
])
34 def log(serveur
,channel
,auteur
=None,message
=None):
35 f
=open(get_config_logfile(serveur
),"a")
36 if auteur
==message
==None:
37 # alors c'est que c'est pas un channel mais juste une ligne de log
38 chain
="%s %s"%(time
.strftime("%F %T"),channel
)
40 chain
="%s [%s:%s] %s"%(time
.strftime("%F %T"),channel
,auteur
,message
)
42 if config
.debug_stdout
:
46 def is_something(chain
,matches
,avant
=u
".*(?:^| )",apres
=u
"(?:$|\.| |,|;).*",case_sensitive
=False,debug
=False):
48 chain
=unicode(chain
,"utf8")
50 chain
=unicode(chain
,"utf8").lower()
51 allmatches
="("+"|".join(matches
)+")"
52 reg
=(avant
+allmatches
+apres
).lower()
56 regexp_pan
= re
.compile(u
".*(" + "|".join(config
.killwords
) + u
").*")
58 return regexp_pan
.match(unicode(chain
,"utf8").lower())
60 def ignore_event(serv
, ev
):
61 """Retourne ``True`` si il faut ignorer cet évènement."""
62 for (blackmask
, exceptmask
) in config
.blacklisted_masks
:
63 usermask
= ev
.source()
64 if exceptmask
is None:
67 exceptit
= bool(irclib
.mask_matches(usermask
, exceptmask
))
68 blackit
= bool(irclib
.mask_matches(usermask
, blackmask
))
69 if blackit
and not exceptit
:
72 class UnicodeBotError(Exception):
74 def bot_unicode(chain
):
77 except UnicodeDecodeError as exc
:
80 class Saturnin(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
,"Coin ? ©braice [mais 'faut frapper 20-100]", 10)
87 self
.overops
=config
.overops
88 self
.ops
=self
.overops
+config
.ops
89 self
.chanlist
=config
.chanlist
90 self
.stay_channels
=config
.stay_channels
91 self
.quiet_channels
=config
.quiet_channels
92 self
.play_channels
=config
.play_channels
93 self
.status
= { chan
: [0, None] for chan
in self
.play_channels
}
94 # 0 : pas de spawn prévu
96 # avec en deuxième paramètre le timestamp du moment où il a été déclenché (pas du moment où il se fera)
100 def give_me_my_pseudo(self
,serv
):
101 serv
.privmsg("NickServ","RECOVER %s %s"%(config
.irc_pseudo
,config
.irc_password
))
102 serv
.privmsg("NickServ","RELEASE %s %s"%(config
.irc_pseudo
,config
.irc_password
))
104 serv
.nick(config
.irc_pseudo
)
106 def on_welcome(self
, serv
, ev
):
107 self
.serv
=serv
# ça serv ira :)
108 self
.give_me_my_pseudo(serv
)
109 serv
.privmsg("NickServ","IDENTIFY %s"%(config
.irc_password
))
110 log(self
.serveur
,"Connected")
112 self
.chanlist
= self
.play_channels
= ["#bot"]
113 self
.status
= { chan
: [0, 0] for chan
in self
.play_channels
}
114 for c
in self
.chanlist
:
115 log(self
.serveur
,"JOIN %s"%(c))
117 if c
in self
.play_channels
:
118 spawn_delay
= random
.randrange(*config
.spawn_delays
)
119 self
.spawn(c
, time
.time(), spawn_delay
)
121 def pourmoi(self
, serv
, message
):
122 """renvoie (False,lemessage) ou (True, le message amputé de "pseudo: ")"""
125 if message
[:size
]==pseudo
and len(message
)>size
and message
[size
]==":":
126 return (True,message
[size
+1:].lstrip(" "))
128 return (False,message
)
130 def on_privmsg(self
, serv
, ev
):
131 if ignore_event(serv
, ev
):
133 message
=ev
.arguments()[0]
134 auteur
= irclib
.nm_to_n(ev
.source())
136 test
=bot_unicode(message
)
137 except UnicodeBotError
:
138 if config
.utf8_trigger
:
139 serv
.privmsg(auteur
, random
.choice(config
.utf8_fail_answers
).encode("utf8"))
141 message
=message
.split()
142 cmd
=message
[0].lower()
145 helpdico
={"help":["""HELP <commande>
146 Affiche de l'aide sur la commande""",None,None],
148 Affiche votre score""", None, None],
150 Afficher tous les scores""", None, None],
151 "join": [None, """JOIN <channel>
152 Me fait rejoindre le channel""",None],
153 "leave": [None,"""LEAVE <channel>
154 Me fait quitter le channel (sauf s'il est dans ma stay_list).""",None],
155 "quiet": [None,"""QUIET <channel>
156 Me rend silencieux sur le channel.""",None],
157 "noquiet": [None,"""NOQUIET <channel>
158 Me rend la parole sur le channel.""",None],
159 "play": [None, """PLAY
160 Passe un channel en mode "jouer" """,None],
161 "noplay": [None, """NOPLAY
162 Passe un channel en mode "ne pas jouer" """,None],
163 "SPAWN": [None, """SPAWN <channel>
164 Me fait spawner sur le channel.""",None],
165 "reload": [None,"""RELOAD
166 Recharge la configuration.""",None],
167 "say": [None,None,"""SAY <channel> <message>
168 Me fait parler sur le channel."""],
169 "do": [None,None,"""DO <channel> <action>
170 Me fait faitre une action (/me) sur le channel."""],
171 "stay": [None,None,"""STAY <channel>
172 Ajoute le channel à ma stay_list."""],
173 "nostay": [None,None,"""NOSTAY <channel>
174 Retire le channel de ma stay_list."""],
175 "ops": [None,None,"""OPS
176 Affiche la liste des ops."""],
177 "overops": [None,None,"""OVEROPS
178 Affiche la liste des overops."""],
179 "kick": [None,None,"""KICK <channel> <pseudo> [<raison>]
180 Kicke <pseudo> du channel (Il faut bien entendu que j'y sois op)."""],
181 "die": [None,None,"""DIE
182 Me déconnecte du serveur IRC."""]
184 helpmsg_default
="Liste des commandes disponibles :\nHELP SCORE SCORES"
185 helpmsg_ops
=" JOIN LEAVE QUIET NOQUIET PLAY NOPLAY SPAWN"
186 helpmsg_overops
=" SAY DO STAY NOSTAY OPS OVEROPS KICK DIE"
187 op
,overop
=auteur
in self
.ops
, auteur
in self
.overops
189 helpmsg
=helpmsg_default
193 helpmsg
+=helpmsg_overops
195 helpmsgs
=helpdico
.get(message
[1].lower(),["Commande inconnue.",None,None])
197 if op
and helpmsgs
[1]:
199 helpmsg
+="\n"+helpmsgs
[1]
202 if overop
and helpmsgs
[2]:
204 helpmsg
+="\n"+helpmsgs
[2]
207 if not helpmsg
: # Un non-op a demandé de l'aide sur une commande dont il n'est pas censé connaître l'existence
208 helpmsg
= "Commande inacessible."
209 for ligne
in helpmsg
.split("\n"):
210 serv
.privmsg(auteur
,ligne
)
212 if auteur
in self
.ops
:
214 if message
[1] in self
.chanlist
:
215 serv
.privmsg(auteur
,"Je suis déjà sur %s"%(message
[1]))
217 serv
.join(message
[1])
218 self
.chanlist
.append(message
[1])
219 serv
.privmsg(auteur
,"Channels : "+" ".join(self
.chanlist
))
220 log(self
.serveur
,"priv",auteur
," ".join(message
))
222 serv
.privmsg(auteur
,"Channels : "+" ".join(self
.chanlist
))
226 if auteur
in self
.ops
and len(message
)>1:
227 if message
[1] in self
.chanlist
:
228 if not (message
[1] in self
.stay_channels
) or auteur
in self
.overops
:
229 self
.quitter(message
[1]," ".join(message
[2:]))
230 self
.chanlist
.remove(message
[1])
231 log(self
.serveur
,"priv",auteur
," ".join(message
)+"[successful]")
233 serv
.privmsg(auteur
,"Non, je reste !")
234 log(self
.serveur
,"priv",auteur
," ".join(message
)+"[failed]")
236 serv
.privmsg(auteur
,"Je ne suis pas sur %s"%(message
[1]))
240 if auteur
in self
.overops
:
242 if message
[1] in self
.stay_channels
:
243 log(self
.serveur
,"priv",auteur
," ".join(message
)+"[failed]")
244 serv
.privmsg(auteur
,"Je stay déjà sur %s."%(message
[1]))
246 log(self
.serveur
,"priv",auteur
," ".join(message
)+"[successful]")
247 self
.stay_channels
.append(message
[1])
248 serv
.privmsg(auteur
,"Stay channels : "+" ".join(self
.stay_channels
))
250 serv
.privmsg(auteur
,"Stay channels : "+" ".join(self
.stay_channels
))
254 if auteur
in self
.overops
:
256 if message
[1] in self
.stay_channels
:
257 log(self
.serveur
,"priv",auteur
," ".join(message
)+"[successful]")
258 self
.stay_channels
.remove(message
[1])
259 serv
.privmsg(auteur
,"Stay channels : "+" ".join(self
.stay_channels
))
261 log(self
.serveur
,"priv",auteur
," ".join(message
)+"[failed]")
262 serv
.privmsg(auteur
,"Je ne stay pas sur %s."%(message
[1]))
267 if auteur
in self
.overops
:
268 log(self
.serveur
,"priv",auteur
," ".join(message
)+"[successful]")
273 if auteur
in self
.ops
:
275 if message
[1] in self
.quiet_channels
:
276 serv
.privmsg(auteur
,"Je me la ferme déjà sur %s"%(message
[1]))
277 log(self
.serveur
,"priv",auteur
," ".join(message
)+"[failed]")
279 self
.quiet_channels
.append(message
[1])
280 serv
.privmsg(auteur
,"Quiet channels : "+" ".join(self
.quiet_channels
))
281 log(self
.serveur
,"priv",auteur
," ".join(message
)+"[successful]")
283 serv
.privmsg(auteur
,"Quiet channels : "+" ".join(self
.quiet_channels
))
287 if auteur
in self
.ops
:
289 if message
[1] in self
.quiet_channels
:
290 self
.quiet_channels
.remove(message
[1])
291 serv
.privmsg(auteur
,"Quiet channels : "+" ".join(self
.quiet_channels
))
292 log(self
.serveur
,"priv",auteur
," ".join(message
)+"[successful]")
294 serv
.privmsg(auteur
,"Je ne me la ferme pas sur %s."%(message
[1]))
295 log(self
.serveur
,"priv",auteur
," ".join(message
)+"[failed]")
299 if auteur
in self
.ops
:
301 if message
[1] in self
.play_channels
:
302 serv
.privmsg(auteur
,"Je play déjà sur %s."%(message
[1]))
303 log(self
.serveur
,"priv",auteur
," ".join(message
)+"[failed]")
305 self
.play_channels
.append(message
[1])
306 self
.spawn(message
[1], 1)
307 serv
.privmsg(auteur
,"Play channels : "+" ".join(self
.play_channels
))
308 log(self
.serveur
,"priv",auteur
," ".join(message
)+"[successful]")
310 serv
.privmsg(auteur
,"Play channels : "+" ".join(self
.play_channels
))
314 if auteur
in self
.ops
:
316 if message
[1] in self
.play_channels
:
317 self
.play_channels
.remove(message
[1])
318 serv
.privmsg(auteur
,"Play channels : "+" ".join(self
.play_channels
))
319 log(self
.serveur
,"priv",auteur
," ".join(message
)+"[successful]")
321 serv
.privmsg(auteur
,"Je ne play pas sur %s."%(message
[1]))
322 log(self
.serveur
,"priv",auteur
," ".join(message
)+"[failed]")
326 if auteur
in self
.ops
:
327 serv
.privmsg(auteur
,"Status : %s" % (self
.status
, ))
331 if auteur
in self
.ops
:
333 if message
[1] in self
.play_channels
:
334 # Le plus pratique pour pas s'embêter c'est de mettre un
335 # delay d'une seconde, comme ça .spawn() fait le boulot
336 self
.spawn(message
[1], time
.time(), 1)
338 serv
.privmsg(auteur
, "Je ne joue pas sur %s" % message
[1])
340 serv
.privmsg(auteur
, "Syntaxe : SPAWN <channel>")
344 if auteur
in self
.overops
and len(message
)>2:
345 serv
.privmsg(message
[1]," ".join(message
[2:]))
346 log(self
.serveur
,"priv",auteur
," ".join(message
))
347 elif len(message
)<=2:
348 serv
.privmsg(auteur
,"Syntaxe : SAY <channel> <message>")
352 if auteur
in self
.overops
and len(message
)>2:
353 serv
.action(message
[1]," ".join(message
[2:]))
354 log(self
.serveur
,"priv",auteur
," ".join(message
))
355 elif len(message
)<=2:
356 serv
.privmsg(auteur
,"Syntaxe : DO <channel> <action>")
360 if auteur
in self
.overops
and len(message
)>2:
361 serv
.kick(message
[1],message
[2]," ".join(message
[3:]))
362 log(self
.serveur
,"priv",auteur
," ".join(message
))
363 elif len(message
)<=2:
364 serv
.privmsg(auteur
,"Syntaxe : KICK <channel> <pseudo> [<raison>]")
368 if auteur
in self
.overops
:
369 serv
.privmsg(auteur
," ".join(self
.ops
))
373 if auteur
in self
.overops
:
374 serv
.privmsg(auteur
," ".join(self
.overops
))
378 if auteur
in self
.ops
:
380 log(self
.serveur
,"priv",auteur
," ".join(message
)+"[successful]")
385 if len(message
) in [3,4] and message
[1].lower()=="transfert":
386 scores
=self
.get_scores()
387 de
,to
=auteur
,message
[2]
388 value
=scores
.get(de
,0)
391 asked
=int(message
[3])
393 serv
.privmsg(auteur
,"Syntaxe : SCORE TRANSFERT <pseudo> [<n>]")
398 serv
.privmsg(auteur
,"Vous n'avez pas de points")
401 serv
.privmsg(auteur
,"Bien tenté…")
404 serv
.privmsg(auteur
,"Vous n'avez que %s points"%(value))
407 self
.add_score(de
,-asked
)
408 self
.add_score(to
,asked
)
409 serv
.privmsg(auteur
,"Transfert de %s points de %s à %s"%(asked
,de
,to
))
410 elif len(message
) == 2:
411 scores
= self
.get_scores()
414 serv
.privmsg(auteur
, "Score de %s : %s" % (asked
, scores
[asked
]))
416 serv
.privmsg(auteur
, "%s n'a encore jamais joué (avec succès)." % (asked
,))
418 serv
.privmsg(auteur
,"Syntaxe : SCORE TRANSFERT <pseudo> [<n>]")
420 self
.sendscore(auteur
)
423 self
.sendscores(auteur
)
424 elif auteur
in self
.overops
:
425 souscmd
=message
[1].lower()
429 scores
=self
.get_scores()
430 if scores
.has_key(todelete
):
432 self
.save_scores(scores
)
433 serv
.privmsg(auteur
,"Score de %s supprimé"%(todelete))
435 serv
.privmsg(auteur
,"Ce score n'existe pas : %s"%(todelete))
437 serv
.privmsg(auteur
,"Syntaxe : SCORES DEL <pseudo>")
438 elif souscmd
in ["add","sub"]:
440 toadd
,val
=message
[2],message
[3]
444 serv
.privmsg(auteur
,"Syntaxe : SCORES {ADD|SUB} <pseudo> <n>")
448 self
.add_score(toadd
,val
)
449 serv
.privmsg(auteur
,"Done")
451 serv
.privmsg(auteur
,"Syntaxe : SCORES {ADD|SUB} <pseudo> <n>")
453 serv
.privmsg(auteur
,"Syntaxe : SCORES {DEL|ADD|SUB} <pseudo> [<n>]")
459 serv
.privmsg(auteur
,"Je n'ai pas compris. Essayez HELP…")
461 def sendscore(self
, to
):
462 self
.serv
.privmsg(to
, "Votre score : %s"%(self
.get_scores().get(to
,0)) )
464 def sendscores(self
, to
):
465 scores
=self
.get_scores().items()
467 scores
.sort(lambda x
,y
:cmp(x
[1],y
[1]))
469 self
.serv
.privmsg(to
, "Scores by score : "+" ; ".join(["%s %s"%(i
[0],i
[1]) for i
in scores
]))
471 scores
.sort(lambda x
,y
:cmp(x
[0].lower(),y
[0].lower()))
472 self
.serv
.privmsg(to
, "Scores by pseudo : "+" ; ".join(["%s %s"%(i
[0],i
[1]) for i
in scores
]))
474 def on_pubmsg(self
, serv
, ev
):
475 if ignore_event(serv
, ev
):
477 auteur
= irclib
.nm_to_n(ev
.source())
478 channel
= ev
.target()
479 message
= ev
.arguments()[0]
481 test
=bot_unicode(message
)
482 except UnicodeBotError
:
483 if config
.utf8_trigger
and not channel
in self
.quiet_channels
:
484 serv
.privmsg(channel
, (u
"%s: %s"%(auteur
,random
.choice(config
.utf8_fail_answers
))).encode("utf8"))
486 pour_moi
,message
=self
.pourmoi(serv
,message
)
487 if pour_moi
and message
.split()!=[]:
488 cmd
=message
.split()[0].lower()
490 args
=" ".join(message
.split()[1:])
493 if cmd
in ["meurs","die","crève"]:
494 if auteur
in self
.overops
:
495 log(self
.serveur
,channel
,auteur
,message
+"[successful]")
498 serv
.privmsg(channel
,("%s: %s"%(auteur
,random
.choice(config
.quit_fail_messages
))).encode("utf8"))
499 log(self
.serveur
,channel
,auteur
,message
+"[failed]")
500 elif cmd
== "reload":
501 if auteur
in self
.ops
:
502 log(self
.serveur
, channel
, auteur
, message
+"[successful]")
504 elif cmd
in ["part","leave","dégage","va-t-en","tut'tiresailleurs,c'estmesgalets"]:
505 if auteur
in self
.ops
and (not (channel
in self
.stay_channels
)
506 or auteur
in self
.overops
):
507 self
.quitter(channel
)
508 log(self
.serveur
,channel
,auteur
,message
+"[successful]")
509 if channel
in self
.chanlist
:
510 self
.chanlist
.remove(channel
)
512 serv
.privmsg(channel
,("%s: %s"%(auteur
,random
.choice(config
.leave_fail_messages
))).encode("utf8"))
513 log(self
.serveur
,channel
,auteur
,message
+"[failed]")
515 self
.sendscore(auteur
)
516 elif cmd
== "scores":
517 self
.sendscores(auteur
)
518 elif cmd
in [u
"deviens", u
"pseudo"]:
519 if auteur
in self
.ops
:
522 log(self
.serveur
, channel
, auteur
, message
+ "[successful]")
524 self
.shot(channel
, auteur
)
526 def on_action(self
, serv
, ev
):
527 if ignore_event(serv
, ev
):
529 action
= ev
.arguments()[0]
530 auteur
= irclib
.nm_to_n(ev
.source())
531 channel
= ev
.target()
533 #~ test=bot_unicode(action)
534 #~ except UnicodeBotError:
535 #~ if config.utf8_trigger and not channel in self.quiet_channels:
536 #~ serv.privmsg(channel, (u"%s: %s"%(auteur,random.choice(config.utf8_fail_answers))).encode("utf8"))
538 #~ mypseudo=self.nick
540 def on_kick(self
,serv
,ev
):
541 auteur
= irclib
.nm_to_n(ev
.source())
542 channel
= ev
.target()
543 victime
= ev
.arguments()[0]
544 raison
= ev
.arguments()[1]
545 if victime
==self
.nick
:
546 log(self
.serveur
,"%s kické de %s par %s (raison : %s)" %(victime
,channel
,auteur
,raison
))
549 #~ l1,l2=config.kick_answers,config.kick_actions
550 #~ n1,n2=len(l1),len(l2)
551 #~ i=random.randrange(n1+n2)
553 #~ serv.action(channel,l2[i-n1].format(auteur).encode("utf8"))
555 #~ serv.privmsg(channel,l1[i].format(auteur).encode("utf8"))
557 def spawn(self
, channel
, timestamp
, delay
=0):
558 if channel
in self
.play_channels
:
560 self
.serv
.execute_delayed(delay
, self
.spawn
, (channel
, timestamp
))
561 self
.status
[channel
] = [1, timestamp
]
563 # on teste le timestamp pour pas s'emmêler dans les spawn
564 infos
= self
.status
.get(channel
, [0,0])
565 if infos
== [1, timestamp
]:
566 spawn_sentence
= random
.choice(config
.canards
) + random
.choice(config
.spawn_sentences
)
567 self
.serv
.privmsg(channel
, spawn_sentence
.encode("utf8"))
568 self
.status
[channel
] = [2, timestamp
]
569 times_up_delay
= random
.randrange(*config
.times_up_delays
)
570 self
.serv
.execute_delayed(times_up_delay
, self
.too_slow
, (channel
, timestamp
))
572 def too_slow(self
, channel
, timestamp
):
573 infos
= self
.status
.get(channel
, [0,0])
574 if infos
== [2, timestamp
]:
575 self
.serv
.privmsg(channel
, random
.choice(config
.times_up_sentences
).encode("utf8"))
576 respawn_delay
= random
.randrange(*config
.spawn_delays
)
577 self
.spawn(channel
, time
.time(), respawn_delay
)
579 def shot(self
, channel
, auteur
):
580 if self
.status
.get(channel
, [0, 0])[0] == 2:
581 succeed
= random
.randrange(0,101) > config
.proba_miss
583 self
.serv
.privmsg(channel
, random
.choice(config
.killed_templates
).format(auteur
).encode("utf8"))
584 self
.add_score(auteur
, 1)
585 if random
.randrange(0, 101) < config
.proba_killed_sentence
:
586 self
.serv
.privmsg(channel
, random
.choice(config
.killed_sentences
).encode("utf8"))
587 respawn_delay
= random
.randrange(*config
.spawn_delays
)
588 self
.spawn(channel
, time
.time(), respawn_delay
)
590 self
.serv
.privmsg(channel
, random
.choice(config
.miss_templates
).format(auteur
).encode("utf8"))
591 if random
.randrange(0,101) < config
.proba_miss_sentence
:
592 self
.serv
.privmsg(channel
, random
.choice(config
.miss_sentences
).encode("utf8"))
594 def quitter(self
,chan
,leave_message
=None):
595 if leave_message
==None:
596 leave_message
=random
.choice(config
.leave_messages
)
597 self
.serv
.part(chan
,message
=leave_message
.encode("utf8"))
600 quit_message
=random
.choice(config
.quit_messages
)
601 self
.die(msg
=quit_message
.encode("utf8"))
603 def get_scores(self
):
604 f
=open(config
.score_file
)
605 scores
=pickle
.load(f
)
609 def add_score(self
, pseudo
, value
):
610 scores
=self
.get_scores()
611 if scores
.has_key(pseudo
):
612 scores
[pseudo
]+=value
615 self
.save_scores(scores
)
617 def save_scores(self
,scores
):
618 f
=open(config
.score_file
,"w")
619 pickle
.dump(scores
,f
)
623 return self
.serv
.get_nickname()
624 nick
=property(_getnick
)
626 def reload(self
, auteur
=None):
628 if auteur
in [None, "SIGHUP"]:
629 towrite
= "Config reloaded" + " (SIGHUP received)"*(auteur
== "SIGHUP")
630 for to
in config
.report_bugs_to
:
631 self
.serv
.privmsg(to
, towrite
)
632 log(self
.serveur
, towrite
)
634 self
.serv
.privmsg(auteur
,"Config reloaded")
636 def start_as_daemon(self
, outfile
):
637 sys
.stderr
= Logger(outfile
)
641 class Logger(object):
642 """Pour écrire ailleurs que sur stdout"""
643 def __init__(self
, filename
="saturnin.full.log"):
644 self
.filename
= filename
646 def write(self
, message
):
647 f
= open(self
.filename
, "a")
652 if __name__
=="__main__":
655 print "Usage : saturnin.py <serveur> [--debug] [--no-output] [--daemon [--pidfile]] [--outfile]"
656 print " --outfile sans --no-output ni --daemon n'a aucun effet"
659 if "--daemon" in sys
.argv
:
660 thisfile
= os
.path
.realpath(__file__
)
661 thisdirectory
= thisfile
.rsplit("/", 1)[0]
662 os
.chdir(thisdirectory
)
666 if "debug" in sys
.argv
or "--debug" in sys
.argv
:
670 if "--no-output" in sys
.argv
or "--daemon" in sys
.argv
:
671 outfile
= "/var/log/bots/saturnin.full.log"
674 if arg
[0].strip('-') in ["out", "outfile", "logfile"]:
676 sys
.stdout
= Logger(outfile
)
677 if "--quiet" in sys
.argv
:
678 config
.debug_stdout
=False
679 serveurs
={"a♡":"acoeur.crans.org","acoeur":"acoeur.crans.org","acoeur.crans.org":"acoeur.crans.org",
680 "irc":"irc.crans.org","crans":"irc.crans.org","irc.crans.org":"irc.crans.org",
683 serveur
=serveurs
[serveur
]
685 print "Server Unknown : %s"%(serveur)
687 saturnin
= Saturnin(serveur
,debug
)
688 # Si on reçoit un SIGHUP, on reload la config
689 def sighup_handler(signum
, frame
):
690 saturnin
.reload("SIGHUP")
691 signal
.signal(signal
.SIGHUP
, sighup_handler
)
693 child_pid
= os
.fork()
696 saturnin
.start_as_daemon(outfile
)
698 # on enregistre le pid de saturnin
699 pidfile
= "/var/run/bots/saturnin.pid"
702 if arg
[0].strip('-') in ["pidfile"]:
704 f
= open(pidfile
, "w")
705 f
.write("%s\n" % child_pid
)