summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastien Martini <seb@dbzteam.org>2010-07-27 15:04:21 +0200
committerSebastien Martini <seb@dbzteam.org>2010-07-27 15:04:21 +0200
commit817169ec933de0eaf0d98793ade01a89aabcc4ce (patch)
treec9400c3440eb1bc0aea1c8e9156b331ec466ea71
parent3c136cf7123099d4b513d364b0929b5321225a8c (diff)
downloadpyinotify-817169ec933de0eaf0d98793ade01a89aabcc4ce.tar.gz
Added new option --raw-format (-f) to explicitly disable the
enhanced output format when Pyinotify is used from command line (idea submitted by hv@tbz-pariv.de).
-rwxr-xr-xpython2/pyinotify.py161
-rwxr-xr-xpython3/pyinotify.py158
2 files changed, 173 insertions, 146 deletions
diff --git a/python2/pyinotify.py b/python2/pyinotify.py
index 8e67993..2bf9aea 100755
--- a/python2/pyinotify.py
+++ b/python2/pyinotify.py
@@ -103,16 +103,16 @@ COMPATIBILITY_MODE = False
# Load libc
LIBC = None
-STRERRNO = None
+strerrno = None
if sys.version_info[0] >= 2 and sys.version_info[1] >= 6:
LIBC = ctypes.CDLL(ctypes.util.find_library('c'), use_errno=True)
def _strerrno():
code = ctypes.get_errno()
return ' Errno=%s (%s)' % (os.strerror(code), errno.errorcode[code])
- STRERRNO = _strerrno
+ strerrno = _strerrno
else:
LIBC = ctypes.CDLL(ctypes.util.find_library('c'))
- STRERRNO = lambda : ''
+ strerrno = lambda : ''
# Check that libc has needed functions inside.
@@ -416,16 +416,19 @@ class _Event:
value = hex(getattr(self, attr))
elif isinstance(value, basestring) and not value:
value = "''"
- s += ' %s%s%s' % (Color.field_name(attr),
- Color.punctuation('='),
- Color.field_value(value))
+ s += ' %s%s%s' % (output_format.field_name(attr),
+ output_format.punctuation('='),
+ output_format.field_value(value))
- s = '%s%s%s %s' % (Color.punctuation('<'),
- Color.class_name(self.__class__.__name__),
+ s = '%s%s%s %s' % (output_format.punctuation('<'),
+ output_format.class_name(self.__class__.__name__),
s,
- Color.punctuation('>'))
+ output_format.punctuation('>'))
return s
+ def __str__(self):
+ return repr(self)
+
class _RawEvent(_Event):
"""
@@ -446,19 +449,20 @@ class _RawEvent(_Event):
on the watched item itself.
@type name: string or None
"""
- # name: remove trailing '\0'
- _Event.__init__(self, {'wd': wd,
- 'mask': mask,
- 'cookie': cookie,
- 'name': name.rstrip('\0')})
- log.debug(repr(self))
- # Use this variable to cache the result of str(self)
+ # Use this variable to cache the result of str(self), this object
+ # is immutable.
self._str = None
+ # name: remove trailing '\0'
+ d = {'wd': wd,
+ 'mask': mask,
+ 'cookie': cookie,
+ 'name': name.rstrip('\0')}
+ _Event.__init__(self, d)
+ log.debug(str(self))
def __str__(self):
if self._str is None:
- self._str = '%s %s %s %s' % (str(self.wd), str(self.mask),
- str(self.cookie), self.name)
+ self._str = _Event.__str__(self)
return self._str
@@ -876,7 +880,7 @@ class PrintAllEvents(ProcessEvent):
IN_Q_OVERFLOW events (see method process_IN_Q_OVERFLOW).
@type event: Event instance
"""
- self._out.write(repr(event))
+ self._out.write(str(event))
self._out.write('\n')
@@ -944,9 +948,9 @@ class Stats(ProcessEvent):
l = []
for ev, value in sorted(stats.items(), key=lambda x: x[0]):
- l.append(' %s=%s' % (Color.field_name(ev),
- Color.field_value(value)))
- s = '<%s%s >' % (Color.class_name(self.__class__.__name__),
+ l.append(' %s=%s' % (output_format.field_name(ev),
+ output_format.field_value(value)))
+ s = '<%s%s >' % (output_format.class_name(self.__class__.__name__),
''.join(l))
return s
@@ -970,12 +974,12 @@ class Stats(ProcessEvent):
m = max(stats.values())
unity = float(scale) / m
- fmt = '%%-26s%%-%ds%%s' % (len(Color.field_value('@' * scale))
+ fmt = '%%-26s%%-%ds%%s' % (len(output_format.field_value('@' * scale))
+ 1)
def func(x):
- return fmt % (Color.field_name(x[0]),
- Color.field_value('@' * int(x[1] * unity)),
- Color.simple('%d' % x[1], 'yellow'))
+ return fmt % (output_format.field_name(x[0]),
+ output_format.field_value('@' * int(x[1] * unity)),
+ output_format.simple('%d' % x[1], 'yellow'))
s = '\n'.join(map(func, sorted(stats.items(), key=lambda x: x[0])))
return s
@@ -1473,15 +1477,16 @@ class Watch:
@return: String representation.
@rtype: str
"""
- s = ' '.join(['%s%s%s' % (Color.field_name(attr),
- Color.punctuation('='),
- Color.field_value(getattr(self, attr))) \
+ s = ' '.join(['%s%s%s' % (output_format.field_name(attr),
+ output_format.punctuation('='),
+ output_format.field_value(getattr(self,
+ attr))) \
for attr in self.__dict__ if not attr.startswith('_')])
- s = '%s%s %s %s' % (Color.punctuation('<'),
- Color.class_name(self.__class__.__name__),
+ s = '%s%s %s %s' % (output_format.punctuation('<'),
+ output_format.class_name(self.__class__.__name__),
s,
- Color.punctuation('>'))
+ output_format.punctuation('>'))
return s
@@ -1585,7 +1590,7 @@ class WatchManager:
self._wmd = {} # watch dict key: watch descriptor, value: watch
self._fd = LIBC.inotify_init() # inotify's init, file descriptor
if self._fd < 0:
- err = 'Cannot initialize new instance of inotify%s' % STRERRNO()
+ err = 'Cannot initialize new instance of inotify%s' % strerrno()
raise OSError(err)
def get_fd(self):
@@ -1736,7 +1741,7 @@ class WatchManager:
exclude_filter)
if wd < 0:
err = 'add_watch: cannot watch %s WD=%d%s'
- err = err % (rpath, wd, STRERRNO())
+ err = err % (rpath, wd, strerrno())
if quiet:
log.error(err)
else:
@@ -1832,7 +1837,7 @@ class WatchManager:
if wd_ < 0:
ret_[awd] = False
err = 'update_watch: cannot update %s WD=%d%s'
- err = err % (apath, wd_, STRERRNO())
+ err = err % (apath, wd_, strerrno())
if quiet:
log.error(err)
continue
@@ -1941,7 +1946,7 @@ class WatchManager:
wd_ = LIBC.inotify_rm_watch(self._fd, awd)
if wd_ < 0:
ret_[awd] = False
- err = 'rm_watch: cannot remove WD=%d%s' % (awd, STRERRNO())
+ err = 'rm_watch: cannot remove WD=%d%s' % (awd, strerrno())
if quiet:
log.error(err)
continue
@@ -1994,54 +1999,55 @@ class WatchManager:
exclude_filter=lambda path: False)
-class Color:
+class RawOutputFormat:
"""
- Internal class. Provide fancy colors used by string representations.
+ Format string representations.
"""
- normal = "\033[0m"
- black = "\033[30m"
- red = "\033[31m"
- green = "\033[32m"
- yellow = "\033[33m"
- blue = "\033[34m"
- purple = "\033[35m"
- cyan = "\033[36m"
- bold = "\033[1m"
- uline = "\033[4m"
- blink = "\033[5m"
- invert = "\033[7m"
-
- @staticmethod
- def punctuation(s):
+ def __init__(self, format=None):
+ self.format = format or {}
+
+ def simple(self, s, attribute):
+ if not isinstance(s, str):
+ s = str(s)
+ return (self.format.get(attribute, '') + s +
+ self.format.get('normal', ''))
+
+ def punctuation(self, s):
"""Punctuation color."""
- return Color.normal + s + Color.normal
+ return self.simple(s, 'normal')
- @staticmethod
- def field_value(s):
+ def field_value(self, s):
"""Field value color."""
- if not isinstance(s, basestring):
- s = str(s)
- return Color.purple + s + Color.normal
+ return self.simple(s, 'purple')
- @staticmethod
- def field_name(s):
+ def field_name(self, s):
"""Field name color."""
- return Color.blue + s + Color.normal
+ return self.simple(s, 'blue')
- @staticmethod
- def class_name(s):
+ def class_name(self, s):
"""Class name color."""
- return Color.red + Color.bold + s + Color.normal
+ return self.format.get('red', '') + self.simple(s, 'bold')
- @staticmethod
- def simple(s, color):
- if not isinstance(s, basestring):
- s = str(s)
- try:
- color_attr = getattr(Color, color)
- except AttributeError:
- return s
- return color_attr + s + Color.normal
+output_format = RawOutputFormat()
+
+class ColoredOutputFormat(RawOutputFormat):
+ """
+ Format colored string representations.
+ """
+ def __init__(self):
+ f = {'normal': '\033[0m',
+ 'black': '\033[30m',
+ 'red': '\033[31m',
+ 'green': '\033[32m',
+ 'yellow': '\033[33m',
+ 'blue': '\033[34m',
+ 'purple': '\033[35m',
+ 'cyan': '\033[36m',
+ 'bold': '\033[1m',
+ 'uline': '\033[4m',
+ 'blink': '\033[5m',
+ 'invert': '\033[7m'}
+ RawOutputFormat.__init__(self, f)
def compatibility_mode():
@@ -2089,6 +2095,9 @@ def command_line():
help="Display dummy statistics")
parser.add_option("-V", "--version", action="store_true",
dest="version", help="Pyinotify version")
+ parser.add_option("-f", "--raw-format", action="store_true",
+ dest="raw_format",
+ help="Disable enhanced output format.")
(options, args) = parser.parse_args()
@@ -2098,6 +2107,10 @@ def command_line():
if options.version:
print(__version__)
+ if not options.raw_format:
+ global output_format
+ output_format = ColoredOutputFormat()
+
if len(args) < 1:
path = '/tmp' # default watched path
else:
diff --git a/python3/pyinotify.py b/python3/pyinotify.py
index 752b76e..2d8fa03 100755
--- a/python3/pyinotify.py
+++ b/python3/pyinotify.py
@@ -102,7 +102,7 @@ COMPATIBILITY_MODE = False
# Load libc
LIBC = ctypes.CDLL(ctypes.util.find_library('c'), use_errno=True)
-def STRERRNO():
+def strerrno():
code = ctypes.get_errno()
return '%s (%s)' % (os.strerror(code), errno.errorcode[code])
@@ -371,16 +371,19 @@ class _Event:
value = hex(getattr(self, attr))
elif isinstance(value, str) and not value:
value = "''"
- s += ' %s%s%s' % (Color.field_name(attr),
- Color.punctuation('='),
- Color.field_value(value))
+ s += ' %s%s%s' % (output_format.field_name(attr),
+ output_format.punctuation('='),
+ output_format.field_value(value))
- s = '%s%s%s %s' % (Color.punctuation('<'),
- Color.class_name(self.__class__.__name__),
+ s = '%s%s%s %s' % (output_format.punctuation('<'),
+ output_format.class_name(self.__class__.__name__),
s,
- Color.punctuation('>'))
+ output_format.punctuation('>'))
return s
+ def __str__(self):
+ return repr(self)
+
class _RawEvent(_Event):
"""
@@ -401,19 +404,20 @@ class _RawEvent(_Event):
on the watched item itself.
@type name: string or None
"""
- # name: remove trailing '\0'
- _Event.__init__(self, {'wd': wd,
- 'mask': mask,
- 'cookie': cookie,
- 'name': name.rstrip('\0')})
- log.debug(repr(self))
- # Use this variable to cache the result of str(self)
+ # Use this variable to cache the result of str(self), this object
+ # is immutable.
self._str = None
+ # name: remove trailing '\0'
+ d = {'wd': wd,
+ 'mask': mask,
+ 'cookie': cookie,
+ 'name': name.rstrip('\0')}
+ _Event.__init__(self, d)
+ log.debug(str(self))
def __str__(self):
if self._str is None:
- self._str = '%s %s %s %s' % (str(self.wd), str(self.mask),
- str(self.cookie), self.name)
+ self._str = _Event.__str__(self)
return self._str
@@ -831,7 +835,7 @@ class PrintAllEvents(ProcessEvent):
IN_Q_OVERFLOW events (see method process_IN_Q_OVERFLOW).
@type event: Event instance
"""
- self._out.write(repr(event))
+ self._out.write(str(event))
self._out.write('\n')
@@ -899,9 +903,9 @@ class Stats(ProcessEvent):
l = []
for ev, value in sorted(stats.items(), key=lambda x: x[0]):
- l.append(' %s=%s' % (Color.field_name(ev),
- Color.field_value(value)))
- s = '<%s%s >' % (Color.class_name(self.__class__.__name__),
+ l.append(' %s=%s' % (output_format.field_name(ev),
+ output_format.field_value(value)))
+ s = '<%s%s >' % (output_format.class_name(self.__class__.__name__),
''.join(l))
return s
@@ -922,12 +926,12 @@ class Stats(ProcessEvent):
m = max(stats.values())
unity = scale / m
- fmt = '%%-26s%%-%ds%%s' % (len(Color.field_value('@' * scale))
+ fmt = '%%-26s%%-%ds%%s' % (len(output_format.field_value('@' * scale))
+ 1)
def func(x):
- return fmt % (Color.field_name(x[0]),
- Color.field_value('@' * int(x[1] * unity)),
- Color.simple('%d' % x[1], 'yellow'))
+ return fmt % (output_format.field_name(x[0]),
+ output_format.field_value('@' * int(x[1] * unity)),
+ output_format.simple('%d' % x[1], 'yellow'))
s = '\n'.join(map(func, sorted(stats.items(), key=lambda x: x[0])))
return s
@@ -1421,15 +1425,16 @@ class Watch:
@return: String representation.
@rtype: str
"""
- s = ' '.join(['%s%s%s' % (Color.field_name(attr),
- Color.punctuation('='),
- Color.field_value(getattr(self, attr))) \
+ s = ' '.join(['%s%s%s' % (output_format.field_name(attr),
+ output_format.punctuation('='),
+ output_format.field_value(getattr(self,
+ attr))) \
for attr in self.__dict__ if not attr.startswith('_')])
- s = '%s%s %s %s' % (Color.punctuation('<'),
- Color.class_name(self.__class__.__name__),
+ s = '%s%s %s %s' % (output_format.punctuation('<'),
+ output_format.class_name(self.__class__.__name__),
s,
- Color.punctuation('>'))
+ output_format.punctuation('>'))
return s
@@ -1531,7 +1536,7 @@ class WatchManager:
self._fd = LIBC.inotify_init() # inotify's init, file descriptor
if self._fd < 0:
err = 'Cannot initialize new instance of inotify Errno=%s'
- raise OSError(err % STRERRNO())
+ raise OSError(err % strerrno())
def get_fd(self):
"""
@@ -1684,7 +1689,7 @@ class WatchManager:
exclude_filter)
if wd < 0:
err = 'add_watch: cannot watch %s WD=%d Errno=%s'
- err = err % (rpath, wd, STRERRNO())
+ err = err % (rpath, wd, strerrno())
if quiet:
log.error(err)
else:
@@ -1784,7 +1789,7 @@ class WatchManager:
if wd_ < 0:
ret_[awd] = False
err = 'update_watch: cannot update %s WD=%d Errno=%s'
- err = err % (apath, wd_, STRERRNO())
+ err = err % (apath, wd_, strerrno())
if quiet:
log.error(err)
continue
@@ -1893,7 +1898,8 @@ class WatchManager:
wd_ = LIBC.inotify_rm_watch(self._fd, awd)
if wd_ < 0:
ret_[awd] = False
- err = 'rm_watch: cannot remove WD=%d Errno=%s' % (awd, STRERRNO())
+ err = 'rm_watch: cannot remove WD=%d Errno=%s' % (awd,
+ strerrno())
if quiet:
log.error(err)
continue
@@ -1946,54 +1952,55 @@ class WatchManager:
exclude_filter=lambda path: False)
-class Color:
+class RawOutputFormat:
"""
- Internal class. Provide fancy colors used by string representations.
+ Format string representations.
"""
- normal = "\033[0m"
- black = "\033[30m"
- red = "\033[31m"
- green = "\033[32m"
- yellow = "\033[33m"
- blue = "\033[34m"
- purple = "\033[35m"
- cyan = "\033[36m"
- bold = "\033[1m"
- uline = "\033[4m"
- blink = "\033[5m"
- invert = "\033[7m"
-
- @staticmethod
- def punctuation(s):
- """Punctuation color."""
- return Color.normal + s + Color.normal
+ def __init__(self, format=None):
+ self.format = format or {}
- @staticmethod
- def field_value(s):
- """Field value color."""
+ def simple(self, s, attribute):
if not isinstance(s, str):
s = str(s)
- return Color.purple + s + Color.normal
+ return (self.format.get(attribute, '') + s +
+ self.format.get('normal', ''))
+
+ def punctuation(self, s):
+ """Punctuation color."""
+ return self.simple(s, 'normal')
+
+ def field_value(self, s):
+ """Field value color."""
+ return self.simple(s, 'purple')
- @staticmethod
- def field_name(s):
+ def field_name(self, s):
"""Field name color."""
- return Color.blue + s + Color.normal
+ return self.simple(s, 'blue')
- @staticmethod
- def class_name(s):
+ def class_name(self, s):
"""Class name color."""
- return Color.red + Color.bold + s + Color.normal
+ return self.format.get('red', '') + self.simple(s, 'bold')
- @staticmethod
- def simple(s, color):
- if not isinstance(s, str):
- s = str(s)
- try:
- color_attr = getattr(Color, color)
- except AttributeError:
- return s
- return color_attr + s + Color.normal
+output_format = RawOutputFormat()
+
+class ColoredOutputFormat(RawOutputFormat):
+ """
+ Format colored string representations.
+ """
+ def __init__(self):
+ f = {'normal': '\033[0m',
+ 'black': '\033[30m',
+ 'red': '\033[31m',
+ 'green': '\033[32m',
+ 'yellow': '\033[33m',
+ 'blue': '\033[34m',
+ 'purple': '\033[35m',
+ 'cyan': '\033[36m',
+ 'bold': '\033[1m',
+ 'uline': '\033[4m',
+ 'blink': '\033[5m',
+ 'invert': '\033[7m'}
+ RawOutputFormat.__init__(self, f)
def compatibility_mode():
@@ -2041,6 +2048,9 @@ def command_line():
help="Display dummy statistics")
parser.add_option("-V", "--version", action="store_true",
dest="version", help="Pyinotify version")
+ parser.add_option("-f", "--raw-format", action="store_true",
+ dest="raw_format",
+ help="Disable enhanced output format.")
(options, args) = parser.parse_args()
@@ -2050,6 +2060,10 @@ def command_line():
if options.version:
print(__version__)
+ if not options.raw_format:
+ global output_format
+ output_format = ColoredOutputFormat()
+
if len(args) < 1:
path = '/tmp' # default watched path
else: