#!/usr/bin/env ruby # Gmail notifier -- show inbox status in notification area. # by Evan Martin , 2005 # # The author disclaims copyright to this source code. In place of # a legal notice, here is a blessing: # May you do good and not evil. # May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # Debian users: # apt-get install librexml-ruby libgtk-trayicon-ruby libgnome2-ruby \ # libopenssl-ruby ca-certificates require 'getoptlong' require 'net/https' require 'rexml/document' require 'gtktrayicon' require 'gnome2' # only for spawning the browser $opts = { 'update_frequency' => 5 * 60 * 1000, # five minutes 'certpath' => '/etc/ssl/certs' } class GmailApplet < Gtk::TrayIcon def initialize super('Gmail') self.border_width = 2 load_images @image = Gtk::Image.new(@inactive) add(@image) show_all @tooltips = Gtk::Tooltips.new menu = Gtk::Menu.new item = Gtk::ImageMenuItem.new('Open _Gmail') item.image = Gtk::Image.new(@active) item.signal_connect('activate') { browser } item.show_all; menu.append(item) item = Gtk::ImageMenuItem.new(Gtk::Stock::QUIT) item.signal_connect('activate') { Gtk.main_quit } item.show; menu.append(item) add_events(Gdk::Event::BUTTON_PRESS_MASK) add_events(Gdk::Event::BUTTON_RELEASE_MASK) signal_connect('button-press-event') do |w, e| browser if e.button == 1 and e.event_type == Gdk::Event::BUTTON2_PRESS end signal_connect('button-release-event') do |w, e| menu.popup(nil, nil, e.button, e.time) if e.button == 3 end update Gtk::timeout_add($opts['update_frequency']) { update; true } end def load_images # the images are the same except for their palette. head = "iVBORw0KGgoAAAANSUhEUgAAABAAAAALBAMAAACEzBAKAAAAFVBMVE" # base64 active = "XaODjp\nWlrygYH5p6f/trb/4uL////pJer3" inactive = "VpaWmF\nhYWjo6PAwMDMzMzr6+v///8TRSyi" tail = "AAAAUUlEQVQI1x3GwQnAIBBE0TVYgFhB\nFoINGO+SgA0IFi" + "A6/ZeQ2fzLfyJHZqewBiy7eqBGYoa2XCKgvkYYnuAuw741\n" + "voPoY6ZdiALWiWHYRP6TD9jWEEbv7ex0AAAAAElFTkSuQmCC" active = head + active + tail inactive = head + inactive + tail loader = Gdk::PixbufLoader.new 'png' loader.last_write active.unpack('m')[0] @active = loader.pixbuf loader = Gdk::PixbufLoader.new 'png' loader.last_write inactive.unpack('m')[0] @inactive = loader.pixbuf end def check req = Net::HTTP::Get.new '/mail/feed/atom' req.basic_auth($opts['username'], $opts['password']) http = Net::HTTP.new('mail.google.com', 443) http.use_ssl = true http.verify_mode = OpenSSL::SSL::VERIFY_PEER http.ca_path = $opts['certpath'] res = http.request req doc = REXML::Document.new res.body doc.root.get_elements('/feed/entry').length end def browser Gnome::URL.show 'http://mail.google.com' end def update messages = check @image.pixbuf = if messages > 0 then @active else @inactive end tip = if messages > 0 then "#{messages} unread" else 'no mail' end @tooltips.set_tip(self, "Gmail (#{$opts['username']}) - " + tip, nil) end end def usage puts "usage: #{$0} -u username -p password [-c certpath]" exit 1 end begin GetoptLong.new( [ '--username', '-u', GetoptLong::REQUIRED_ARGUMENT ], [ '--password', '-p', GetoptLong::REQUIRED_ARGUMENT ], [ '--certpath', '-c', GetoptLong::REQUIRED_ARGUMENT ] ).each do |opt, arg| $opts[opt[2..-1]] = arg end rescue GetoptLong::InvalidOption usage end unless $opts['username'] and $opts['password'] puts 'must specify username and password' usage end Gtk.init; GmailApplet.new; Gtk.main # vim: set ft=ruby ts=2 sw=2 et :