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 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167
|
#!/usr/bin/env python2
# Terminator by Chris Jones <cmsj@tenshu.net>
# GPL v2 only
"""activitywatch.py - Terminator Plugin to watch a terminal for activity"""
import time
import gi
from gi.repository import Gtk
from gi.repository import GObject
from terminatorlib.config import Config
import terminatorlib.plugin as plugin
from terminatorlib.translation import _
from terminatorlib.util import err, dbg
from terminatorlib.version import APP_NAME
try:
gi.require_version('Notify', '0.7')
from gi.repository import Notify
# Every plugin you want Terminator to load *must* be listed in 'AVAILABLE'
# This is inside this try so we only make the plugin available if pynotify
# is present on this computer.
AVAILABLE = ['ActivityWatch', 'InactivityWatch']
except (ImportError, ValueError):
err('ActivityWatch plugin unavailable as we cannot import Notify')
config = Config()
inactive_period = float(config.plugin_get('InactivityWatch', 'inactive_period',
10.0))
watch_interval = int(config.plugin_get('InactivityWatch', 'watch_interval',
5000))
hush_period = float(config.plugin_get('ActivityWatch', 'hush_period',
10.0))
class ActivityWatch(plugin.MenuItem):
"""Add custom commands to the terminal menu"""
capabilities = ['terminal_menu']
watches = None
last_notifies = None
timers = None
def __init__(self):
plugin.MenuItem.__init__(self)
if not self.watches:
self.watches = {}
if not self.last_notifies:
self.last_notifies = {}
if not self.timers:
self.timers = {}
Notify.init(APP_NAME.capitalize())
def callback(self, menuitems, menu, terminal):
"""Add our menu item to the menu"""
item = Gtk.CheckMenuItem.new_with_mnemonic(_('Watch for _activity'))
item.set_active(terminal in self.watches)
if item.get_active():
item.connect("activate", self.unwatch, terminal)
else:
item.connect("activate", self.watch, terminal)
menuitems.append(item)
dbg('Menu item appended')
def watch(self, _widget, terminal):
"""Watch a terminal"""
vte = terminal.get_vte()
self.watches[terminal] = vte.connect('contents-changed',
self.notify, terminal)
def unwatch(self, _widget, terminal):
"""Stop watching a terminal"""
vte = terminal.get_vte()
vte.disconnect(self.watches[terminal])
del(self.watches[terminal])
def notify(self, _vte, terminal):
"""Notify that a terminal did something"""
show_notify = False
# Don't notify if the user is already looking at this terminal.
if terminal.vte.has_focus():
return True
note = Notify.Notification.new(_('Terminator'), _('Activity in: %s') %
terminal.get_window_title(), 'terminator')
this_time = time.mktime(time.gmtime())
if terminal not in self.last_notifies:
show_notify = True
else:
last_time = self.last_notifies[terminal]
if this_time - last_time > hush_period:
show_notify = True
if show_notify == True:
note.show()
self.last_notifies[terminal] = this_time
return True
class InactivityWatch(plugin.MenuItem):
"""Add custom commands to notify when a terminal goes inactive"""
capabilities = ['terminal_menu']
watches = None
last_activities = None
timers = None
def __init__(self):
plugin.MenuItem.__init__(self)
if not self.watches:
self.watches = {}
if not self.last_activities:
self.last_activities = {}
if not self.timers:
self.timers = {}
Notify.init(APP_NAME.capitalize())
def callback(self, menuitems, menu, terminal):
"""Add our menu item to the menu"""
item = Gtk.CheckMenuItem.new_with_mnemonic(_("Watch for _silence"))
item.set_active(terminal in self.watches)
if item.get_active():
item.connect("activate", self.unwatch, terminal)
else:
item.connect("activate", self.watch, terminal)
menuitems.append(item)
dbg('Menu items appended')
def watch(self, _widget, terminal):
"""Watch a terminal"""
vte = terminal.get_vte()
self.watches[terminal] = vte.connect('contents-changed',
self.reset_timer, terminal)
timeout_id = GObject.timeout_add(watch_interval, self.check_times, terminal)
self.timers[terminal] = timeout_id
dbg('timer %s added for %s' %(timeout_id, terminal))
def unwatch(self, _vte, terminal):
"""Unwatch a terminal"""
vte = terminal.get_vte()
vte.disconnect(self.watches[terminal])
del(self.watches[terminal])
GObject.source_remove(self.timers[terminal])
del(self.timers[terminal])
def reset_timer(self, _vte, terminal):
"""Reset the last-changed time for a terminal"""
time_now = time.mktime(time.gmtime())
self.last_activities[terminal] = time_now
dbg('reset activity time for %s' % terminal)
def check_times(self, terminal):
"""Check if this terminal has gone silent"""
time_now = time.mktime(time.gmtime())
if terminal not in self.last_activities:
dbg('Terminal %s has no last activity' % terminal)
return True
dbg('seconds since last activity: %f (%s)' % (time_now - self.last_activities[terminal], terminal))
if time_now - self.last_activities[terminal] >= inactive_period:
del(self.last_activities[terminal])
note = Notify.Notification.new(_('Terminator'), _('Silence in: %s') %
terminal.get_window_title(), 'terminator')
note.show()
return True
|