Sei sulla pagina 1di 4

e c o u d r c e o n j

Create Indicator Applet for Ubuntu Unity (with Python!)


We're going to walk through the process of creating a status indicator applet for the latest version of Ubuntu running Unity. In this example we're going to create a basic new mail indicator which works with GMail. This will give you a solid grounding in the basic structure of an applet while providing a real-world (albeit simplistic) example that you can easily extend. Let's go through the final script piece by piece, first our header:
#!/usr/bin/env python import sys import gtk import appindicator import imaplib import re PING_FREQUENCY = 60

search this blog

Categories
Android (1) Firefox (1) Gnome (2) Linux (11) Python (5) Security (1)

Tags
Environment One Liners Hacks Utilities Culture Spotify

The first line instructs the system to find the current environment's version of python and use it to run this file. The first three imports are probably going to be used in every indicator you use. sys is used so we can offer a "Quit" option, GTK drives the interface, and appindicator provides Unity-specific code for creating indicator applets. The last two includes are required for this indicator's specific functionality, checking GMail. Finally we have one application wide constant which dictates how often we should ping (or check) GMail's servers for new mail, in seconds.
class CheckGMail: def __init__(self): self.ind = appindicator.Indicator("debian-doc-menu", "indicator-messages", appindicator.CATEGORY_APPLICATION_STATUS) self.ind.set_status(appindicator.STATUS_ACTIVE) self.ind.set_attention_icon("new-messages-red") self.menu_setup() self.ind.set_menu(self.menu)

Archives
April 2012 (1) August 2011 (1) July 2011 (4) June 2011 (3) May 2011 (4) April 2011 (7)

Recent Posts
Send text to clipboard in linux terminal Linux and sharing, so awesome it just might be illegal UDev rules for Android Development on Motorola Triumph Fix Spotify playlist URLs in Ubuntu / Linux / Gnome 3 Disable the Universal Access accessibility menu in Gnome 3

Next we create a class called CheckGMail which will hold all of our indicator's functionality. To initialize our class first we create the variable "ind" which holds an Indicator object. According to the API this constructor takes 3 (or 4) arguments, a unique id for our indicator, an icon name, and an indicator category. We set an initial status for our indicator with ind.set_status and then define the icon to use when our indicator requires attention (in this case when we have new mail waiting). Then we call our custom menu_setup() function (which we haven't defined yet), and then the set_menu() function on the Indicator object which takes a GTK menu as an argument and attaches it to our indicator.
def menu_setup(self): self.menu = gtk.Menu() self.quit_item = gtk.MenuItem("Quit") self.quit_item.connect("activate", self.quit) self.quit_item.show() self.menu.append(self.quit_item)

This work is licensed under a Creative Commons Attribution 3.0 Unported License.

Here is the aforementioned menu_setup() function. Here we create a new GTK Menu and then define a single menu item called "quit_item". We define the text label for the menu, and then connect it with an action. We instruct the menu item to launch the quit() function when the item is "activated" (clicked) and then add the item to our menu variable.
def main(self): self.check_mail() gtk.timeout_add(PING_FREQUENCY * 1000, self.check_mail) gtk.main()

The main() function constitutes our primary program loop. When our indicator is first loaded we run this function. First it runs the check_mail() function (which has yet to be defined), and then creates a timeout. This causes our program to wait the specified amount of time and then run the given callback function, which is in this case, check_mail(). Then finally we run our main() function again, putting our program into an infinite loop, since we'd like our applet to continually check mail as long as it's running.
def quit(self, widget): sys.exit(0)

Here we define the quit() function which we referenced in menu_setup(). This function makes a call to sys.exit which will cause our application to stop running. At this point the process will stop and our indicator applet will disappear.
def check_mail(self): messages, unread = self.gmail_checker('myaddress@gmail.com','mypassword') if unread > 0: self.ind.set_status(appindicator.STATUS_ATTENTION) else: self.ind.set_status(appindicator.STATUS_ACTIVE) return True

