You are viewing benlast

Previous Entry | Next Entry

Counting down in Python


I have events coming up in my life; some are good and some are not so good. Anticipating the good ones is positive, and one way to do that is to have a little countdown visible on my desktop. I run Ubuntu Linux on my home laptop, and so I wanted a way to drop a countdown into the menu bar (where Unity shows indicator output).

Unity (the Ubuntu window manager/interface) does this using indicators (yet another term to learn for gadgets). It took about 30 minutes to work out how to knock up a little indicator in Python, and here it is for anyone who needs it. I based it on a bare-bones clock indicator: the link to the original is in the comments.

#!/usr/bin/env python
# Unity indicator for countdown to a fixed date
# author: ben last
# based on Phil Ayres' clock indicator
# (see https://gist.github.com/philayres/1309895)
# 17 Mar 2013
 
import gobject
import gtk
import appindicator
import os, sys
import time

#Define the target time as a time_t
TARGET=time.mktime((2013,12,24,23,59,0,0,0,0))

def on_left_click(widget,ind):
    """Quit"""
    ind.set_label("")
    sys.exit(0)
  
def on_timer(ind):
  """Update the label - we always use local time."""

  #Get the local time as a time_t (seconds since the epoch)
  t=time.mktime(time.localtime())
  
  #Get the offset to the target such that a positive value
  #means the target is in the future, in seconds.  Also save
  #in offset, so we can spot the end of the countdown.
  offset=seconds=TARGET-t

  #If we're at or past the target, reset to zero
  if seconds < 0: seconds=0

  #Convert to days, hours, minutes and seconds
  (days,seconds) = divmod(seconds,24*60*60)
  (hours,seconds) = divmod(seconds,60*60)
  (minutes,seconds) = divmod(seconds,60)

  #Generate the label
  label="%02d:%02d:%02d:%02d"%(days,hours,minutes,seconds)

  #Debug output
  #sys.stdout.write("%s %s\n"%(offset,label))
  
  #ind is the indicator - setting the label shows the countdown
  #in the indicator area.
  ind.set_label(label)

  #returning False means no more calls to this method
  return offset>=0

if __name__ == "__main__":
    #Create the indicator with a clock icon
    ind = appindicator.Indicator("simple-countdown",
                                 "clock",
                                 appindicator.CATEGORY_APPLICATION_STATUS)
    ind.set_status (appindicator.STATUS_ACTIVE)

    #Set the label
    on_timer(ind)

    #Creata a menu and an item
    menu = gtk.Menu()
    item = gtk.MenuItem("Quit")

    item.connect("activate", on_left_click, ind)
    item.show()
    menu.append(item)
    ind.set_menu(menu)

    #Start a one-second tick
    gtk.timeout_add(1000, on_timer, ind)

    gtk.main()