Path: csiph.com!fu-berlin.de!uni-berlin.de!not-for-mail From: Mohan L Newsgroups: comp.lang.python Subject: [pyinotify] help required to send only one mail for chunk of events Date: Tue, 24 May 2016 01:50:07 +0530 Lines: 195 Message-ID: References: Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 X-Trace: news.uni-berlin.de A4TB1XUC+WPkpsxMvAns/Q0sfXxCLY9zzOJt9oghDVzA== Return-Path: X-Original-To: python-list@python.org Delivered-To: python-list@mail.python.org X-Spam-Status: OK 0.000 X-Spam-Evidence: '*H*': 1.00; '*S*': 0.00; 'else:': 0.03; 'handler': 0.04; '"""': 0.05; 'paths': 0.05; 'sys': 0.05; '__name__': 0.07; 'aggregate': 0.07; 'append': 0.07; 'chunk': 0.07; 'except:': 0.07; 'main()': 0.07; 'mask': 0.07; 'msg': 0.07; 'subject:help': 0.07; '###': 0.09; 'dict': 0.09; 'event):': 0.09; 'events.': 0.09; 'msg)': 0.09; 'newly': 0.09; 'skip:# 30': 0.09; 'timestamp': 0.09; 'python': 0.10; 'def': 0.13; "skip:' 30": 0.15; 'skip:p 40': 0.15; 'value.': 0.15; "'__main__':": 0.16; "'a')": 0.16; '(int)': 0.16; '(list)': 0.16; '(say': 0.16; '->': 0.16; 'descriptors.': 0.16; 'irc:': 0.16; 'log.': 0.16; 'main():': 0.16; 'msg):': 0.16; 'paths.': 0.16; 'received:io': 0.16; 'received:psf.io': 0.16; 'subject:required': 0.16; 'subject:send': 0.16; 'sys.exit(1)': 0.16; 'directory.': 0.18; 'skip:l 30': 0.18; 'try:': 0.18; '>': 0.18; 'subject:] ': 0.19; 'all,': 0.20; 'parser': 0.22; 'import': 0.24; 'script': 0.25; 'skip:" 20': 0.26; 'appreciated.': 0.27; 'skip:m 30': 0.27; 'skip:# 10': 0.27; 'message- id:@mail.gmail.com': 0.27; 'moved': 0.27; 'sequence': 0.27; 'specify': 0.27; 'idea': 0.28; "skip:' 10": 0.28; '"': 0.29; 'accepts': 0.29; 'mode.': 0.29; 'code:': 0.29; 'print': 0.30; 'code': 0.30; 'skip:& 30': 0.30; 'to:name:python-list': 0.30; 'writes': 0.30; 'operations': 0.31; 'seconds': 0.31; 'skip:s 30': 0.31; 'reported': 0.32; 'class': 0.33; 'extract': 0.33; '(for': 0.34; 'file': 0.34; 'skip:d 20': 0.34; 'add': 0.34; 'list': 0.34; 'mobile:': 0.35; 'received:google.com': 0.35; 'instance': 0.35; 'integrate': 0.35; 'path': 0.35; 'skip:p 30': 0.35; 'but': 0.36; 'created': 0.36; 'received:209.85': 0.36; 'event.': 0.36; 'to:addr :python-list': 0.36; 'really': 0.37; 'two': 0.37; 'skip:& 10': 0.37; 'method': 0.37; 'thanks': 0.37; 'wanted': 0.37; 'associated': 0.38; 'received:209': 0.38; 'log': 0.38; 'several': 0.38; 'skip:p 20': 0.38; 'subject:[': 0.39; 'sure': 0.39; 'format': 0.39; 'to:addr:python.org': 0.40; 'some': 0.40; 'your': 0.60; '&': 0.61; 'email addr:gmail.com': 0.62; 'watch': 0.62; 'efforts.': 0.63; 'skip:y 20': 0.63; 'more': 0.63; 'times': 0.63; 'skip:w 30': 0.64; 'e-mail:': 0.65; 'skip:w 40': 0.66; '\xc2\xa0\xc2\xa0': 0.66; 'here': 0.66; 'repeat': 0.67; 'configparser': 0.84; 'mins': 0.84; 'subject:events': 0.84; 'watches': 0.84; 'watched': 0.91 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:date:message-id:subject:from:to; bh=eN+70+T2LfCiEFDZ3tK4Uo20Au99oA/2E7HuJjKlvBU=; b=dyNxsp65hF9O1Ka1AWUohTwFERRGU0yCllVE/dxz3xKl0GNV+lepFET2ndpMmluxjw fcC22PjwUsSKbGiXY+7lPN3gqIIfU0ZiLe+UMLo2nDncUL1WwPhD2uNVU8igpUTjIxaC 2IPaIMQlq4bNvLXgdhxTIqrHLd4OXn6AnQKH02xtvX68vO/3EtMvNQUwTawnjWcsKvEn h7312Hxs/sY8j1jxd/sMc5vAVPrr4APgVMslcP0zmFvHvMV6HDxkK9wREuQL6hNLmRDP XqQx6TLq7vTYNqLTtdrmQYCYaEJtm8a92NiY6PT/EakSeccciZ/lZbebmKKiPbjJ/PmX GNSQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:date:message-id:subject:from:to; bh=eN+70+T2LfCiEFDZ3tK4Uo20Au99oA/2E7HuJjKlvBU=; b=V0JaRsk17Q4uU379Oq1C9w0lhvKpZb/4OtDy2H9mnUEqdqk7ldrF97rcL2Ndq+sIGI b2kgDuQD4XjosWJ2Mt46uH222Gwmu+HCSEqyyHzntosGpRczVs5gVCXe3JEtuf7WyZQO Ol+at+CTDxyqn6/UJ0BFQ53nvpiWG1mMcefdRnPm5gyQU/WS4X/k0Wzr9IVmFrYRs0V3 a5Aagz86Tqt8YJhu7rg/oCYPp3JY1gM8tI8rQ+sof4a0qPesMscxdNAD5u0QkE9n1Ttj ClgBohaC6MS6us7+kI9slBtDPCSYN5Abnv0zVRC7UrC+OkATjRAyIlzUthP2cq+s4dL5 aSog== X-Gm-Message-State: ALyK8tJ4keLM/y8XuQEIHY59lxm0mjNfCaIEeiNgUetp/sJMyNC4R2eDxfS0RS0lRPfT96jKBoZFEH5jEMZEgQ== X-Received: by 10.98.93.129 with SMTP id n1mr1074721pfj.16.1464034808009; Mon, 23 May 2016 13:20:08 -0700 (PDT) X-Content-Filtered-By: Mailman/MimeDel 2.1.22 X-BeenThere: python-list@python.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: General discussion list for the Python programming language List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Mailman-Original-Message-ID: Xref: csiph.com comp.lang.python:109024 Hi All, I am using the bellow script to watch directories. Using 20 seconds to aggregate together a larger chunk of events and enabled coalescing of events. I wanted to send an email notification with content of logfile after 15 mins on any change. The idea is I want to send only one mail for chunk of events.Say for example, I want to send only one email when some one extract a tar.gz file in watched directory. I can write method to send email (say send_mail) which accept content of logfile. But I am not sure How to integrate it with below code so that my send_mail method get triggered only once for chunk of events. Any help will be really appreciated. Thanks for your time and efforts. Here is code: #!/usr/bin/env python import sys try: import pyinotify except: print "pyinotify not installed" sys.exit(1) import datetime from ConfigParser import SafeConfigParser class MyEventHandler(pyinotify.ProcessEvent): log = "" flog = None def process_IN_CREATE(self, event): """ This method processes a specific type of event: IN_CREATE. event is an instance of Event. """ self.write_msg("CREATING", event.pathname) def process_IN_DELETE(self, event): """ This method processes a specific type of event: IN_DELETE. event is an instance of Event. """ self.write_msg("DELETING", event.pathname) def process_IN_MODIFY(self, event): """ This method processes a specific type of event: IN_MODIFY. event is an instance of Event. """ self.write_msg("MODIFIED", event.pathname) def process_IN_OPEN(self, event): """ This method processes a specific type of event: IN_OPEN. event is an instance of Event. """ self.write_msg("OPENED", event.pathname) def process_IN_ACCESS(self, event): """ This method processes a specific type of event: IN_ACCESS. event is an instance of Event. """ self.write_msg("ACCESSED", event.pathname) def process_IN_ATTRIB(self, event): """ This method processes a specific type of event: IN_ATTRIB. event is an instance of Event. """ self.write_msg("ATTRIB", event.pathname) def process_IN_DELETE_SELF(self, event): """ This method processes a specific type of event: IN_DELETE_SELF. event is an instance of Event. """ self.write_msg("DELETE_SELF", event.pathname) def process_IN_MOVED_FROM(self, event): """ This method processes a specific type of event: IN_MOVED_FROM. event is an instance of Event. """ self.write_msg("FILE MOVED FROM", event.pathname) def process_IN_MOVED_TO(self, event): """ This method processes a specific type of event: IN_MOVED_TO. event is an instance of Event. """ try: msg = event.src_pathname + " -> " + event.pathname except: msg = event.pathname self.write_msg("FILE MOVED INTO", msg) def openlog(self, logfile): """ This method opens log file in append mode. """ self.log = logfile self.flog = file(self.log, 'a') def write_msg(self, event, msg): """ This method writes evens in logfile as well as stdout. """ out_msg = self.generate_timestamp() + "\t" + event + ": " + msg + "\n" if len(self.log) > 0: self.flog.write(out_msg) self.flog.flush() print "LOGGED", out_msg else: print "NOT LOGGED", out_msg def generate_timestamp(self): """ This method generate and return timestamp for log. Timestamp format is YYYY/MM/DD-HH:MM:SS. """ d = datetime.datetime.now() datestr = "%d/%.2d/%.2d-%.2d:%.2d:%.2d" % (d.year, d.month, d.day, d.hour, d.minute, d.second) return datestr def main(): parser = SafeConfigParser() parser.read('/etc/mywatcherscript.ini') ### The watch manager stores the watches and provides operations on watches ### wm = pyinotify.WatchManager() ### List of watched events. To specify two or more events just orize them ### mask = pyinotify.IN_CREATE | pyinotify.IN_DELETE | pyinotify.IN_MODIFY # List of watch path #watched_path_list=['/var/log','/tmp'] watched_path_list=parser.get('mywatcherscript', 'watched_path_list').split(',') pid_file_name=parser.get('mywatcherscript', 'pid_file_name') logfile=parser.get('mywatcherscript', 'logfile') # Add watch(s) on the provided path(s) with associated flag value. # Parameters: # path - Path to watch, the path can either be a file or a directory. # Also accepts a sequence (list) of paths. # mask (int) - Bitmask of events. # rec (bool) - Recursively add watches from path on all its subdirectories. # auto_add (bool) - Automatically add watches on newly created directories in watched parent directory. # # Returns: dict of {str: int} # dict of paths associated to watch descriptors. wm.add_watch(watched_path_list, mask, rec=True, auto_add=True) # event handler eh = MyEventHandler() eh.openlog(logfile) # notifier # Put an arbitrary large value (20 seconds) to aggregate together a larger # chunk of events. For instance if you repeat several times a given action # on the same file its events will be coalesced into a single event and only # one event of this type will be reported (for this period). notifier = pyinotify.Notifier(wm, eh, read_freq=20) #notifier = pyinotify.Notifier(wm, eh) # Enable coalescing of events. notifier.coalesce_events() #notifier.loop() notifier.loop(daemonize=True, pid_file=pid_file_name) if __name__ == '__main__': main() -- Thanks & Regards Mobile: 9444955058 E-Mail: l.mohanphy@gmail.com | thefossgeek@gmail.com IRC: neophy Blog : http://lmohanphy.livejournal.com/