This is the core functionality of this specific indicator applet. We're calling the function gmail_checker() which we've borrowed from Martin Brook for the purposes of this example. We load in the number of total messages and the number of unread messages from the provided GMail account. (I should note, this will work with Google Apps account, you are not required to have a @gmail.com address). If there is more than one unread messages found, we change the status of our indicator to STATUS_ATTENTION, which is this case turns our icon red, notifying you of new messages.
def gmail_checker(self, username, password): i = imaplib.IMAP4_SSL('imap.gmail.com') try: i.login(username, password) x, y = i.status('INBOX', '(MESSAGES UNSEEN)') messages = int(re.search('MESSAGES\s+(\d+)', y[0]).group(1)) unseen = int(re.search('UNSEEN\s+(\d+)', y[0]).group(1)) return (messages, unseen) except: return False, 0

This is the final function of our indicator applet class, and it is the code that we borrowed from Martin. It creates an SSL encrypted connection to an IMAP server, in this case GMail, and will attempt to determine how many total and unread messages are available.
if __name__ == "__main__": indicator = CheckGMail() indicator.main()

We come a the close of our file with some basic python initialization. This special block will be run when our file is called directly. It instantiated an object of the CheckGMail class and then runs the main() function, which set's everything off for us. Here is our entire file:
#!/usr/bin/env python import sys import gtk import appindicator import imaplib import re PING_FREQUENCY = 10 # seconds class CheckGMail: def __init__(self): self.ind = appindicator.Indicator("new-gmail-indicator", "indicator-messages", appindicator.CATEGORY_APPLICATION_STATUS) self.ind.set_status(appindicator.STATUS_ACTIVE) self.ind.set_attention_icon("new-messages-red") self.menu_setup() self.ind.set_menu(self.menu)

self.ind.set_menu(self.menu) def menu_setup(self): self.menu = gtk.Menu() self.quit_item = gtk.MenuItem("Quit") self.quit_item.connect("activate", self.quit) self.quit_item.show() self.menu.append(self.quit_item) def main(self): self.check_mail() gtk.timeout_add(PING_FREQUENCY * 1000, self.check_mail) gtk.main() def quit(self, widget): sys.exit(0) def check_mail(self): messages, unread = self.gmail_checker('myaddress@gmail.com','mypassword') if unread > 0: self.ind.set_status(appindicator.STATUS_ATTENTION) else: self.ind.set_status(appindicator.STATUS_ACTIVE) return True def gmail_checker(self, username, password): i = imaplib.IMAP4_SSL('imap.gmail.com') try: i.login(username, password) x, y = i.status('INBOX', '(MESSAGES UNSEEN)') messages = int(re.search('MESSAGES\s+(\d+)', y[0]).group(1)) unseen = int(re.search('UNSEEN\s+(\d+)', y[0]).group(1)) return (messages, unseen) except: return False, 0 if __name__ == "__main__": indicator = CheckGMail() indicator.main()

Now we just need to mark the file as executable and run it to see the results.
chmod +x check_gmail.py ./check_gmail.py

Now if you have a bunch of unread messages in your gmail account it will always be red, so you'll have to extend this example if you want to make the new message checking more intelligent. We've learned how to setup a basic indicator applet with it's own menu and icon, and give it a useful piece of functionality. You could easily replace the check_email() function with almost anything else you could program in python normally. Hope this helps to get you started with creating indicators, if you have any questions or comments, please let me know!
0
5 responses

Linux, Python Utilities June 9th, 2011

Add New Comment

Login

Showing 4 comments

Sort by popular now

Ekoz

Thanks to this example I'm creating my own indicator :) So thank you. But I'm wondering about how make a .deb or an executable to give it to friends, or any people... I mean, run it on startup, and hide sources...

dread

Thanks for the article! It's very useful!

vamsi

how to specify the location of a custom icon as the application icon

atrus

I was going to write another part to go over this, but check this out in the mean time http://freakaboutlinux.wordpre...

M Subscribe by email

S RSS

Potrebbero piacerti anche