2012-04-09 02:19:39 +00:00
# coding=utf-8
import re
2012-04-11 15:33:57 +00:00
import sys
2012-04-09 02:19:39 +00:00
from datetime import timedelta
from datetime import datetime
from datetime import date
2012-04-30 16:22:10 +00:00
import time
2012-05-14 15:50:11 +00:00
import threading
2012-04-09 02:19:39 +00:00
2012-06-20 14:24:19 +00:00
from module_state import ModuleState
2012-05-20 07:44:07 +00:00
2012-06-20 14:24:19 +00:00
nemubotversion = 3.0
2012-05-20 07:44:07 +00:00
2012-06-20 14:24:19 +00:00
def help_tiny ( ) :
""" Line inserted in the response to the command !help """
return " events manager "
def help_full ( ) :
return " This module store a lot of events: ny, we, vacs, " + ( " , " . join ( DATAS . index . keys ( ) ) ) + " \n !eventslist: gets list of timer \n !start /something/: launch a timer "
2012-05-14 15:50:11 +00:00
class Manager ( threading . Thread ) :
2012-06-20 14:24:19 +00:00
def __init__ ( self ) :
2012-05-14 15:50:11 +00:00
self . stop = False
threading . Thread . __init__ ( self )
2012-06-20 14:24:19 +00:00
def alertEnd ( self , evt ) :
global newStrendEvt , SRVS , DATAS
#Send the message on each matched servers
for server in SRVS . keys ( ) :
if not evt . hasAttribute ( " server " ) or server == evt [ " server " ] :
if evt [ " channel " ] == SRVS [ server ] . nick :
SRVS [ server ] . send_msg_usr ( evt [ " proprio " ] , " %s : %s arrivé à échéance. " % ( evt [ " proprio " ] , evt [ " name " ] ) )
else :
SRVS [ server ] . send_msg ( evt [ " channel " ] , " %s : %s arrivé à échéance. " % ( evt [ " proprio " ] , evt [ " name " ] ) )
DATAS . delChild ( DATAS . index [ evt [ " name " ] ] )
save ( )
newStrendEvt . set ( )
2012-05-14 15:50:11 +00:00
def run ( self ) :
2012-06-20 14:24:19 +00:00
global DATAS
2012-05-14 15:50:11 +00:00
while not self . stop :
newStrendEvt . clear ( )
closer = None
#Gets the closer event
2012-06-20 14:24:19 +00:00
for evt in DATAS . index . keys ( ) :
if DATAS . index [ evt ] . hasAttribute ( " end " ) and ( closer is None or DATAS . index [ evt ] . getDate ( " end " ) < closer . getDate ( " end " ) ) and DATAS . index [ evt ] . getDate ( " end " ) > datetime . now ( ) :
closer = DATAS . index [ evt ]
if closer is not None and closer . hasAttribute ( " end " ) :
#print ("Closer: %s à %s"%(closer.name, closer["end"]))
timeleft = ( closer . getDate ( " end " ) - datetime . now ( ) ) . seconds
timer = threading . Timer ( timeleft , self . alertEnd , ( closer , ) )
2012-05-14 15:50:11 +00:00
timer . start ( )
#print ("Start timer (%ds)"%timeleft)
newStrendEvt . wait ( )
2012-06-20 14:24:19 +00:00
if closer is not None and closer . hasAttribute ( " end " ) and closer . getDate ( " end " ) > datetime . now ( ) :
2012-05-14 15:50:11 +00:00
timer . cancel ( )
2012-06-20 14:24:19 +00:00
self . threadManager = None
2012-05-14 15:50:11 +00:00
2012-06-20 14:24:19 +00:00
threadManager = None
newStrendEvt = threading . Event ( )
2012-04-30 16:22:10 +00:00
2012-06-20 14:24:19 +00:00
def load ( ) :
global DATAS
#Define the index
DATAS . setIndex ( " name " )
#Load the manager
threadManager = Manager ( )
threadManager . start ( )
2012-05-20 07:44:07 +00:00
2012-06-20 14:24:19 +00:00
def close ( ) :
if self . threadManager is not None :
self . threadManager . stop = True
self . newStrendEvt . set ( )
2012-04-09 02:19:39 +00:00
def parseanswer ( msg ) :
2012-06-20 14:24:19 +00:00
global DATAS
2012-04-09 02:19:39 +00:00
if msg . cmd [ 0 ] == " we " or msg . cmd [ 0 ] == " week-end " or msg . cmd [ 0 ] == " weekend " :
ndate = datetime . today ( ) + timedelta ( 5 - datetime . today ( ) . weekday ( ) )
ndate = datetime ( ndate . year , ndate . month , ndate . day , 0 , 0 , 1 )
msg . send_chn (
msg . countdown_format ( ndate ,
2012-06-20 14:24:19 +00:00
" Il reste %s avant le week-end, courage ;) " ,
2012-04-09 02:19:39 +00:00
" Youhou, on est en week-end depuis %s . " ) )
return True
elif msg . cmd [ 0 ] == " new-year " or msg . cmd [ 0 ] == " newyear " or msg . cmd [ 0 ] == " ny " :
msg . send_chn (
msg . countdown_format ( datetime ( datetime . today ( ) . year + 1 , 1 , 1 , 0 , 0 , 1 ) ,
" Il reste %s avant la nouvelle année. " ,
" Nous faisons déjà la fête depuis %s ! " ) )
return True
elif msg . cmd [ 0 ] == " vacances " or msg . cmd [ 0 ] == " vacs " or msg . cmd [ 0 ] == " holiday " or msg . cmd [ 0 ] == " holidays " :
msg . send_chn (
msg . countdown_format ( datetime ( 2012 , 7 , 30 , 18 , 0 , 1 ) ,
" Il reste %s avant les vacances :) " ,
" Profitons, c ' est les vacances depuis %s . " ) )
return True
2012-04-30 16:22:10 +00:00
elif msg . cmd [ 0 ] == " start " and len ( msg . cmd ) > 1 :
2012-06-20 14:24:19 +00:00
if msg . cmd [ 1 ] not in DATAS :
strnd = ModuleState ( " strend " )
strnd [ " server " ] = msg . srv . id
strnd [ " channel " ] = msg . channel
strnd [ " proprio " ] = msg . sender
strnd [ " start " ] = datetime . now ( )
strnd [ " name " ] = msg . cmd [ 1 ]
DATAS . addChild ( strnd )
2012-05-14 15:50:11 +00:00
if len ( msg . cmd ) > 2 :
result = re . match ( " ([0-9]+)([smhdjSMHDJ])? " , msg . cmd [ 2 ] )
if result is not None :
try :
if result . group ( 2 ) is not None and ( result . group ( 2 ) == " m " or result . group ( 2 ) == " M " ) :
2012-06-20 14:24:19 +00:00
strnd [ " end " ] = datetime . now ( ) + timedelta ( minutes = int ( result . group ( 1 ) ) )
2012-05-14 15:50:11 +00:00
elif result . group ( 2 ) is not None and ( result . group ( 2 ) == " h " or result . group ( 2 ) == " H " ) :
2012-06-20 14:24:19 +00:00
strnd [ " end " ] = datetime . now ( ) + timedelta ( hours = int ( result . group ( 1 ) ) )
2012-05-14 15:50:11 +00:00
elif result . group ( 2 ) is not None and ( result . group ( 2 ) == " d " or result . group ( 2 ) == " D " or result . group ( 2 ) == " j " or result . group ( 2 ) == " J " ) :
2012-06-20 14:24:19 +00:00
strnd [ " end " ] = datetime . now ( ) + timedelta ( days = int ( result . group ( 1 ) ) )
2012-05-14 15:50:11 +00:00
else :
2012-06-20 14:24:19 +00:00
strnd [ " end " ] = datetime . now ( ) + timedelta ( seconds = int ( result . group ( 1 ) ) )
2012-05-14 15:50:11 +00:00
newStrendEvt . set ( )
2012-06-20 14:24:19 +00:00
msg . send_snd ( " %s commencé le %s et se terminera le %s . " % ( msg . cmd [ 1 ] , datetime . now ( ) , strnd . getDate ( " end " ) ) )
2012-05-14 15:50:11 +00:00
except :
msg . send_snd ( " Impossible de définir la fin de %s . " % ( msg . cmd [ 1 ] ) )
msg . send_snd ( " %s commencé le %s . " % ( msg . cmd [ 1 ] , datetime . now ( ) ) )
else :
msg . send_snd ( " %s commencé le %s " % ( msg . cmd [ 1 ] , datetime . now ( ) ) )
2012-06-20 14:24:19 +00:00
save ( )
2012-04-30 16:22:10 +00:00
else :
msg . send_snd ( " %s existe déjà. " % ( msg . cmd [ 1 ] ) )
2012-06-20 14:24:19 +00:00
return True
2012-05-14 15:50:11 +00:00
elif ( msg . cmd [ 0 ] == " end " or msg . cmd [ 0 ] == " forceend " ) and len ( msg . cmd ) > 1 :
2012-06-23 11:36:08 +00:00
if msg . cmd [ 1 ] in DATAS . index :
if DATAS . index [ msg . cmd [ 1 ] ] . hasAttribute ( " end " ) :
msg . send_chn ( " %s a duré %s . " % ( msg . cmd [ 1 ] , msg . just_countdown ( datetime . now ( ) - DATAS . index [ msg . cmd [ 1 ] ] . getDate ( " start " ) ) ) )
2012-06-20 14:24:19 +00:00
if DATAS . index [ msg . cmd [ 1 ] ] [ " proprio " ] == msg . sender or ( msg . cmd [ 0 ] == " forceend " and msg . sender == msg . srv . owner ) :
DATAS . delChild ( DATAS . index [ msg . cmd [ 1 ] ] )
2012-05-14 15:50:11 +00:00
newStrendEvt . set ( )
2012-06-20 14:24:19 +00:00
save ( )
2012-04-30 16:22:10 +00:00
else :
2012-06-20 14:24:19 +00:00
msg . send_snd ( " Vous ne pouvez pas terminer le compteur %s , créé par %s . " % ( msg . cmd [ 1 ] , DATAS . index [ msg . cmd [ 1 ] ] [ " proprio " ] ) )
2012-04-30 16:22:10 +00:00
else :
msg . send_snd ( " %s n ' est pas un compteur connu. " % ( msg . cmd [ 1 ] ) )
2012-06-20 14:24:19 +00:00
return True
2012-04-30 16:22:10 +00:00
elif msg . cmd [ 0 ] == " eventslist " or msg . cmd [ 0 ] == " eventlist " or msg . cmd [ 0 ] == " eventsliste " or msg . cmd [ 0 ] == " eventliste " :
2012-06-20 14:24:19 +00:00
msg . send_snd ( " Compteurs connus : %s . " % " , " . join ( DATAS . index . keys ( ) ) )
elif msg . cmd [ 0 ] in DATAS . index :
if DATAS . index [ msg . cmd [ 0 ] ] . name == " strend " :
msg . send_chn ( " %s commencé il y a %s . " % ( msg . cmd [ 0 ] , msg . just_countdown ( datetime . now ( ) - DATAS . index [ msg . cmd [ 0 ] ] . getDate ( " start " ) ) ) )
2012-04-09 02:19:39 +00:00
else :
2012-06-20 14:24:19 +00:00
msg . send_chn ( msg . countdown_format ( DATAS . index [ msg . cmd [ 0 ] ] . getDate ( " start " ) , DATAS . index [ msg . cmd [ 0 ] ] [ " msg_before " ] , DATAS . index [ msg . cmd [ 0 ] ] [ " msg_after " ] ) )
save ( )
2012-04-09 02:19:39 +00:00
return True
else :
return False
def parseask ( msg ) :
msgl = msg . content . lower ( )
if re . match ( " ^.*((create|new) +(a|an|a +new|an *other)? *(events?|commande?)|(nouvel(le)?|ajoute|cr[ée] { 1,3}) +(un)? *([eé]v[ée]nements?|commande?)).*$ " , msgl ) is not None :
name = re . match ( " ^.*!([^ \" ' @!]+).*$ " , msg . content )
2012-06-20 14:24:19 +00:00
if name is not None and name . group ( 1 ) not in DATAS . index :
2012-04-09 02:19:39 +00:00
texts = re . match ( " ^[^ \" ]*(avant|après|apres|before|after)?[^ \" ]* \" ([^ \" ]+) \" [^ \" ]*((avant|après|apres|before|after)?.* \" ([^ \" ]+) \" .*)?$ " , msg . content )
if texts is not None and texts . group ( 3 ) is not None :
extDate = msg . extractDate ( )
if extDate is None or extDate == " " :
msg . send_snd ( " La date de l ' événement est invalide... " )
else :
if texts . group ( 1 ) is not None and ( texts . group ( 1 ) == " après " or texts . group ( 1 ) == " apres " or texts . group ( 1 ) == " after " ) :
msg_after = texts . group ( 2 )
msg_before = texts . group ( 5 )
if ( texts . group ( 4 ) is not None and ( texts . group ( 4 ) == " après " or texts . group ( 4 ) == " apres " or texts . group ( 4 ) == " after " ) ) or texts . group ( 1 ) is None :
msg_before = texts . group ( 2 )
msg_after = texts . group ( 5 )
if msg_before . find ( " %s " ) != - 1 and msg_after . find ( " %s " ) != - 1 :
2012-06-20 14:24:19 +00:00
evt = ModuleState ( " event " )
evt [ " server " ] = msg . srv . id
evt [ " channel " ] = msg . channel
evt [ " proprio " ] = msg . sender
evt [ " name " ] = name . group ( 1 )
evt [ " start " ] = extDate
evt [ " msg_after " ] = msg_after
evt [ " msg_before " ] = msg_before
DATAS . addChild ( evt )
save ( )
2012-04-09 02:19:39 +00:00
msg . send_snd ( " Nouvel événement ! %s ajouté avec succès. " % name . group ( 1 ) )
else :
msg . send_snd ( " Pour que l ' événement soit valide, ajouter %s à l ' endroit où vous voulez que soit ajouté le compte à rebours. " )
elif texts is not None and texts . group ( 2 ) is not None :
2012-06-20 14:24:19 +00:00
evt = ModuleState ( " event " )
evt [ " server " ] = msg . srv . id
evt [ " channel " ] = msg . channel
evt [ " proprio " ] = msg . sender
evt [ " name " ] = name . group ( 1 )
evt [ " msg_before " ] = texts . group ( 2 )
DATAS . addChild ( evt )
save ( )
2012-04-09 02:19:39 +00:00
msg . send_snd ( " Nouvelle commande ! %s ajoutée avec succès. " % name . group ( 1 ) )
else :
msg . send_snd ( " Veuillez indiquez les messages d ' attente et d ' après événement entre guillemets. " )
elif name is None :
msg . send_snd ( " Veuillez attribuer une commande à l ' événement. " )
else :
msg . send_snd ( " Un événement portant ce nom existe déjà. " )
return False
def parselisten ( msg ) :
return False