2010-06-15 13:59:27 +00:00
|
|
|
# Terminator by Chris Jones <cmsj@tenshu.net>
|
|
|
|
# GPL v2 only
|
|
|
|
"""activitywatch.py - Terminator Plugin to watch a terminal for activity"""
|
|
|
|
|
|
|
|
import time
|
2015-11-28 17:56:02 +00:00
|
|
|
import gi
|
2014-09-19 14:08:08 +00:00
|
|
|
from gi.repository import Gtk
|
|
|
|
from gi.repository import GObject
|
2010-06-15 13:59:27 +00:00
|
|
|
|
2015-02-25 23:02:09 +00:00
|
|
|
from terminatorlib.config import Config
|
2010-06-15 13:59:27 +00:00
|
|
|
import terminatorlib.plugin as plugin
|
|
|
|
from terminatorlib.translation import _
|
2011-08-20 23:15:14 +00:00
|
|
|
from terminatorlib.util import err, dbg
|
2010-06-15 13:59:27 +00:00
|
|
|
from terminatorlib.version import APP_NAME
|
|
|
|
|
|
|
|
try:
|
2015-11-28 17:56:02 +00:00
|
|
|
gi.require_version('Notify', '0.7')
|
2014-09-19 14:08:08 +00:00
|
|
|
from gi.repository import Notify
|
2010-06-15 13:59:27 +00:00
|
|
|
# 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.
|
2011-08-20 23:15:14 +00:00
|
|
|
AVAILABLE = ['ActivityWatch', 'InactivityWatch']
|
2017-02-07 16:09:34 +00:00
|
|
|
except (ImportError, ValueError):
|
|
|
|
err('ActivityWatch plugin unavailable as we cannot import Notify')
|
2010-06-15 13:59:27 +00:00
|
|
|
|
2015-02-25 23:02:09 +00:00
|
|
|
config = Config()
|
2015-08-03 18:36:14 +00:00
|
|
|
inactive_period = float(config.plugin_get('InactivityWatch', 'inactive_period',
|
2015-02-25 23:02:09 +00:00
|
|
|
10.0))
|
2015-08-03 18:36:14 +00:00
|
|
|
watch_interval = int(config.plugin_get('InactivityWatch', 'watch_interval',
|
2015-02-25 23:02:09 +00:00
|
|
|
5000))
|
2015-08-03 18:36:14 +00:00
|
|
|
hush_period = float(config.plugin_get('ActivityWatch', 'hush_period',
|
|
|
|
10.0))
|
2015-02-25 23:02:09 +00:00
|
|
|
|
2010-06-15 13:59:27 +00:00
|
|
|
class ActivityWatch(plugin.MenuItem):
|
|
|
|
"""Add custom commands to the terminal menu"""
|
|
|
|
capabilities = ['terminal_menu']
|
|
|
|
watches = None
|
|
|
|
last_notifies = None
|
2011-08-20 23:15:14 +00:00
|
|
|
timers = None
|
2010-06-15 13:59:27 +00:00
|
|
|
|
|
|
|
def __init__(self):
|
|
|
|
plugin.MenuItem.__init__(self)
|
|
|
|
if not self.watches:
|
|
|
|
self.watches = {}
|
|
|
|
if not self.last_notifies:
|
|
|
|
self.last_notifies = {}
|
2011-08-20 23:15:14 +00:00
|
|
|
if not self.timers:
|
|
|
|
self.timers = {}
|
2010-06-15 13:59:27 +00:00
|
|
|
|
2014-09-19 14:08:08 +00:00
|
|
|
Notify.init(APP_NAME.capitalize())
|
2010-06-15 13:59:27 +00:00
|
|
|
|
|
|
|
def callback(self, menuitems, menu, terminal):
|
2015-02-25 23:02:09 +00:00
|
|
|
"""Add our menu item to the menu"""
|
2015-08-04 01:17:05 +00:00
|
|
|
item = Gtk.CheckMenuItem.new_with_mnemonic(_('Watch for _activity'))
|
2018-04-24 18:22:10 +00:00
|
|
|
item.set_active(terminal in self.watches)
|
2015-02-25 23:02:09 +00:00
|
|
|
if item.get_active():
|
2010-06-15 13:59:27 +00:00
|
|
|
item.connect("activate", self.unwatch, terminal)
|
2015-02-25 23:02:09 +00:00
|
|
|
else:
|
|
|
|
item.connect("activate", self.watch, terminal)
|
2010-06-15 13:59:27 +00:00
|
|
|
menuitems.append(item)
|
2015-02-25 23:02:09 +00:00
|
|
|
dbg('Menu item appended')
|
2010-06-15 13:59:27 +00:00
|
|
|
|
|
|
|
def watch(self, _widget, terminal):
|
|
|
|
"""Watch a terminal"""
|
|
|
|
vte = terminal.get_vte()
|
2015-02-25 23:02:09 +00:00
|
|
|
self.watches[terminal] = vte.connect('contents-changed',
|
2010-06-15 13:59:27 +00:00
|
|
|
self.notify, terminal)
|
|
|
|
|
|
|
|
def unwatch(self, _widget, terminal):
|
|
|
|
"""Stop watching a terminal"""
|
|
|
|
vte = terminal.get_vte()
|
2015-02-25 23:02:09 +00:00
|
|
|
vte.disconnect(self.watches[terminal])
|
2010-06-15 13:59:27 +00:00
|
|
|
del(self.watches[terminal])
|
|
|
|
|
|
|
|
def notify(self, _vte, terminal):
|
|
|
|
"""Notify that a terminal did something"""
|
|
|
|
show_notify = False
|
|
|
|
|
2011-08-21 00:43:51 +00:00
|
|
|
# Don't notify if the user is already looking at this terminal.
|
2015-02-25 23:02:09 +00:00
|
|
|
if terminal.vte.has_focus():
|
2011-08-21 00:43:51 +00:00
|
|
|
return True
|
|
|
|
|
2015-08-04 01:17:05 +00:00
|
|
|
note = Notify.Notification.new(_('Terminator'), _('Activity in: %s') %
|
2010-06-15 13:59:27 +00:00
|
|
|
terminal.get_window_title(), 'terminator')
|
|
|
|
|
|
|
|
this_time = time.mktime(time.gmtime())
|
2018-04-24 18:22:10 +00:00
|
|
|
if terminal not in self.last_notifies:
|
2010-06-15 13:59:27 +00:00
|
|
|
show_notify = True
|
|
|
|
else:
|
|
|
|
last_time = self.last_notifies[terminal]
|
2015-08-03 18:36:14 +00:00
|
|
|
if this_time - last_time > hush_period:
|
2010-06-15 13:59:27 +00:00
|
|
|
show_notify = True
|
|
|
|
|
|
|
|
if show_notify == True:
|
|
|
|
note.show()
|
|
|
|
self.last_notifies[terminal] = this_time
|
|
|
|
|
2011-08-21 00:43:51 +00:00
|
|
|
return True
|
2011-08-20 23:15:14 +00:00
|
|
|
|
|
|
|
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 = {}
|
|
|
|
|
2014-09-19 14:08:08 +00:00
|
|
|
Notify.init(APP_NAME.capitalize())
|
2011-08-20 23:15:14 +00:00
|
|
|
|
|
|
|
def callback(self, menuitems, menu, terminal):
|
2015-02-25 23:02:09 +00:00
|
|
|
"""Add our menu item to the menu"""
|
2015-08-04 01:17:05 +00:00
|
|
|
item = Gtk.CheckMenuItem.new_with_mnemonic(_("Watch for _silence"))
|
2018-04-24 18:22:10 +00:00
|
|
|
item.set_active(terminal in self.watches)
|
2015-02-25 23:02:09 +00:00
|
|
|
if item.get_active():
|
2011-08-20 23:15:14 +00:00
|
|
|
item.connect("activate", self.unwatch, terminal)
|
2015-02-25 23:02:09 +00:00
|
|
|
else:
|
|
|
|
item.connect("activate", self.watch, terminal)
|
2011-08-20 23:15:14 +00:00
|
|
|
menuitems.append(item)
|
|
|
|
dbg('Menu items appended')
|
|
|
|
|
|
|
|
def watch(self, _widget, terminal):
|
|
|
|
"""Watch a terminal"""
|
|
|
|
vte = terminal.get_vte()
|
2015-02-25 23:02:09 +00:00
|
|
|
self.watches[terminal] = vte.connect('contents-changed',
|
2011-08-20 23:15:14 +00:00
|
|
|
self.reset_timer, terminal)
|
2015-02-25 23:02:09 +00:00
|
|
|
timeout_id = GObject.timeout_add(watch_interval, self.check_times, terminal)
|
2011-08-20 23:15:14 +00:00
|
|
|
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()
|
2015-02-25 23:02:09 +00:00
|
|
|
vte.disconnect(self.watches[terminal])
|
2011-08-20 23:15:14 +00:00
|
|
|
del(self.watches[terminal])
|
2014-09-19 14:08:08 +00:00
|
|
|
GObject.source_remove(self.timers[terminal])
|
2011-08-20 23:15:14 +00:00
|
|
|
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())
|
2018-04-24 18:22:10 +00:00
|
|
|
if terminal not in self.last_activities:
|
2011-08-20 23:15:14 +00:00
|
|
|
dbg('Terminal %s has no last activity' % terminal)
|
|
|
|
return True
|
|
|
|
|
|
|
|
dbg('seconds since last activity: %f (%s)' % (time_now - self.last_activities[terminal], terminal))
|
2015-02-25 23:02:09 +00:00
|
|
|
if time_now - self.last_activities[terminal] >= inactive_period:
|
2011-08-20 23:15:14 +00:00
|
|
|
del(self.last_activities[terminal])
|
2015-08-04 01:17:05 +00:00
|
|
|
note = Notify.Notification.new(_('Terminator'), _('Silence in: %s') %
|
2011-08-20 23:15:14 +00:00
|
|
|
terminal.get_window_title(), 'terminator')
|
|
|
|
note.show()
|
|
|
|
|
|
|
|
return True
|