class TimerPlug(SignalPlug): """The Timer plug-in will be the most simplistic SignalPlugin. It will create a timer in accordance with the time you need, and then send an alert once the timer is finished. You can ask for a port number from this plug-in if you want the alert to bypass the daemon all together and ping some other program. """ def __init__(self, conf): SignalPlug.__init__(self,conf, autostart=False) #force no autostart self._timers = [] self._connections = [] self.running = False self._port = self.config.getint("port", DEFAULT_PORT) self._maxrand = max(self.config.getint("maxrand", DEFAULT_MAXRAND), LOWEST_RAND) self._minrand = max(self.config.getint("minrand", DEFAULT_MINRAND), LOWEST_RAND) if self._maxrand < self._minrand: self._maxrand , self._minrand = self._minrand, self._maxrand self._socket = DaemonServerSocket(port=self._port) #TODO: get these other settings working. # ip_whitelist=whitelist, # externalBlock=self.config.getboolean("Daemon","local-only"), # allowAll=self.config.getboolean("Daemon", "allow-all")) # See the readme for more information on these commands. self._commands = [ #TODO: fix all triggers Command("status", trigger=self.getstatus, help="Returns the status of a given timer, or all of them."), Command("timers", trigger=self.gettimers, help="Return a printout of the timers' status."), Command("kill", trigger=self.deactivate, help="Stops all timers/connections"), Command("stopall", trigger=self.killtimers, help="Stops all timers!"), Command("closeall", trigger=self.killconnections, help="Closes all open connections."), Command("rm", trigger=self.removetimer, help="Remove a timer by its index"), Command("arand", trigger=self.arand, help="Add a timer for a random amount of time between two numbers."), Command("port", trigger=self.getport, help="Get the port to connect to on the current host that the alert msg will signal down."), Command("add", trigger=self.add, help="Add with three variables, first is seconds, second is minutes, third is hours.")] self.EVENT_timer = Event(self, "timer", "Timer went off!") self._events = [self.EVENT_timer] def save(self): """ Save my internal configuration.""" SignalPlug.save(self) self.config.set("port", self._port) self.config.set("maxrand", self._maxrand) self.config.set("minrand", self._minrand) def get_commands(self): """ Returns the command dictionary! """ return self._commands def get_events(self): #just to make sure everything is registered first. for e in self._events: e.register() return self._events def getport(self): return self._port def getstatus(self): return "There are "+str(len(self._timers))+" timers running." def gettimers(self): timers = [] for timer in self._timers: timers.append({"Created":timer.getTimeCreated(), "Ends":timer.getTimeToEnd()}) return timers def add(self, *args): seconds = 0 if len(args) == 3: #hours seconds += int(args[2])*3600 if len(args) >= 2:#minutes seconds += int(args[1])*60 if len(args) >= 1: #seconds seconds += int(args[0]) if len(args) > 0: self.addtimer(seconds) else: raise Exception("Add needs 1-3 arguments.") def arand(self, *args): if len(args) == 1: #set min=args min = int(args[0]) if min < 1: raise Exception("Value given for arand must be larger than 1.") else: return self.addtimer(random.randint(min, self._maxrand)) elif len(args) == 2: #set both max and min min = int(args[0]) max = int(args[1]) if min <= LOWEST_RAND or max <= LOWEST_RAND: raise Exception("Value given for arand must be larger than "+str(LOWEST_RAND)) #if max and min are switched, then swap them before testing. elif max < min: max, min = min, max return self.addtimer(random.randint(min, max)) else: #use the variables from the config file return self.addtimer(random.randint(self._minrand, self._maxrand)) def addtimer(self, seconds): """ Adds a timer, and starts the SingalPlugin if needed.""" try: t = MyTimer(seconds, self.sendSignal) t.start() self._timers.append(t) self.activate() #starts the run thread if its not already running return "Started timer for "+str(seconds)+" seconds!" except Exception as e: logging.exception(e) raise Exception("Couldn't add timer!") def removetimer(self, index): """ Removes a timer. The _run method will notice if nothings there. """ try: t = self._timers.pop(index) t.cancel() return "Successfully removed timer!" except: raise Exception("Couldn't removed timer!") def sendSignal(self, timer): for conn in self._connections: try:conn.send(self.EVENT_timer) except:pass self.EVENT_timer.trigger() self._timers = list(filter(lambda a: not a.isFinished(), self._timers)) def killconnections(self): """ Close all open connections. """ for conn in self._connections: try:conn.close() except:pass self._connections=[] def killtimers(self): """ Cancels all running timers! """ for timer in self._timers: timer.cancel() self._timers = [] def deactivate(self): """ stops all connections and the server. """ SignalPlug.deactivate(self) self.killconnections() self.killtimers() def run(self): """ Runs when there are timers to watch, and then sends a signal when there is need to.""" try: self.is_activated=True while self.is_activated: try: #make sure all of the connections are saved. connection = self._socket.accept() self._connections.append(connection) except timeout: pass except Exception as e: logging.exception(e) finally: self.deactivate()
class FileWatcher(LoopPlug): """ Watches a list of local files for changes. Any changes are added to the internal alert queue. The commands that can be sent to this are: update - forces an update status - checks whether the plug-in is activated files - returns a list of the files being watched add x - add file x to list of files being watched rm x - remove file x from list, x being an index or the file name. The actual changes to the files are not known since they are not cached or stored in anyway. This can change if you want to write a more advanced FileWatcher class. """ def __init__(self, conf): LoopPlug.__init__(self, conf) self._files = {} for file in self.config.getlist("files",[]): try: self._files[file] = os.path.getmtime(file) except Exception as e: logging.error("%s had an error getting the file time" % e) break self._commands =[Command("update", trigger=self.update, help="forces an update"), Command("status", trigger=self.check_status, help="checks whether the plug is activated"), Command("files", trigger=self.get_files, help="returns a list of files being watched"), Command("add", trigger=self.add_file, help="add file x o list of files being watched"), Command("rm", trigger=self.rm_file, help="remove file x from list, x being an index or the file name.")] # The file watcher only has one event... self.EVENT_filechange = Event(self, "filechange") self._events = [self.EVENT_filechange] def get_commands(self): return self._commands def get_events(self): return self._events def check_status(self): """ Returns whether or not this plug-in is activated or not. """ return self.is_activated def update(self, *args): if len(args) > 0: #update the one given if args[0] in self._files: if self._files.get(args[0]) < os.path.getmtime(args[0]): self._files[args[0]] = os.path.getmtime(args[0]) self.EVENT_filechange.trigger("File '"+args[0]+"' changed at "+str(self._files[args[0]])+"!") #ignore the fact that the file doesn't exist, if this problem arises. else:#update all for file in list(self._files.keys()): try: if self._files.get(file) < os.path.getmtime(file): self._files[file] = os.path.getmtime(file) self.EVENT_filechange.trigger("File '"+file+"' changed at "+str(self._files[file])+"!") except Exception as e: logging.exception(e) def get_files(self): """ Gets the internal list of files """ return list(self._files.keys()) def add_file(self, dest, args): try: self._files[args[0]] = int(time.time()) return "success" except: raise Exception("couldn't add file.") def rm_file(self, dest, args): try: for key in self._files.keys(): if key == args[0]: self._files.remove(key) break return "success" except: raise Exception("couldn't add file.") def save(self): """Pushes the internal variables to the config variable for saving! """ LoopPlug.save(self) filestring = "" count = len(self._files.keys()) for file in self._files.keys(): filestring+=file count-=1 if count>0:filestring+="," self.config.set("files", filestring)