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 ...
随机推荐
- hihoCoder #1246 王胖浩与环
题目大意 $n$($1\le n\le 2000$)个正整数 $a_1, a_2, \dots, a_n$($a_i\le 5\times 10^7$)分布在一个圆环上. 定义 $b_k$ 为:将环上 ...
- sklearn python API
sklearn python API LinearRegression from sklearn.linear_model import LinearRegression # 线性回归 # modul ...
- [CODEVS1916] 负载平衡问题(最小费用最大流)
传送门 输入所有 a[i],求出平均值 sum,每个 a[i] -= sum 那么如果 a[i] > 0,从 s 向 i 连一条容量为 a[i] 费用为 0 的有向边 如果 a[i] < ...
- c++ 的语法方面的问题
1.字符串string 中 ""和null的区别 答:举个例子,你老妈让你去打瓶酱油.你要是空手去了,你就是带着null去的.你要是带着空瓶子去的,你就是呆着“”去的.希望你能理 ...
- jenkins配置发送邮件
1.打开系统管理->系统设置,找到邮件设置,如下: 2.SMTP或者其他方式的发送邮件,可自行配置,一下列出了qq邮箱和163邮箱设置的地方,如下图: qq邮箱: 往下拉,找到如下图: 163邮 ...
- Zabbix实现短信报警设置(实战)
配置环境: zabbix 2.2.15 1.配置示警媒介类型 此文件所在位置:/usr/lib/zabbix/alertscripts/ 必须拥有执行权限,并且改变所属用户和组 要修改此脚本的路径,需 ...
- 【CF696B】Puzzles(树形DP,期望)
题意:n 个节点的树,初始位置为 1 号节点,初始时间为 1.每次随机地走向任何一个没有走过的子树并且令时间 +1求问走到每一个点时的时间的期望值 思路:比较少见的一道自顶向下的树形DP dp[i]表 ...
- UML系列,使用UML实现GOF Design patterns,常用模式类图解读
1.单例:Singleton, DirectedAssociation
- ubuntu 为firefox 安装flash_player
1.下载安装包install_flash_player_11_linux.i386.tar.gz: 2.解压文件:$ tar -xvf install_flash_player_11_linux.i3 ...
- 手機 停充的種類 與 量測 power consumption 功率 使用 bq25896 bq25890
Precondition : 配有 power path 功能的 BQ2589 手機. 接上 pc usb port. Origin : 今天有同事問我, 手機是否可以在接上 pc usb port ...