Sunday, April 12, 2009

New addition

The task I find myself doing the most often with my computer is probably one of the most banal exercises known to man. If I had stuff on there I needed to keep private, or if the possibility existed someone might hack into my computer, I'd feel it would be one of the most important things you can do.
Of course, it is entering my password.
A mix of settings encourages -- actually, it requires -- this situation. Not only do I enter my password when logging in (for both CLI and GUI[1]), I enter it whenever I make changes to my system, when I pipe the view from my monitor up to the office, and even when I let my screen saver kick on.
So, I got to thinking. I'm entering 16 keystrokes every time I put in my password. Is there anything I do normally right after restoring my screen that I could automate?
The result? weatherd.py

#!/usr/bin/env python
# weatherd.py v0.3: Current Weather Conditions when you return
# to your desktop.
# Stolen ruthlessly from
# PyGlue's Pause_Rythmbox_on_XScreensaver
# http://code.google.com/p/pyglue
# And the PyNotify Examples
# /usr/share/doc/ptyhon-notify/examples
# GNU GPL 3 licensing applies.
# http://www.gnu.org/licenses/gpl.html

import dbus
import commands

try:
import dbus.glib
except ImportError:
from dbus.mainloop.glib import DBusGMainLoop
DBusGMainLoop(set_as_default=True)

def screensaver_changed(state):
"""This method is called
when the screensaver starts/stops"""

import pygtk
pygtk.require('2.0')
import pynotify
import sys

if not pynotify.init("Basics"):
sys.exit(1)

currentweather = commands.getstatusoutput('weather ddc')
n = pynotify.Notification("Current DC Conditions", currentweather[1])

if not n.show():
print "Failed to send notification"
sys.exit(1)

session_bus = dbus.SessionBus()
session_bus.add_signal_receiver
(screensaver_changed,
'SessionIdleChanged',
'org.gnome.ScreenSaver')

def main():
import gobject
loop = gobject.MainLoop()
loop.run()

def daemonize(func):
import os
import sys
try:
pid = os.fork()
if pid > 0:
# exit first parent
sys.exit(0)
except OSError, e:
print >>sys.stderr,
"fork #1 failed: %d (%s)" % (e.errno, e.strerror)
sys.exit(1)

# decouple from parent environment
os.chdir("/")
os.setsid()
os.umask(0)

# do second fork
try:
pid = os.fork()
if pid > 0:
# exit from second parent,
#print eventual PID before
print "Daemon PID %d" % pid
sys.exit(0)
except OSError, e:
print >>sys.stderr,
"fork #2 failed: %d (%s)" % (e.errno, e.strerror)
sys.exit(1)

# start the daemon main loop
func()

if __name__ == "__main__":
daemonize(main)
So, what does this do? Well, a lot of programs on my computer send a signal when something happens. That session_bus stuff listens for those signals, and when it hears the screensaver saying "I'm turning off", it tells the function called 'screensaver_changed' to do its thing.
In this case, I've decided to take advantage of the National Weather Service's automated feed -- that's the 'weather ddc' line. 'Weather' is part of the weather-utils package available for Debian. 'DDC' tells it to grab the current conditions from KDDC: the Dodge City Municipal Airport. Then we use feed that information to pyNotify, which makes it look like this:


Useful? Right now, that's debatable. It saves me from opening a new terminal and searching, or Firefox and getting the radar. But, writing this thing three different ways before making it work gave me some time to work on my programming skills.

TODO:
  • Change the Notify template from Basic to Markup, add hyperlink to a radar site.
    --Note... possible with www.crh.noaa.gov/[TLA]
  • Un-Hard Code weather station, make it user selectable from command line.
WISHLIST:
  • Grab and use the most recent weather radar image as the popup icon.
Now, you're probably wondering right now, Deege, why didn't you go out and -- for example -- grab the Linux version of WeatherBug? Now, I could say that my intent was actually finding something useful to work toward while trying to improve my Python skills. Or, I could say that I'm not fond of having Java programs running constantly on my computer. Or, I could say that the amount of junk mail I got from registering the Windows version turned me off to it. Or, that I'd rather use the bandwidth for other things than keeping a connection open. All of which would be true - but none of which would be the real reason. ***Sheepish Grin*** I just didn't know there was one until I started looking for the link for the weather-util package. It's Creative Commons License instead of GNU Public License, which means it's not in Debian's repositories, which means I really didn't know about it.

[1] CLI: Command Line Interface. Like DOS, if you were using a computer that long ago. I use this when I need to get results quickly: type in a command, get an answer back. Graphical User Interface. It shows the pretty pictures. I use this when I need to see what I'm doing -- photo viewing/editing, surfing the web (for the most part).

No comments: