~jconti/recent-notifications/trunk

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
"""
LogWatcher.py
by Jason Conti
February 15, 2010

Watches a log file for changes.

Adapted from Watcher.py in the deskbar applet.
"""

import gio
import glib
import gobject
import gtk
import os.path

class LogWatcher(gobject.GObject):
  """Tracks a log file for changes."""
  __gsignals__ = {
      "changed": (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, [gobject.TYPE_STRING])
  }
  def __init__(self, path):
    gobject.GObject.__init__(self)

    self._path = os.path.abspath(path)
    self._offset = self.get_file_length()
    self._watcher = None

  def start(self):
    """Starts watching the file."""
    gfile = gio.File(path=self._path)
    self._watcher = gfile.monitor_file()
    self._watcher.connect("changed", self.on_changed)

  def stop(self):
    """Removes the watch from the tracked file and stops the notifier."""
    if self._watcher != None:
      self._watcher.cancel()
      del self._watcher
      self._watcher = None

  def get_file_length(self):
    """Returns the length of the tracked file, returns 0 if there is an error,
    assuming that the file may not have been created yet."""
    try:
      f = open(self._path, "r")
      f.seek(0, os.SEEK_END)
      size = f.tell()
      f.close()
      return size
    except:
      return 0

  def read_appended_text(self):
    """Opens the tracked file, seeks to the last read offset, reads to EOF
    and updates the last read offset."""
    f = open(self._path, "r")
    f.seek(self._offset, os.SEEK_SET)
    text = f.read()
    self._offset = f.tell()
    f.close()
    return text

  def on_changed(self, monitor, file, other_file, event_type):
    """Reads the appended text in the tracked file and sends it to the listeners."""
    text = self.read_appended_text()
    if event_type == gio.FILE_MONITOR_EVENT_CHANGED:
      glib.idle_add(self.emit, "changed", text)
      

if gtk.pygtk_version < (2, 8, 0):
  gobject.type_register(LogWatcher)