@ -2,7 +2,7 @@ import main
import argparse
import sys
from io import StringIO
from pprint import pformat
from yaml import dump
class Mon :
def __init__ ( self , register ) :
@ -11,27 +11,30 @@ class Mon:
def setup_arguments ( self , ArgumentParser ) :
self . parser = ArgumentParser ( prog = " mon " , description = " Manage monitors. Extremely flexible. All arguments are optional. " )
group1 = self . parser . add_mutually_exclusive_group ( required = True )
group1 . add_argument ( " - -add" , metavar = " entry " , dest = " addEntry " , help = " Add an entry " )
group1 . add_argument ( " - -del" , metavar = " entry " , dest = " delEntry " , help = " Delete an entry " )
group1 . add_argument ( " - -list" , action = " store_true " , dest = " listEntry " , help = " List all entries " )
group1 . add_argument ( " - -mod" , metavar = " entry " , dest = " modEntry " , help = " Modify an entry " )
group1 . add_argument ( " - a" , " - -add" , metavar = " entry " , dest = " addEntry " , help = " Add an entry " )
group1 . add_argument ( " - d" , " - -del" , metavar = " entry " , dest = " delEntry " , help = " Delete an entry " )
group1 . add_argument ( " - l" , " - -list" , action = " store_true " , dest = " listEntry " , help = " List all entries " )
group1 . add_argument ( " - m" , " - -mod" , metavar = " entry " , dest = " modEntry " , help = " Modify an entry " )
group2 = self . parser . add_mutually_exclusive_group ( )
group2 . add_argument ( " - -append" , action = " store_true " , dest = " doAppend " , help = " Append entries to lists instead of replacing " )
group2 . add_argument ( " - -remove" , action = " store_true " , dest = " doRemove " , help = " Remove entries in lists instead of replacing " )
group2 . add_argument ( " - p" , " - -append" , action = " store_true " , dest = " doAppend " , help = " Append entries to lists instead of replacing " )
group2 . add_argument ( " - r" , " - -remove" , action = " store_true " , dest = " doRemove " , help = " Remove entries in lists instead of replacing " )
self . parser . add_argument ( " --type " , nargs = " * " , metavar = " type " , dest = " specType " , help = " Specify type of spec matching. Available types: join, part, quit, msg, topic, mode, nick, kick, notice, action, any " )
self . parser . add_argument ( " --type " , nargs = " * " , metavar = " type " , dest = " specType " , help = " Specify type of spec matching. Available types: join, part, quit, msg, topic, mode, nick, kick, notice, action, who " )
self . parser . add_argument ( " --free " , nargs = " * " , metavar = " query " , dest = " free " , help = " Use freeform matching " )
self . parser . add_argument ( " --exact " , nargs = " * " , metavar = " query " , dest = " exact " , help = " Use exact matching " )
self . parser . add_argument ( " --nick " , nargs = " * " , metavar = " nickname " , dest = " nick " , help = " Use nickname matching " )
self . parser . add_argument ( " --ident " , nargs = " * " , metavar = " ident " , dest = " ident " , help = " Use ident matching " )
self . parser . add_argument ( " --host " , nargs = " * " , metavar = " host " , dest = " host " , help = " Use host matching " )
self . parser . add_argument ( " --real " , nargs = " * " , metavar = " realname " , dest = " real " , help = " Use real name (GECOS) matching (only works on WHO) " )
self . parser . add_argument ( " --real " , nargs = " * " , metavar = " realname " , dest = " real " , help = " Use real name (GECOS) matching . Works with types: who " )
self . parser . add_argument ( " --source " , nargs = " * " , action = " append " , metavar = ( " network " , " channel " ) , dest = " source " , help = " Target network and channel. Works with types: join, part, msg, topic, mode, kick, notice, action (can be specified multiple times) " )
self . parser . add_argument ( " --message " , nargs = " * " , action = " append " , metavar = " message " , dest = " message " , help = " Message. Works with types: part, quit, msg, topic, kick, notice, action " )
self . parser . add_argument ( " --user " , nargs = " * " , metavar = " user " , dest = " user " , help = " User (new nickname or kickee). Works with types: kick, nick " )
self . parser . add_argument ( " --modes " , nargs = " * " , metavar = " modes " , dest = " modes " , help = " Modes. Works with types: mode " )
self . parser . add_argument ( " --modeargs " , nargs = " * " , metavar = " modeargs " , dest = " modeargs " , help = " Mode arguments. Works with types: mode " )
self . parser . add_argument ( " --server " , nargs = " * " , metavar = " server " , dest = " server " , help = " Server. Works with types: who " )
self . parser . add_argument ( " --status " , nargs = " * " , metavar = " status " , dest = " status " , help = " Status. Works with types: who " )
self . parser . add_argument ( " --send " , nargs = " * " , action = " append " , metavar = ( " network " , " target " ) , dest = " send " , help = " Network and target to send notifications to (can be specified multiple times) " )
def mon ( self , addr , authed , data , obj , spl , success , failure , info , incUsage , length ) :
@ -90,6 +93,9 @@ class Mon:
success ( " Successfully removed monitor group: %s " % parsed . delEntry )
return
elif parsed . modEntry :
if not parsed . doAppend and not parsed . doRemove :
failure ( " Specify --append or --remove with --mod " )
return
if not parsed . modEntry in main . monitor . keys ( ) :
failure ( " No such monitor group: %s " % parsed . modEntry )
return
@ -101,22 +107,28 @@ class Mon:
main . monitor [ parsed . modEntry ] = merged
elif parsed . doRemove :
merged = self . subtractCast ( main . monitor [ parsed . modEntry ] , cast , info )
if merged == { } :
del main . monitor [ parsed . modEntry ]
info ( " Group %s deleted due to having no attributes " % parsed . modEntry )
main . saveConf ( " monitor " )
return
main . monitor [ parsed . modEntry ] = merged
else :
failure ( " Specify --append or --remove with --mod " )
return
main . saveConf ( " monitor " )
success ( " Successfully updated entry %s " % parsed . modEntry )
return
elif parsed . listEntry :
info ( pformat ( main . monitor ) )
info ( dum p( main . monitor ) )
return
else :
incUsage ( None )
def dedup ( self , data ) :
if not isinstance ( data , bool ) :
return list ( set ( data ) )
return data
def parseNetworkFormat ( self , lst , failure , info ) :
dedup = lambda x : list ( set ( x ) )
cast = { }
if lst == None :
return " nil "
@ -140,24 +152,23 @@ class Mon:
else :
if i [ 0 ] in cast . keys ( ) :
if not cast [ i [ 0 ] ] == True :
for x in dedup ( i [ 1 : ] ) :
for x in self . dedup ( i [ 1 : ] ) :
cast [ i [ 0 ] ] . append ( x )
else :
cast [ i [ 0 ] ] = dedup ( i [ 1 : ] )
cast [ i [ 0 ] ] = self . dedup ( i [ 1 : ] )
else :
cast [ i [ 0 ] ] = dedup ( i [ 1 : ] )
cast [ i [ 0 ] ] = self . dedup ( i [ 1 : ] )
for i in cast . keys ( ) :
deduped = dedup ( cast [ i ] )
deduped = self . dedup ( cast [ i ] )
cast [ i ] = deduped
return cast
# Create or modify a monitor group magically
def makeCast ( self , obj , failure , info ) :
dedup = lambda x : list ( set ( x ) )
validTypes = [ " join " , " part " , " quit " , " msg " , " topic " , " mode " , " nick " , " kick " , " notice " , " action " , " any " ]
validTypes = [ " join " , " part " , " quit " , " msg " , " topic " , " mode " , " nick " , " kick " , " notice " , " action " , " who " ]
cast = { }
if not obj . specType == None :
types = dedup ( obj . specType )
types = self . dedup ( obj . specType )
for i in types :
if not i in validTypes :
failure ( " Invalid type: %s " % i )
@ -187,6 +198,12 @@ class Mon:
cast [ " user " ] = obj . user
if not obj . modes == None :
cast [ " modes " ] = obj . modes
if not obj . modeargs == None :
cast [ " modeargs " ] = obj . modeargs
if not obj . server == None :
cast [ " server " ] = obj . server
if not obj . status == None :
cast [ " status " ] = obj . status
if not obj . free == None :
cast [ " free " ] = obj . free
if not obj . exact == None :
@ -208,11 +225,24 @@ class Mon:
if i in source . keys ( ) :
if isinstance ( source [ i ] , dict ) :
result = self . subtractCast ( source [ i ] , patch [ i ] , info )
if result == { } :
info ( " Removing upper element: %s " % i )
del source [ i ]
continue
source [ i ] = result
continue
if isinstance ( patch [ i ] , bool ) :
del source [ i ]
info ( " Removing entire element: %s " % i )
continue
for x in patch [ i ] :
if isinstance ( source [ i ] , bool ) :
info ( " Attempt to remove %s from network-wide definition " % x )
continue
if x in source [ i ] :
source [ i ] . remove ( x )
if source [ i ] == [ ] :
del source [ i ]
else :
info ( " Element %s not in source %s " % ( x , i ) )
else :
@ -226,7 +256,14 @@ class Mon:
result = self . addCast ( source [ i ] , patch [ i ] , info )
source [ i ] = result
continue
if isinstance ( patch [ i ] , bool ) :
source [ i ] = patch [ i ]
info ( " Overriding local element %s with network-wide definition " % i )
continue
for x in patch [ i ] :
if isinstance ( source [ i ] , bool ) :
source [ i ] = [ ]
info ( " Overriding element %s , previously set network-wide " % i )
if x in source [ i ] :
info ( " Element %s already in source %s " % ( x , i ) )
else :