Ubuntu: How would I make a simple indicator program to record timestamps?



Question:

I would like to make a button to sit up next to my sound/wireless/etc indicators which, when toggled, will change color and write the system time with the word "begin" to a file, then, when toggled again, return to its original color and record the system time with the word "end." Ideally, the button would maintain it's toggled/untoggled state even if the system restarts.

I can't imagine this would be a difficult program to make at all, but I am a bit new to Ubuntu and I'm not sure how to make a program work as an indicator, or how to make something maintain its state on system restart.


Solution:1

I got interested so here is my Python code:

#!/usr/bin/python    from time import time, ctime  from gi.repository import Gtk  from gi.repository import AppIndicator3 as Indicator      MY_FILENAME = '/home/your-username/myfile.log'  MY_INDICATOR_ID = 'my-indicator-example'  STOP_ICON_NAME = 'indicator-messages'  START_ICON_NAME = 'indicator-messages-new'    class MyIndicator(object):        def __init__(self, filename):          self.indicator = Indicator.Indicator.new(                                  MY_INDICATOR_ID,                                  STOP_ICON_NAME,                                  Indicator.IndicatorCategory.APPLICATION_STATUS)            self.indicator.set_status(Indicator.IndicatorStatus.ACTIVE)          self.indicator.set_attention_icon(START_ICON_NAME)            self.has_started = False            self.menu = Gtk.Menu()            start_item = Gtk.MenuItem('Start')          start_item.connect('activate', self.start_activated, filename)          self.menu.append(start_item)          start_item.show()            stop_item = Gtk.MenuItem('Stop')          stop_item.connect('activate', self.stop_activated, filename)          self.menu.append(stop_item)          stop_item.show()            self.indicator.set_menu(self.menu)        def main(self):          Gtk.main()        def start_activated (self, menu_item, filename):          if not self.has_started:              myfile = open(filename, 'a')              myfile.write('Start  <%s>\n' % ctime(time()))              self.indicator.set_status(Indicator.IndicatorStatus.ATTENTION)              self.has_started = True        def stop_activated (self, menu_item, filename):          if self.has_started:              myfile = open(filename, 'a')              myfile.write('End    <%s>\n' % ctime(time()))              self.indicator.set_status(Indicator.IndicatorStatus.ACTIVE)              self.has_started = False      if __name__ == '__main__':      indicator = MyIndicator(MY_FILENAME)      indicator.main()  

I used the info given by gpaste-indicator and the Ubuntu Wiki. I'm not sure about the "keeping the state between restarts" feature, the simplest would be to read the last line of myfile.log and setting self.has_started accordingly. Good luck.


Solution:2

I was able to modify and improve the code from edwin's very helpful answer so that the app does keep state between restarts! I'm using it all the time now.

For anyone else who wants to use it, here it is (also available on pastebin):

#!/usr/bin/python    from time import time, ctime  from gi.repository import Gtk  from gi.repository import AppIndicator3 as Indicator  from datetime import datetime, date      MY_FILENAME = '/home/anotherghost/workhours.log'  MY_INDICATOR_ID = 'work-hours-indicator'  STOP_ICON_NAME = 'indicator-messages'  START_ICON_NAME = 'indicator-messages-new'  FMT = "%a %b %d %H:%M:%S %Y"    class MyIndicator(object):        def __init__(self, filename):          self.indicator = Indicator.Indicator.new(                                  MY_INDICATOR_ID,                                  STOP_ICON_NAME,                                  Indicator.IndicatorCategory.APPLICATION_STATUS)            self.menu = Gtk.Menu()            start_item = Gtk.MenuItem('Start')          start_item.connect('activate', self.start_activated, filename)          self.menu.append(start_item)          start_item.show()            stop_item = Gtk.MenuItem('Stop')          stop_item.connect('activate', self.stop_activated, filename)          self.menu.append(stop_item)          stop_item.show()            showall_item = Gtk.MenuItem('Show all')          showall_item.connect('activate', self.showall, filename)          self.menu.append(showall_item)          showall_item.show()            self.indicator.set_menu(self.menu)          self.indicator.set_attention_icon(START_ICON_NAME)            with open(MY_FILENAME,'r') as fn:              try:                  fn.seek(-70, 2)              except (IndexError, IOError):                  fn.seek(max(-len(fn.read().decode()),-69),2)              self.last = fn.readlines()[-1].decode()              if len(self.last) > 1 and len(self.last) < 30:                  self.last = self.last.split(" ")                  self.last[-1] = self.last[-1][:4]                  self.last = " ".join(self.last)                  self.start_time = datetime.strptime(self.last, FMT)                  self.indicator.set_status(Indicator.IndicatorStatus.ATTENTION)                  self.has_started = True                  self.end_time = datetime.now()              else:                  self.indicator.set_status(Indicator.IndicatorStatus.ACTIVE)                  self.has_started = False                  self.start_time = datetime.now()                  self.end_time = datetime.now()          def main(self):          Gtk.main()        def start_activated (self, menu_item, filename):          if not self.has_started:              myfile = open(filename, 'a')              self.start_time = datetime.now()              myfile.write('%s' % self.start_time.strftime(FMT))              self.indicator.set_status(Indicator.IndicatorStatus.ATTENTION)              self.has_started = True              myfile.close()        def stop_activated (self, menu_item, filename):          if self.has_started:              myfile = open(filename, 'r+')              myfile.seek(-1, 2)              if myfile.read(1) == '\n':                  myfile.seek(-1, 2)              self.end_time = datetime.now()              self.elapsed_time = self.end_time - self.start_time              myfile.write('\t%s\t' % self.end_time.strftime(FMT))              myfile.write('%s\n' % round(float(self.elapsed_time.seconds)/3600,3) )              self.indicator.set_status(Indicator.IndicatorStatus.ACTIVE)              self.has_started = False              myfile.close()        def showall (self, menu_item, filename):          myfile = open('op.log', 'a')          myfile.write('has_started: %s\n' % self.has_started)          myfile.write('start_time: %s\n' % self.start_time.strftime(FMT))          myfile.write('end_time: %s\n' % self.end_time.strftime(FMT))      if __name__ == '__main__':      indicator = MyIndicator(MY_FILENAME)      indicator.main()  

Note:If u also have question or solution just comment us below or mail us on toontricks1994@gmail.com
Previous
Next Post »