]>
gitweb.pimeys.fr Git - bots/deconnaisseur.git/blob - deconnaisseur.py
4 # Codé par 20-100 le 23/04/12
6 # Un bot IRC qui sort des déconnaissances
16 from remplace_accents
import remplace_accents
18 # Oui, j'ai recodé ma version d'irclib pour pouvoir rattrapper les SIGHUP
19 sys
.path
.insert(0, "/home/vincent/scripts/python-myirclib")
26 def get_config_played_file(serveur
):
27 serveurs
={"acoeur.crans.org":"acoeur","irc.crans.org":"crans"}
28 return config
.played_file_template
%(serveurs
[serveur
])
30 def get_config_logfile(serveur
):
31 serveurs
={"acoeur.crans.org":"acoeur","irc.crans.org":"crans"}
32 return config
.logfile_template
%(serveurs
[serveur
])
34 class UnicodeBotError(Exception):
36 def bot_unicode(chain
):
39 except UnicodeDecodeError:
42 def log(serveur
,channel
,auteur
=None,message
=None):
43 f
=open(get_config_logfile(serveur
),"a")
44 if auteur
==message
==None:
45 # alors c'est que c'est pas un channel mais juste une ligne de log
46 chain
="%s %s"%(time
.strftime("%F %T"),channel
)
48 chain
="%s [%s:%s] %s"%(time
.strftime("%F %T"),channel
,auteur
,message
)
50 if config
.debug_stdout
:
54 def ignore_event(serv
, ev
):
55 """Retourne ``True`` si il faut ignorer cet évènement."""
56 for (blackmask
, exceptmask
) in config
.blacklisted_masks
:
57 usermask
= ev
.source()
58 if exceptmask
is None:
61 exceptit
= bool(irclib
.mask_matches(usermask
, exceptmask
))
62 blackit
= bool(irclib
.mask_matches(usermask
, blackmask
))
63 if blackit
and not exceptit
:
66 def reussi(message
,answer
,answer_regexp
,auteur
):
67 if auteur
in config
.level3
:
68 return answer
in message
69 if auteur
in config
.level2
:
70 return remplace_accents(answer
) in message
72 if re
.match(".*" + remplace_accents(answer_regexp
).lower(),remplace_accents(message
).lower()):
75 def is_something(chain
,matches
,avant
=u
".*(?:^| )",apres
=u
"(?:$|\.| |,|;).*",case_sensitive
=False,debug
=False):
77 chain
=unicode(chain
,"utf8")
79 chain
=unicode(chain
,"utf8").lower()
80 allmatches
="("+"|".join(matches
)+")"
81 reg
=(avant
+allmatches
+apres
).lower()
86 return is_something(chain
,config
.tag_triggers
)
88 class RefuseError(Exception):
91 class Deconnaisseur(ircbot
.SingleServerIRCBot
):
92 def __init__(self
,serveur
,debug
=False):
93 temporary_pseudo
=config
.pseudo
+str(random
.randrange(10000,100000))
94 ircbot
.SingleServerIRCBot
.__init
__(self
, [(serveur
, 6667)],
95 temporary_pseudo
,"Un bot irc.[flagellez 20-100, il le mérite]", 10)
98 self
.overops
=config
.overops
99 self
.ops
=self
.overops
+config
.ops
100 self
.chanlist
=config
.chanlist
101 self
.stay_channels
=config
.stay_channels
102 self
.play_channels
=config
.play_channels
103 self
.play_status
={i
:[0] for i
in self
.play_channels
}
104 self
.last_activity
={}
105 self
.quiet_channels
=[]
107 def give_me_my_pseudo(self
,serv
):
108 serv
.privmsg("NickServ","RECOVER %s %s"%(config
.pseudo
,config
.password
))
109 serv
.privmsg("NickServ","RELEASE %s %s"%(config
.pseudo
,config
.password
))
111 serv
.nick(config
.pseudo
)
113 def on_welcome(self
, serv
, ev
):
114 self
.serv
=serv
# ça serv ira :)
115 self
.give_me_my_pseudo(serv
)
116 serv
.privmsg("NickServ","identify %s"%(config
.password
))
117 log(self
.serveur
,"Connected")
119 self
.chanlist
=["#bot"]
120 self
.play_channels
=["#bot"]
121 for c
in self
.chanlist
:
122 log(self
.serveur
,"JOIN %s"%(c))
124 self
.update_activity(c
,force
=True)
125 for c
in self
.play_channels
:
126 token
=time
.time()-3600
127 self
.play_status
[c
]=[0,token
]
128 serv
.execute_delayed(random
.randrange(config
.ttrig
),self
.start_enigme
,(serv
,c
,token
))
130 def start_enigme(self
,serv
,channel
,token
=None):
131 # On reste silencieux si lechan n'est pas actif
132 if not self
.is_active(channel
):
133 serv
.execute_delayed(config
.ttrig
*5,self
.start_enigme
,(serv
,channel
,token
))
135 if self
.play_status
[channel
][0]==0 and channel
in self
.play_channels
:
137 if token
==self
.play_status
[channel
][-1]:
140 if time
.time() > self
.play_status
[channel
][-1]+config
.time_incompressible
:
145 enigme
,indice
,answer_reg
,answer
=self
.get_enigme()
146 log(self
.serveur
,channel
,u
"$Énigme$".encode("utf8"),("%s; %s; %s; %s"%(enigme
, indice
, answer_reg
, answer
)).encode("utf8"))
147 serv
.privmsg(channel
,enigme
.encode("utf8"))
149 self
.play_status
[channel
]=[1,enigme
,indice
,answer_reg
,answer
,token
]
150 serv
.execute_delayed(random
.randrange(config
.ttrig
*3,config
.ttrig
*5),self
.give_indice
,(serv
,channel
,token
))
153 def give_indice(self
,serv
,channel
,token
):
154 if self
.play_status
[channel
][0]==1:
156 # c'est donc que l'indice a été demandé
157 if self
.play_status
[channel
][-1]+config
.time_incompressible_clue
<time
.time():
158 token
=self
.play_status
[channel
][-1]
159 if self
.play_status
[channel
][-1]==token
:
160 indice
=self
.play_status
[channel
][2]
161 serv
.privmsg(channel
,"indice : %s"%(indice).encode("utf8"))
162 self
.play_status
[channel
][0]=2
163 serv
.execute_delayed(random
.randrange(config
.ttrig
*1,config
.ttrig
*3),self
.give_answer
,(serv
,channel
,token
))
164 def give_answer(self
,serv
,channel
,token
):
165 if self
.play_status
[channel
][0]==2 and self
.play_status
[channel
][-1]==token
:
166 answer
=self
.play_status
[channel
][4]
167 serv
.privmsg(channel
,"C'était : %s"%(answer).encode("utf8"))
169 self
.play_status
[channel
]=[0,token
]
170 serv
.execute_delayed(random
.randrange(config
.Ttrig
*5,config
.Ttrig
*10),self
.start_enigme
,(serv
,channel
,token
))
172 def get_enigme(self
):
173 # on récupère les déconnaissances
174 f
=open(config
.source_file
)
177 l
=re
.findall("%\n(.*)\n(.*)\n(.*)\n(.*)\n(.*)\n",t
)
178 dec
={int(i
[0]):list(i
[1:]) for i
in l
if len(i
)==5}
179 # on va chercher combien de fois elles ont été jouées
180 played_file
=get_config_played_file(self
.serveur
)
184 l
=re
.findall("(.*):(.*)",t
)
185 played
={int(i
[0]):int(i
[1]) for i
in l
}
186 # on récupère le nombre d'occurrences le plus faible
187 mini
=min(played
.values())
188 # on choisit un id dans ceux qui ont ce nombre d'occurences
189 id_choisi
=random
.choice([k
for k
,v
in played
.items() if v
==mini
])
190 enigme
,indice
,answer_reg
,answer
=dec
[id_choisi
]
191 # on incrémente la choisie
193 # on enregistre le played_file
194 f
=open(played_file
,"w")
195 f
.write("\n".join(["%-3s : %s"%(k
,v
) for k
,v
in played
.items()]))
197 return enigme
.decode("utf8"),indice
.decode("utf8"),answer_reg
.decode("utf8"),answer
.decode("utf8")
199 def pourmoi(self
, serv
, message
):
202 if message
[:size
]==pseudo
and len(message
)>size
and message
[size
]==":":
203 return (True,message
[size
+1:].strip(" "))
205 return (False,message
)
207 def on_privmsg(self
, serv
, ev
):
208 if ignore_event(serv
, ev
):
210 message
=ev
.arguments()[0]
211 auteur
= irclib
.nm_to_n(ev
.source())
213 test
=bot_unicode(message
)
214 except UnicodeBotError
:
215 if config
.utf8_trigger
:
216 serv
.privmsg(auteur
, random
.choice(config
.utf8_fail_answers
).encode("utf8"))
218 message
=message
.split()
219 cmd
=message
[0].lower()
222 helpmsg_default
="""Liste des commandes :
223 HELP Affiche ce message d'aide
224 SCORE Affiche ton score (SCORE TRANSFERT <pseudo> [<n>] pour transférer des points)
225 SCORES Affiche les scores"""
227 JOIN Faire rejoindre un channel (sans paramètres, donne la liste des chans actuels)
228 LEAVE Faire quitter un channel
229 PLAY Passe un channel en mode "jouer"
230 NOPLAY Passe un channel en mode "ne pas jouer"
231 QUIET Se taire sur un channel
232 NOQUIET Opposé de QUIET
233 RELOAD Recharge la config"""
235 SCORES {DEL|ADD|SUB} Tu veux un dessin ?
236 SAY Fais envoyer un message sur un chan ou à une personne
237 STAY Ignorera les prochains LEAVE pour un chan
238 NOSTAY Opposé de STAY
239 STATUS Montre l'état courant
241 helpmsg
=helpmsg_default
242 if auteur
in self
.ops
:
244 if auteur
in self
.overops
:
245 helpmsg
+=helpmsg_overops
246 for ligne
in helpmsg
.split("\n"):
247 serv
.privmsg(auteur
,ligne
)
249 if auteur
in self
.ops
:
251 if message
[1] in self
.chanlist
:
252 serv
.privmsg(auteur
,"Je suis déjà sur %s"%(message
[1]))
254 serv
.join(message
[1])
255 self
.chanlist
.append(message
[1])
256 self
.update_activity(message
[1],force
=True)
257 serv
.privmsg(auteur
,"Channels : "+" ".join(self
.chanlist
))
258 log(self
.serveur
,"priv",auteur
," ".join(message
))
260 serv
.privmsg(auteur
,"Channels : "+" ".join(self
.chanlist
))
264 if auteur
in self
.ops
and len(message
)>1:
265 if message
[1] in self
.chanlist
:
266 if not (message
[1] in self
.stay_channels
) or auteur
in self
.overops
:
267 self
.quitter(message
[1]," ".join(message
[2:]))
268 self
.chanlist
.remove(message
[1])
269 log(self
.serveur
,"priv",auteur
," ".join(message
)+"[successful]")
271 serv
.privmsg(auteur
,"Non, je reste !")
272 log(self
.serveur
,"priv",auteur
," ".join(message
)+"[failed]")
274 serv
.privmsg(auteur
,"Je ne suis pas sur %s"%(message
[1]))
278 if auteur
in self
.overops
:
280 if message
[1] in self
.stay_channels
:
281 serv
.privmsg(auteur
,"Je stay déjà sur %s."%(message
[1]))
282 log(self
.serveur
,"priv",auteur
," ".join(message
)+"[failed]")
284 self
.stay_channels
.append(message
[1])
285 serv
.privmsg(auteur
,"Stay channels : "+" ".join(self
.stay_channels
))
286 log(self
.serveur
,"priv",auteur
," ".join(message
)+"[successful]")
288 serv
.privmsg(auteur
,"Stay channels : "+" ".join(self
.stay_channels
))
292 if auteur
in self
.overops
:
294 if message
[1] in self
.stay_channels
:
295 self
.stay_channels
.remove(message
[1])
296 serv
.privmsg(auteur
,"Stay channels : "+" ".join(self
.stay_channels
))
297 log(self
.serveur
,"priv",auteur
," ".join(message
)+"[successful]")
299 serv
.privmsg(auteur
,"Je ne stay pas sur %s."%(message
[1]))
300 log(self
.serveur
,"priv",auteur
," ".join(message
)+"[failed]")
304 if auteur
in self
.ops
:
306 if message
[1] in self
.play_channels
:
307 serv
.privmsg(auteur
,"Je play déjà sur %s."%(message
[1]))
308 log(self
.serveur
,"priv",auteur
," ".join(message
)+"[failed]")
310 self
.play_channels
.append(message
[1])
311 self
.play_status
[message
[1]]=[0,time
.time()-3600]
312 serv
.privmsg(auteur
,"Play channels : "+" ".join(self
.play_channels
))
313 log(self
.serveur
,"priv",auteur
," ".join(message
)+"[successful]")
315 serv
.privmsg(auteur
,"Play channels : "+" ".join(self
.play_channels
))
319 if auteur
in self
.ops
:
321 if message
[1] in self
.play_channels
:
322 self
.play_channels
.remove(message
[1])
323 serv
.privmsg(auteur
,"Play channels : "+" ".join(self
.play_channels
))
324 log(self
.serveur
,"priv",auteur
," ".join(message
)+"[successful]")
326 serv
.privmsg(auteur
,"Je ne play pas sur %s."%(message
[1]))
327 log(self
.serveur
,"priv",auteur
," ".join(message
)+"[failed]")
331 if auteur
in self
.ops
:
333 if message
[1] in self
.quiet_channels
:
334 serv
.privmsg(auteur
,"Je me la ferme déjà sur %s"%(message
[1]))
335 log(self
.serveur
,"priv",auteur
," ".join(message
)+"[failed]")
337 self
.quiet_channels
.append(message
[1])
338 serv
.privmsg(auteur
,"Quiet channels : "+" ".join(self
.quiet_channels
))
339 log(self
.serveur
,"priv",auteur
," ".join(message
)+"[successful]")
341 serv
.privmsg(auteur
,"Quiet channels : "+" ".join(self
.quiet_channels
))
345 if auteur
in self
.ops
:
347 if message
[1] in self
.quiet_channels
:
348 self
.quiet_channels
.remove(message
[1])
349 serv
.privmsg(auteur
,"Quiet channels : "+" ".join(self
.quiet_channels
))
350 log(self
.serveur
,"priv",auteur
," ".join(message
)+"[successful]")
352 serv
.privmsg(auteur
,"Je ne me la ferme pas sur %s."%(message
[1]))
353 log(self
.serveur
,"priv",auteur
," ".join(message
)+"[failed]")
357 if auteur
in self
.ops
:
359 log(self
.serveur
,"priv",auteur
," ".join(message
)+"[successful]")
362 elif cmd
in ["states","status"]:
363 if auteur
in self
.overops
:
364 for k
in self
.play_status
.keys():
365 serv
.privmsg(auteur
,(u
"%s : %s"%(k
,"; ".join([unicode(i
) for i
in self
.play_status
[k
]]))).encode("utf8") )
367 if auteur
in self
.overops
and len(message
)>2:
368 serv
.privmsg(message
[1]," ".join(message
[2:]))
369 log(self
.serveur
,"priv",auteur
," ".join(message
))
370 elif len(message
)<=2:
371 serv
.privmsg(auteur
,"Syntaxe : SAY <channel> <message>")
375 if auteur
in self
.overops
:
376 log(self
.serveur
,"priv",auteur
," ".join(message
)+"[successful]")
380 if len(message
) in [3,4] and message
[1].lower()=="transfert":
381 scores
=self
.get_scores()
382 de
,to
=auteur
,message
[2]
383 value
=scores
.get(de
,0)
386 asked
=int(message
[3])
388 serv
.privmsg(auteur
,"Syntaxe : SCORE TRANSFERT <pseudo> [<n>]")
393 serv
.privmsg(auteur
,"Vous n'avez pas de points")
396 serv
.privmsg(auteur
,"Bien tenté…")
399 serv
.privmsg(auteur
,"Vous n'avez que %s points"%(value))
402 self
.add_score(de
,-asked
)
403 self
.add_score(to
,asked
)
404 serv
.privmsg(auteur
,"Transfert de %s points de %s à %s"%(asked
,de
,to
))
406 serv
.privmsg(auteur
,"Syntaxe : SCORE TRANSFERT <pseudo> [<n>]")
408 serv
.privmsg(auteur
,"Votre score : %s"%(self
.get_scores().get(auteur
,0)) )
411 scores
=self
.get_scores().items()
413 scores
.sort(lambda x
,y
:cmp(x
[1],y
[1]))
415 serv
.privmsg(auteur
,"Scores by score : "+" ; ".join(["%s %s"%(i
[0],i
[1]) for i
in scores
]))
417 scores
.sort(lambda x
,y
:cmp(x
[0].lower(),y
[0].lower()))
418 serv
.privmsg(auteur
,"Scores by pseudo : "+" ; ".join(["%s %s"%(i
[0],i
[1]) for i
in scores
]))
419 elif auteur
in self
.overops
:
420 souscmd
=message
[1].lower()
424 scores
=self
.get_scores()
425 if scores
.has_key(todelete
):
427 self
.save_scores(scores
)
428 serv
.privmsg(auteur
,"Score de %s supprimé"%(todelete))
430 serv
.privmsg(auteur
,"Ce score n'existe pas : %s"%(todelete))
432 serv
.privmsg(auteur
,"Syntaxe : SCORES DEL <pseudo>")
433 elif souscmd
in ["add","sub"]:
435 toadd
,val
=message
[2],message
[3]
439 serv
.privmsg(auteur
,"Syntaxe : SCORES {ADD|SUB} <pseudo> <n>")
443 self
.add_score(toadd
,val
)
444 serv
.privmsg(auteur
,"Done")
446 serv
.privmsg(auteur
,"Syntaxe : SCORES {ADD|SUB} <pseudo> <n>")
448 serv
.privmsg(auteur
,"Syntaxe : SCORES {DEL|ADD|SUB} <pseudo> [<n>]")
454 serv
.privmsg(auteur
,"Je n'ai pas compris. Essaye HELP…")
456 def on_pubmsg(self
, serv
, ev
):
457 if ignore_event(serv
, ev
):
459 auteur
= irclib
.nm_to_n(ev
.source())
461 message
= ev
.arguments()[0]
462 self
.update_activity(canal
,auteur
,message
)
464 test
=bot_unicode(message
)
465 except UnicodeBotError
:
466 if config
.utf8_trigger
and not canal
in self
.quiet_channels
:
467 serv
.privmsg(canal
, (u
"%s: %s"%(auteur
,random
.choice(config
.utf8_fail_answers
))).encode("utf8"))
470 pour_moi
,message
=self
.pourmoi(serv
,message
)
471 if pour_moi
and message
.split()!=[]:
472 cmd
=message
.split()[0].lower()
474 args
=" ".join(message
.split()[1:])
477 if cmd
in ["meurs","die","crève"]:
478 if auteur
in self
.overops
:
480 log(self
.serveur
,canal
,auteur
,message
+"[successful]")
482 serv
.privmsg(canal
,"%s: crève !"%(auteur))
483 log(self
.serveur
,canal
,auteur
,message
+"[failed]")
484 elif cmd
in ["meur", "meurt","meurre","meurres"] and not canal
in self
.quiet_channels
:
485 serv
.privmsg(canal
,'%s: Mourir, impératif, 2ème personne du singulier : "meurs" (de rien)'%(auteur))
486 elif cmd
== "reload":
487 if auteur
in self
.ops
:
488 log(self
.serveur
, canal
, auteur
, message
+"[successful]")
490 elif cmd
in ["part","leave","dégage"]:
491 if auteur
in self
.ops
and (not (canal
in self
.stay_channels
)
492 or auteur
in self
.overops
):
494 log(self
.serveur
,canal
,auteur
,message
+"[successful]")
495 self
.chanlist
.remove(canal
)
497 serv
.privmsg(canal
,"%s: Non, je reste !"%(auteur))
498 log(self
.serveur
,canal
,auteur
,message
+"[failed]")
500 elif cmd
in ["deviens","pseudo"]:
501 if auteur
in self
.ops
:
504 log(self
.serveur
,canal
,auteur
,message
+"[successful]")
505 elif cmd
in ["coucou"] and not canal
in self
.quiet_channels
:
506 serv
.privmsg(canal
,"%s: coucou"%(auteur))
507 elif cmd
in ["ping"] and not canal
in self
.quiet_channels
:
508 serv
.privmsg(canal
,"%s: pong"%(auteur))
509 elif cmd
in ["déconnaissance","deconnaissance","énigme","enigme","encore","aco","moo","moo !","moo !"]:
510 if canal
in self
.play_channels
:
511 if self
.play_status
.get(canal
,[-1])[0]==0:
513 self
.start_enigme(serv
,canal
)
515 serv
.privmsg(canal
,"%s: Je peux souffler une minute ?"%(auteur))
517 serv
.privmsg(canal
,("%s: Rappel : %s"%(auteur
,self
.play_status
[canal
][1])).encode("utf8") )
519 serv
.privmsg(canal
,"%s: pas ici…"%(auteur))
520 elif cmd
in ["score","!score"]:
521 serv
.privmsg(auteur
,"Votre score : %s"%(self
.get_scores().get(auteur
,0)) )
522 elif cmd
in ["scores","!scores"]:
523 scores
=self
.get_scores().items()
525 scores
.sort(lambda x
,y
:cmp(x
[1],y
[1]))
527 serv
.privmsg(auteur
,"Scores by score : "+" ; ".join(["%s %s"%(i
[0],i
[1]) for i
in scores
]))
529 scores
.sort(lambda x
,y
:cmp(x
[0].lower(),y
[0].lower()))
530 serv
.privmsg(auteur
,"Scores by pseudo : "+" ; ".join(["%s %s"%(i
[0],i
[1]) for i
in scores
]))
531 elif cmd
=="indice" and canal
in self
.play_channels
:
532 self
.give_indice(serv
,canal
,None)
533 elif is_tag(message
) and not canal
in self
.quiet_channels
:
534 if auteur
in self
.ops
:
535 action
=random
.choice(config
.tag_actions
)
536 serv
.action(canal
,action
.encode("utf8"))
537 self
.quiet_channels
.append(canal
)
539 answer
=random
.choice(config
.tag_answers
)
540 for ligne
in answer
.split("\n"):
541 serv
.privmsg(canal
,"%s: %s"%(auteur
,ligne
.encode("utf8")))
542 elif "Bâille, cru aile ou orld" in message
:
543 self
.mourir(u
"Un de mes easters eggs (non en fait j'en ai qu'un) a été découvert par %s !"%auteur
)
549 if self
.play_status
.get(canal
,[-1])[0] in [1,2]:
550 answer_regexp
=self
.play_status
[canal
][3]
551 answer
=self
.play_status
[canal
][4]
552 if reussi(message
.decode("utf8"),answer
,answer_regexp
,auteur
):
553 serv
.privmsg(canal
,(u
"%s: bravo ! (C'était %s)"%(auteur
,answer
)).encode("utf8"))
554 log(self
.serveur
,canal
,auteur
+"$win",message
)
555 self
.add_score(auteur
,1)
557 self
.play_status
[canal
]=[0,token
]
558 serv
.execute_delayed(random
.randrange(config
.Ttrig
*5,config
.Ttrig
*10),self
.start_enigme
,(serv
,canal
,token
))
560 def on_kick(self
,serv
,ev
):
561 auteur
= irclib
.nm_to_n(ev
.source())
562 channel
= ev
.target()
563 victime
= ev
.arguments()[0]
564 raison
= ev
.arguments()[1]
565 if victime
==self
.nick
:
566 log(self
.serveur
,"%s kické de %s par %s (raison : %s)" %(victime
,channel
,auteur
,raison
))
569 self
.update_activity(channel
,force
=True)
570 # on ne dit rien au rejoin
571 #l1,l2=config.kick_answers,config.kick_actions
572 #n1,n2=len(l1),len(l2)
573 #i=random.randrange(n1+n2)
575 # serv.action(channel,l2[i-n1].format(auteur).encode("utf8"))
577 # serv.privmsg(channel,l1[i].format(auteur).encode("utf8"))
579 def quitter(self
,chan
,leave_message
=None):
580 if leave_message
==None:
581 leave_message
=random
.choice(config
.leave_messages
)
582 self
.serv
.part(chan
,message
=leave_message
.encode("utf8"))
584 def mourir(self
,quit_message
=None):
585 if quit_message
==None:
586 quit_message
=random
.choice(config
.quit_messages
)
587 self
.die(msg
=quit_message
.encode("utf8"))
589 def get_scores(self
):
590 f
=open(config
.score_file
)
591 scores
=pickle
.load(f
)
595 def add_score(self
,pseudo
,value
):
596 scores
=self
.get_scores()
597 if scores
.has_key(pseudo
):
598 scores
[pseudo
]+=value
601 self
.save_scores(scores
)
603 def save_scores(self
,scores
):
604 f
=open(config
.score_file
,"w")
605 pickle
.dump(scores
,f
)
609 return self
.serv
.get_nickname()
610 nick
= property(_getnick
)
612 def update_activity(self
,canal
="",pseudo
="",message
="",force
=False):
613 if force
or (not pseudo
in config
.idle_bots
and all([not re
.match(ignore
, message
) for ignore
in config
.idle_messages
])):
614 self
.last_activity
[canal
]=time
.time()
615 def is_active(self
,canal
):
616 return time
.time()-self
.last_activity
[canal
]<config
.idle_time
618 def reload(self
, auteur
=None):
620 if auteur
in [None, "SIGHUP"]:
621 towrite
= "Config reloaded" + " (SIGHUP received)"*(auteur
== "SIGHUP")
622 for to
in config
.report_bugs_to
:
623 self
.serv
.privmsg(to
, towrite
)
624 log(self
.serveur
, towrite
)
626 self
.serv
.privmsg(auteur
,"Config reloaded")
628 def start_as_daemon(self
, outfile
):
629 sys
.stderr
= Logger(outfile
)
633 class Logger(object):
634 """Pour écrire ailleurs que sur stdout"""
635 def __init__(self
, filename
="deconnaisseur.full.log"):
636 self
.filename
= filename
638 def write(self
, message
):
639 f
= open(self
.filename
, "a")
644 if __name__
=="__main__":
647 print "Usage : deconnaisseur.py <serveur> [--debug] [--no-output] [--daemon [--pidfile]] [--outfile]"
648 print " --outfile sans --no-output ni --daemon n'a aucun effet"
651 if "--daemon" in sys
.argv
:
652 thisfile
= os
.path
.realpath(__file__
)
653 thisdirectory
= thisfile
.rsplit("/", 1)[0]
654 os
.chdir(thisdirectory
)
658 if "debug" in sys
.argv
or "--debug" in sys
.argv
:
662 serveurs
={"a♡":"acoeur.crans.org","acoeur":"acoeur.crans.org","acoeur.crans.org":"acoeur.crans.org",
663 "irc":"irc.crans.org","crans":"irc.crans.org","irc.crans.org":"irc.crans.org"}
664 if "--no-output" in sys
.argv
or "--daemon" in sys
.argv
:
665 outfile
= "/var/log/bots/deconnaisseur.full.log"
668 if arg
[0].strip('-') in ["out", "outfile", "logfile"]:
670 sys
.stdout
= Logger(outfile
)
672 serveur
=serveurs
[serveur
]
674 print "Server Unknown : %s"%(serveur)
676 deconnaisseur
=Deconnaisseur(serveur
,debug
)
677 # Si on reçoit un SIGHUP, on reload la config
678 def sighup_handler(signum
, frame
):
679 deconnaisseur
.reload("SIGHUP")
680 signal
.signal(signal
.SIGHUP
, sighup_handler
)
682 child_pid
= os
.fork()
685 deconnaisseur
.start_as_daemon(outfile
)
687 # on enregistre le pid de deconnaisseur
688 pidfile
= "/var/run/bots/deconnaisseur.pid"
691 if arg
[0].strip('-') in ["pidfile"]:
693 f
= open(pidfile
, "w")
694 f
.write("%s\n" % child_pid
)
697 deconnaisseur
.start()