2014-08-27 23:39:31 +00:00
""" Create alias of commands """
2015-09-09 23:40:06 +00:00
# PYTHON STUFFS #######################################################
2012-06-30 16:40:42 +00:00
import re
import sys
2014-09-30 21:51:14 +00:00
from datetime import datetime , timezone
2014-10-05 16:19:20 +00:00
import shlex
2012-06-30 16:40:42 +00:00
2015-02-11 17:12:39 +00:00
from nemubot import context
2015-01-04 22:57:09 +00:00
from nemubot . exception import IRCException
2015-01-03 19:34:44 +00:00
from nemubot . hooks import hook
2015-04-06 07:50:13 +00:00
from nemubot . message import Command
2015-01-05 09:18:40 +00:00
from nemubot . tools . xmlparser . node import ModuleState
2014-08-12 18:10:19 +00:00
2014-09-26 16:00:22 +00:00
from more import Response
2014-11-13 01:51:49 +00:00
2015-09-09 23:40:06 +00:00
# HELP ################################################################
def help_full ( ) :
return " Pour créer un alias, adressez-vous à moi en disant quelque chose comme : \" nouvel alias XX : YY \" , où YY sera la commande équivalente à XX. Vous pouvez ajouter des variables comme $ {1} , $ {2} , ... correspondant aux éventuels arguments. \n De l ' aide supplémentaire existe pour les commandes !alias, !listalias, !unalias, !set et !listvars "
# LOADING #############################################################
2012-08-22 23:54:52 +00:00
def load ( context ) :
""" Load this module """
2015-02-11 17:12:39 +00:00
if not context . data . hasNode ( " aliases " ) :
context . data . addChild ( ModuleState ( " aliases " ) )
context . data . getNode ( " aliases " ) . setIndex ( " alias " )
if not context . data . hasNode ( " variables " ) :
context . data . addChild ( ModuleState ( " variables " ) )
context . data . getNode ( " variables " ) . setIndex ( " name " )
2012-06-30 16:40:42 +00:00
2015-09-09 23:40:06 +00:00
# MODULE CORE #########################################################
## Alias management
def list_alias ( channel = None ) :
""" List known aliases.
Argument :
channel - - optional , if defined , return a list of aliases only defined on this channel , else alias widly defined
"""
2012-06-30 16:40:42 +00:00
2015-09-09 23:40:06 +00:00
for alias in context . data . getNode ( " aliases " ) . index . values ( ) :
if ( channel is None and " channel " not in alias ) or ( channel is not None and " channel " in alias and alias [ " channel " ] == channel ) :
yield alias
def create_alias ( alias , origin , channel = None , creator = None ) :
""" Create or erase an existing alias
"""
anode = ModuleState ( " alias " )
anode [ " alias " ] = alias
anode [ " origin " ] = origin
if channel is not None :
anode [ " creator " ] = channel
if creator is not None :
anode [ " creator " ] = creator
context . data . getNode ( " aliases " ) . addChild ( anode )
context . save ( )
## Variables management
2014-11-13 01:51:49 +00:00
2012-08-22 23:54:52 +00:00
def get_variable ( name , msg = None ) :
2015-09-09 23:40:06 +00:00
""" Get the value for the given variable
Arguments :
name - - The variable identifier
msg - - optional , original message where some variable can be picked
"""
if msg is not None and ( name == " sender " or name == " from " or name == " nick " ) :
2014-10-05 16:19:20 +00:00
return msg . frm
2015-09-09 23:40:06 +00:00
elif msg is not None and ( name == " chan " or name == " channel " ) :
2012-08-22 23:54:52 +00:00
return msg . channel
elif name == " date " :
2014-09-30 21:51:14 +00:00
return datetime . now ( timezone . utc ) . strftime ( " %c " )
2015-02-11 17:12:39 +00:00
elif name in context . data . getNode ( " variables " ) . index :
return context . data . getNode ( " variables " ) . index [ name ] [ " value " ]
2012-08-22 23:54:52 +00:00
else :
return " "
2014-11-13 01:51:49 +00:00
2015-09-09 23:40:06 +00:00
def list_variables ( user = None ) :
""" List known variables.
2012-08-22 23:54:52 +00:00
2015-09-09 23:40:06 +00:00
Argument :
user - - optional , if defined , display only variable created by the given user
"""
if user is not None :
return [ x for x in context . data . getNode ( " variables " ) . index . values ( ) if x [ " creator " ] == user ]
2015-07-10 22:09:43 +00:00
else :
2015-09-09 23:40:06 +00:00
return context . data . getNode ( " variables " ) . index . values ( )
2014-11-13 01:51:49 +00:00
2014-06-30 08:59:25 +00:00
2015-09-09 23:40:06 +00:00
def set_variable ( name , value , creator ) :
""" Define or erase a variable.
2014-11-13 01:51:49 +00:00
2015-09-09 23:40:06 +00:00
Arguments :
name - - The variable identifier
value - - Variable value
creator - - User who has created this variable
"""
2014-06-30 08:59:25 +00:00
2015-09-09 23:40:06 +00:00
var = ModuleState ( " variable " )
var [ " name " ] = name
var [ " value " ] = value
var [ " creator " ] = creator
context . data . getNode ( " variables " ) . addChild ( var )
context . save ( )
2012-11-02 19:28:48 +00:00
2014-11-13 01:51:49 +00:00
2015-09-09 23:40:06 +00:00
def replace_variables ( cnt , msg = None ) :
""" Replace variables contained in the content
2014-11-13 01:51:49 +00:00
2015-09-09 23:40:06 +00:00
Arguments :
cnt - - content where search variables
msg - - optional message where pick some variables
"""
2012-11-02 19:28:48 +00:00
2015-06-07 13:49:01 +00:00
if isinstance ( cnt , list ) :
return [ replace_variables ( c , msg ) for c in cnt ]
2014-03-03 19:26:34 +00:00
unsetCnt = list ( )
2015-07-02 18:17:22 +00:00
for res in re . findall ( " \\ $ \ { (?P<name>[a-zA-Z0-9:]+) \ } " , cnt ) :
rv = re . match ( " ([0-9]+)(:([0-9]*))? " , res )
if rv is not None :
varI = int ( rv . group ( 1 ) ) - 1
print ( varI , len ( msg . args ) )
if varI > len ( msg . args ) :
cnt = cnt . replace ( " $ { %s } " % res , " " , 1 )
elif rv . group ( 2 ) is not None :
if rv . group ( 3 ) is not None :
varJ = int ( rv . group ( 3 ) ) - 1
cnt = cnt . replace ( " $ { %s } " % res , " " . join ( msg . args [ varI : varJ ] ) , 1 )
else :
cnt = cnt . replace ( " $ { %s } " % res , " " . join ( msg . args [ varI : ] ) , 1 )
else :
cnt = cnt . replace ( " $ { %s } " % res , msg . args [ varI ] , 1 )
2015-06-07 13:49:01 +00:00
unsetCnt . append ( varI )
2015-07-02 18:17:22 +00:00
else :
2015-06-07 13:49:01 +00:00
cnt = cnt . replace ( " $ { %s } " % res , get_variable ( res ) , 1 )
for u in sorted ( unsetCnt , reverse = True ) :
msg . args . pop ( u )
return cnt
2012-11-02 19:28:48 +00:00
2015-09-09 23:40:06 +00:00
# MODULE INTERFACE ####################################################
## Variables management
@hook ( " cmd_hook " , " listvars " )
def cmd_listvars ( msg ) :
if len ( msg . args ) :
res = list ( )
for user in msg . args :
als = [ v [ " alias " ] for v in list_variables ( user ) ]
if len ( als ) > 0 :
res . append ( " Variables créées par %s : %s " % ( user , " , " . join ( als ) ) )
else :
res . append ( " %s n ' a pas encore créé de variable " % user )
return Response ( " ; " . join ( res ) , channel = msg . channel )
elif len ( context . data . getNode ( " variables " ) . index ) :
return Response ( " Variables connues : %s . " %
" , " . join ( list_variables ( ) ) ,
channel = msg . channel )
else :
return Response ( " No variable are currently stored. " , channel = msg . channel )
@hook ( " cmd_hook " , " set " )
def cmd_set ( msg ) :
if len ( msg . args ) < 2 :
raise IRCException ( " !set prend au minimum deux arguments : "
" le nom de la variable et sa valeur. " )
set_variable ( msg . args [ 0 ] , " " . join ( msg . args [ 1 : ] ) , msg . nick )
return Response ( " Variable \ $ %s définie avec succès. " % msg . args [ 0 ] ,
channel = msg . channel )
## Alias management
@hook ( " cmd_hook " , " listalias " )
def cmd_listalias ( msg ) :
aliases = [ a for a in list_alias ( None ) ] + [ a for a in list_alias ( msg . channel ) ]
if len ( aliases ) :
return Response ( [ a [ " alias " ] for a in aliases ] ,
channel = msg . channel ,
title = " Known aliases: " )
return Response ( " There is no alias currently. " , channel = msg . channel )
@hook ( " cmd_hook " , " alias " )
def cmd_alias ( msg ) :
if not len ( msg . args ) :
raise IRCException ( " !alias prend en argument l ' alias à étendre. " )
res = list ( )
for alias in msg . args :
if alias [ 0 ] == " ! " :
alias = alias [ 1 : ]
if alias in context . data . getNode ( " aliases " ) . index :
res . append ( " ! %s correspond à %s " % ( alias , context . data . getNode ( " aliases " ) . index [ alias ] [ " origin " ] ) )
else :
res . append ( " ! %s n ' est pas un alias " % alias )
return Response ( res , channel = msg . channel , nick = msg . nick )
@hook ( " cmd_hook " , " unalias " )
def cmd_unalias ( msg ) :
if not len ( msg . args ) :
raise IRCException ( " Quel alias voulez-vous supprimer ? " )
res = list ( )
for alias in msg . args :
if alias [ 0 ] == " ! " and len ( alias ) > 1 :
alias = alias [ 1 : ]
if alias in context . data . getNode ( " aliases " ) . index :
context . data . getNode ( " aliases " ) . delChild ( context . data . getNode ( " aliases " ) . index [ alias ] )
res . append ( Response ( " %s a bien été supprimé " % alias ,
channel = msg . channel ) )
else :
res . append ( Response ( " %s n ' est pas un alias " % alias ,
channel = msg . channel ) )
return res
## Alias replacement
2014-10-05 16:19:20 +00:00
@hook ( " pre_Command " )
2014-09-01 17:21:54 +00:00
def treat_alias ( msg ) :
2015-02-11 17:12:39 +00:00
if msg . cmd in context . data . getNode ( " aliases " ) . index :
txt = context . data . getNode ( " aliases " ) . index [ msg . cmd ] [ " origin " ]
2014-10-05 16:19:20 +00:00
# TODO: for legacy compatibility
if txt [ 0 ] == " ! " :
txt = txt [ 1 : ]
try :
args = shlex . split ( txt )
except ValueError :
args = txt . split ( ' ' )
2015-06-07 13:49:01 +00:00
nmsg = Command ( args [ 0 ] , replace_variables ( args [ 1 : ] , msg ) + msg . args , * * msg . export_args ( ) )
2012-11-02 19:28:48 +00:00
2014-09-15 05:55:35 +00:00
# Avoid infinite recursion
2014-10-05 16:19:20 +00:00
if msg . cmd != nmsg . cmd :
2015-06-10 22:09:33 +00:00
# Also return origin message, if it can be treated as well
return [ msg , nmsg ]
2014-10-05 16:19:20 +00:00
return msg
2012-11-02 19:28:48 +00:00
2012-06-30 16:40:42 +00:00
2014-08-28 16:05:21 +00:00
@hook ( " ask_default " )
2012-08-22 23:54:52 +00:00
def parseask ( msg ) :
2014-08-29 14:33:45 +00:00
if re . match ( " .*(set|cr[ée] {2} |nouvel(le)?) alias.* " , msg . text ) is not None :
2015-09-09 23:40:06 +00:00
result = re . match ( " .*alias !?([^ ]+) ?(pour|=|:) ?(.+)$ " , msg . text )
2015-06-10 22:06:55 +00:00
if result . group ( 1 ) in context . data . getNode ( " aliases " ) . index :
2014-09-18 05:57:06 +00:00
raise IRCException ( " cet alias est déjà défini. " )
2012-08-30 23:54:57 +00:00
else :
2015-09-09 23:40:06 +00:00
create_alias ( result . group ( 1 ) ,
result . group ( 3 ) ,
channel = msg . channel ,
creator = msg . nick )
2014-11-13 01:51:49 +00:00
res = Response ( " Nouvel alias %s défini avec succès. " %
result . group ( 1 ) , channel = msg . channel )
2012-08-30 23:54:57 +00:00
return res
2014-09-01 17:21:54 +00:00
return None