python pyinotify模块详解
- flags = IN_CLOSE_WRITE|IN_CREATE|IN_Q_OVERFLOW
pyinotify.IN_CREATE就好懂多了,这里用几个监控的类型的int值进行逻辑运算成监控需要监控的改变类型的数值具体数值怎么定义可以看
看pyinotify.py文件中的class EventsCodes:中定义FLAG_COLLECTIONS的数值
UpdateParentDir(ProcessEvent):这里之前看不懂,特别是下面的process_IN_CLOSE_WRITE(self,
event):,都不知道event哪里来的因为以前学c么什么函数重载,类的重载。这里其实就是什么派生重载子类而已
- def __init__(self, pevent=None, **kargs):
- self.pevent = pevent
- self.my_init(**kargs)
- def process_IN_Q_OVERFLOW(self, event):
- log.warning('Event queue overflowed.')
- def process_default(self, event):
- pass
- class WatchManager:
- def __init__(self, exclude_filter=lambda path: False):
- self._fd = self._inotify_wrapper.inotify_init()
- def add_watch(self, path, mask, proc_fun=None, rec=False,
- auto_add=False, do_glob=False, quiet=True,
- exclude_filter=None):
- wd = ret_[rpath] = self.__add_watch(rpath, mask,
- proc_fun,
- auto_add,
- exclude_filter)
- class Notifier:
- def __init__(self, watch_manager, default_proc_fun=None, read_freq=0,
- threshold=0, timeout=None):
- """
- @type watch_manager: WatchManager instance
- @param default_proc_fun: Default processing method. If None, a new
- instance of PrintAllEvents will be assigned.
- @type default_proc_fun: instance of ProcessEvent
- """
- # Watch Manager instance
- self._watch_manager = watch_manager
- # File descriptor
- self._fd = self._watch_manager.get_fd()
- # Poll object and registration
- self._pollobj = select.poll()
- self._pollobj.register(self._fd, select.POLLIN)
- # This pipe is correctely initialized and used by ThreadedNotifier
- self._pipe = (-1, -1)
- # Event queue
- self._eventq = deque()
- # System processing functor, common to all events
- self._sys_proc_fun = _SysProcessEvent(self._watch_manager, self)
- # Default processing method
- self._default_proc_fun = default_proc_fun
- if default_proc_fun is None:
- self._default_proc_fun = PrintAllEvents()
- # Loop parameters
- self._read_freq = read_freq
- self._threshold = threshold
- self._timeout = timeout
- # Coalesce events option
- self._coalesce = False
- # set of str(raw_event), only used when coalesce option is True
- self._eventset = set()
- self._fd = self._watch_manager.get_fd()
- self._pollobj = select.poll()
- self._sys_proc_fun = _SysProcessEvent(self._watch_manager, self)
- self._default_proc_fun = default_proc_fun
- def loop(self, callback=None, daemonize=False, **args):
- """
- Events are read only one time every min(read_freq, timeout)
- seconds at best and only if the size to read is >= threshold.
- After this method returns it must not be called again for the same
- instance.
- @param callback: Functor called after each event processing iteration.
- Expects to receive the notifier object (self) as first
- parameter. If this function returns True the loop is
- immediately terminated otherwise the loop method keeps
- looping.
- @type callback: callable object or function
- @param daemonize: This thread is daemonized if set to True.
- @type daemonize: boolean
- @param args: Optional and relevant only if daemonize is True. Remaining
- keyworded arguments are directly passed to daemonize see
- __daemonize() method. If pid_file=None or is set to a
- pathname the caller must ensure the file does not exist
- before this method is called otherwise an exception
- pyinotify.NotifierError will be raised. If pid_file=False
- it is still daemonized but the pid is not written in any
- file.
- @type args: various
- """
- if daemonize:
- self.__daemonize(**args)
- # Read and process events forever
- while 1:
- try:
- self.process_events()
- if (callback is not None) and (callback(self) is True):
- break
- ref_time = time.time()
- # check_events is blocking
- if self.check_events():
- self._sleep(ref_time)
- self.read_events()
- except KeyboardInterrupt:
- # Stop monitoring if sigint is caught (Control-C).
- log.debug('Pyinotify stops monitoring.')
- break
- # Close internals
- self.stop()
- def process_events(self):
- """
- Routine for processing events from queue by calling their
- associated proccessing method (an instance of ProcessEvent).
- It also does internal processings, to keep the system updated.
- """
- while self._eventq:
- raw_event = self._eventq.popleft() # pop next event
- watch_ = self._watch_manager.get_watch(raw_event.wd)
- if watch_ is None:
- # Not really sure how we ended up here, nor how we should
- # handle these types of events and if it is appropriate to
- # completly skip them (like we are doing here).
- log.warning("Unable to retrieve Watch object associated to %s",
- repr(raw_event))
- continue
- revent = self._sys_proc_fun(raw_event) # system processings
- if watch_ and watch_.proc_fun:
- watch_.proc_fun(revent) # user processings
- else:
- self._default_proc_fun(revent)
- self._sys_proc_fun.cleanup() # remove olds MOVED_* events records
- if self._coalesce:
- self._eventset.clear()
- if (callback is not None) and (callback(self) is True):
- break
- ref_time = time.time()
- def check_events(self, timeout=None):
- """
- Check for new events available to read, blocks up to timeout
- milliseconds.
- @param timeout: If specified it overrides the corresponding instance
- attribute _timeout.
- @type timeout: int
- @return: New events to read.
- @rtype: bool
- """
- while True:
- try:
- # blocks up to 'timeout' milliseconds
- if timeout is None:
- timeout = self._timeout
- ret = self._pollobj.poll(timeout)
- except select.error, err:
- if err[0] == errno.EINTR:
- continue # interrupted, retry
- else:
- raise
- else:
- break
- if not ret or (self._pipe[0] == ret[0][0]):
- return False
- # only one fd is polled
- return ret[0][1] & select.POLLIN
- while True:
- GetList,SendList,ErrList = select.select([self.socket,],[],[],0)
- if len(GetList) > 0:
- try:
- curSock,userAddr = self.socket.accept()
- # curSock.settimeout(15)
- self.socket_pool.append(curSock)
- print "get new socket"
- except:
- print "error or time out"
- get_sock_pool,send_sock_pool,err_sock_pool = select.select(self.socket_pool,[],[],0)
- def read_events(self):
- """
- Read events from device, build _RawEvents, and enqueue them.
- """
- buf_ = array.array('i', [0])
- # get event queue size
- if fcntl.ioctl(self._fd, termios.FIONREAD, buf_, 1) == -1:
- return
- queue_size = buf_[0]
- if queue_size < self._threshold:
- log.debug('(fd: %d) %d bytes available to read but threshold is '
- 'fixed to %d bytes', self._fd, queue_size,
- self._threshold)
- return
- try:
- # Read content from file
- r = os.read(self._fd, queue_size)
- except Exception, msg:
- raise NotifierError(msg)
- log.debug('Event queue size: %d', queue_size)
- rsum = 0 # counter
- while rsum < queue_size:
- s_size = 16
- # Retrieve wd, mask, cookie and fname_len
- wd, mask, cookie, fname_len = struct.unpack('iIII',
- r[rsum:rsum+s_size])
- # Retrieve name
- fname, = struct.unpack('%ds' % fname_len,
- r[rsum + s_size:rsum + s_size + fname_len])
- rawevent = _RawEvent(wd, mask, cookie, fname)
- if self._coalesce:
- # Only enqueue new (unique) events.
- raweventstr = str(rawevent)
- if raweventstr not in self._eventset:
- self._eventset.add(raweventstr)
- self._eventq.append(rawevent)
- else:
- self._eventq.append(rawevent)
- rsum += s_size + fname_len
- raw_event = self._eventq.popleft()
- watch_ = self._watch_manager.get_watch(raw_event.wd)
- if watch_ is None:
- revent = self._sys_proc_fun(raw_event)
- if watch_ and watch_.proc_fun:
- watch_.proc_fun(revent)
- else:
- self._default_proc_fun(revent)
- #!/usr/bin/python
- from pyinotify import *
- import os, os.path
- flags = IN_CLOSE_WRITE|IN_CREATE|IN_Q_OVERFLOW
- dirs = {}
- base = '/log/lighttpd/cache/images/icon/u241'
- base = 'tmp'
- class UpdateParentDir(ProcessEvent):
- def process_IN_CLOSE_WRITE(self, event):
- print 'modify', event.pathname
- mtime = os.path.getmtime(event.pathname)
- p = event.path
- while p.startswith(base):
- m = os.path.getmtime(p)
- if m < mtime:
- print 'update', p
- os.utime(p, (mtime,mtime))
- elif m > mtime:
- mtime = m
- p = os.path.dirname(p)
- process_IN_MODIFY = process_IN_CLOSE_WRITE
- def process_IN_Q_OVERFLOW(self, event):
- print 'over flow'
- max_queued_events.value *= 2
- def process_default(self, event):
- pass
- wm = WatchManager()
- notifier = Notifier(wm, UpdateParentDir())
- dirs.update(wm.add_watch(base, flags, rec=True, auto_add=True))
- notifier.loop()
所以后面self._default_proc_fun(revent)重载的之前,_ProcessEvent中的process_IN_CREATE
其实已经执行过了,即使后面重载process_IN_CREATE方法,原来的process_IN_CREATE
- meth = getattr(self, 'process_' + maskname, None)
- if meth is not None:
- return meth(event)
- meth = getattr(self, 'process_IN_' + maskname.split('_')[1], None)
- self._inotify_wrapper = INotifyWrapper.create()
- if self._inotify_wrapper is None:
- raise InotifyBindingNotFoundError()
- self._fd = self._inotify_wrapper.inotify_init() # file descriptor
- wd = self._inotify_wrapper.inotify_add_watch(self._fd, path, mask)
- try:
- libc_name = ctypes.util.find_library('c')
- except (OSError, IOError):
- pass # Will attemp to load it with None anyway.
- if sys.version_info >= (2, 6):
- self._libc = ctypes.CDLL(libc_name, use_errno=True)
- self._get_errno_func = ctypes.get_errno
- else:
- self._libc = ctypes.CDLL(libc_name)
- try:
- location = self._libc.__errno_location
- location.restype = ctypes.POINTER(ctypes.c_int)
- self._get_errno_func = lambda: location().contents.value
- except AttributeError:
- pass
- # Eventually check that libc has needed inotify bindings.
- if (not hasattr(self._libc, 'inotify_init') or
- not hasattr(self._libc, 'inotify_add_watch') or
- not hasattr(self._libc, 'inotify_rm_watch')):
- return False
- return True
python pyinotify模块详解的更多相关文章
- python time模块详解
python time模块详解 转自:http://blog.csdn.net/kiki113/article/details/4033017 python 的内嵌time模板翻译及说明 一.简介 ...
- python docopt模块详解
python docopt模块详解 docopt 本质上是在 Python 中引入了一种针对命令行参数的形式语言,在代码的最开头使用 """ ""&q ...
- (转)python collections模块详解
python collections模块详解 原文:http://www.cnblogs.com/dahu-daqing/p/7040490.html 1.模块简介 collections包含了一些特 ...
- python pathlib模块详解
python pathlib模块详解
- Python Fabric模块详解
Python Fabric模块详解 什么是Fabric? 简单介绍一下: Fabric是一个Python的库和命令行工具,用来提高基于SSH的应用部署和系统管理效率. 再具体点介绍一下,Fabri ...
- python time 模块详解
Python中time模块详解 发表于2011年5月5日 12:58 a.m. 位于分类我爱Python 在平常的代码中,我们常常需要与时间打交道.在Python中,与时间处理有关的模块就包括: ...
- python常用模块详解
python常用模块详解 什么是模块? 常见的场景:一个模块就是一个包含了python定义和声明的文件,文件名就是模块名字加上.py的后缀. 但其实import加载的模块分为四个通用类别: 1 使用p ...
- python os模块详解
一.Python os模块(Linux环境) 1.1 执行shell命令 os.system('cmd') 执行命令不保存结果 os.popen('command') 执行后返回结果,使用.read( ...
- Python ZipFile模块详解(转)
Python zipfile模块用来做zip格式编码的压缩和解压缩的,zipfile里有两个非常重要的class, 分别是ZipFile和ZipInfo, 在绝大多数的情况下,我们只需要使用这两个cl ...
随机推荐
- 浅谈android反调试之 API判断
反调试:利用Java层API来判断Android程序是否是处于被调试下. 1.直接调用系统的android.os.Debug.isDebuggerConnected()方法 我们进行动态调试的时候,其 ...
- mybatis学习(十二)——mybatis逆向工程
MyBatis Generator (MBG)是一个mabatis的代码生成器,能够根据表自动生成mapper接口,mapper.xml文件,javaBean文件. 1.MBG的下载 打开https: ...
- css3 手机端翻屏切换效果
原理是基于css3的 1.景深:perspective:100px; 2.中心点:transform-origin:center center 0; 3.transform-style:preserv ...
- yii模板中常用变量总结
yii模板中常用的一些变量总结. 现有这样一个url:http://www.phpernote.com/demos/helloworld/index.php/xxx/xxx 则通过如下方式获取的值对应 ...
- 关于vsftp所遇问题
问题:使用ftp工具上传文件时提示 553 Could not create file.错误: 严重文件传输错误解决方法:除了检查ftp服务外,需要使用 getsebool -a|grep ftp, ...
- 笔记-迎难而上之Java基础进阶5
Lambda表达式无参数无返回值的练习 //定义一个接口 public interface Cook{ public abstract void makeFood(); } public class ...
- 使用spring声明式事务,spring使用AOP来支持声明式事务,会根据事务属性,自动在方法调用之前决定是否开启一个事务,并在方法执行之后决定事务提交或回滚事务。
使用spring声明式事务,spring使用AOP来支持声明式事务,会根据事务属性,自动在方法调用之前决定是否开启一个事务,并在方法执行之后决定事务提交或回滚事务.
- Objective-C 的 API 设计(转)
英文原文:API Design 转自oschina 参与翻译(14人): 李远超, 魏涛, showme, weizhe72, 周荣冰, crAzyli0n, WangWenjing, throwab ...
- [zlib]_[0基础]_[使用Zlib完整解压zip内容]
场景: 1. 解压文件一般用在下载了一个zip文件之后解压,或者分析某个文件须要解压的操作上. 2. 解压文件,特别是解压带目录的zip文件往往系统没有提供这类Win32 API,当然C#自带库能解压 ...
- 如何突破Windows环境限制打开“命令提示符”
如今,许多企业或组织都会通过使用受限的windows环境来减少系统表面的漏洞.系统加固的越好,那么也就意味着能被访问和使用到的功能就越少. 我最近遇到的情况是,一个已经加固的系统同时受到McAfee ...