Software

Installing Linux

The DPF runs on Debian, because that's the Linux flavor that I'm most familiar with. Many other people have installed lighter versions of linux on their DPF, such as Damn Small Linux.

You can get Debian here. You're probably need to choose i386, and you should grab the CD-1 iso. Once the download has finished, simply put a blank CD in your CD writable drive and double click the downloaded file to start Window's ISO burning wizard.

Once the CD has finished burning, just pop it into the DPF laptop and restart it. Leave all of the options on default, but be sure to plug an ethernet cable into the laptop so all of the needed software can be downloaded.

Wireless authentication

Like most Linux distributions, Debian will automatically detect, setup and utilize internal and PCMCIA wireless adaptors. But our needs were a little more complicated: we wanted to only connect to UCA's wireless network, and we had to authenticate automatically. For this we needed some scripts.

Scripting is Linux's most powerful tool: you can automate very complex tasks very quickly and easily, something which simply cannot be done in Windows. For example, the following scripts do the following: (1) stop wired networking (2) stop wireless networking (3) start wireless networking (4) connect to the wireless network UCAWIRELESS (5) get an IP address from the wireless network

sudo ifconfig eth0 down
sudo ifconfig eth1 down
sudo ifconfig eth1 up
sudo iwconfig essid UCAWIRELESS
sudo dhclient eth1

This script runs every time the DPF starts, to ensure that it only connects to the UCA wireless network. But that's only half the battle: how do we authenticate to the network?

Part of the fun of Linux is that there are many ways to do almost every task. To solve the authentication problem, I used the ruby programming language and one of its libraries. Below is the code, which is pretty reasonble to understand if you have some understanding of HTML.


#! /usr/bin/env ruby
#Include libraries
require 'rubygems'
require 'mechanize'
#Run forever
while(true)

#Create a mechanize object
browser = WWW::Mechanize.new;
#Attempt to fetch www.google.com
page = browser.get('http://www.google.com');

#If we ended up with the UCA Wireless login in page instead of google, login
if browser.page.title == "UCA Wireless Network Log In";

#Grab the login form from the page
login_form = page.form('bluesocket_u');

#Fill in the username field
login_form.bs_name = '####';

#Fill in the password field
login_form.bs_password = '####';

#Select the legal stuff checkbox
login_form.checkboxes.name('require_terms_g').check;

#Submit the form
page = browser.submit(login_form);

#If we didn't get google or the UCA wireless login page, something isn't working correctly
elsif browser.page.title == "Google"

#If we got google, we're already logged in!
else
end
sleep(5);
end

This script will run pretty much continuously, so the DPF will reauthenticate to the wireless network if it gets kicked for some reason.

Fetching pictures from flickr

We looked at a lot of different options for grabbing the pictures from Flickr, including writing the software to connect to Flickr's API ourselves. But we really didn't have time for that. It was pretty difficult to find a simple Linux downloader, but we finally did with Webilder. The program is reasonally complex, but we ended up using just one small part: webilder-downloader. This command-line tool enabled us to a automate the downloads using scripts. It was perfect, except for one small problem: it would only download 30 pictures. Luckily, Webilder is open-source, so we could look at the source code and make some changes. We increased the download limit to 300, which should work just fine.

Once we got our downloader, we had one more problem: Flickr's API renames the files, which was a problem when we wanted pictures to be in a certain order (such as Powerpoint slides). Fortunately, the API did give us an info file for each picture, which included the original file name. I simply wrote a script to rename the files to their original.

#Directory where pictures to be sorted are stored
my $dir = "/home/physics/pictures";
#Array to hold list of .inf files
my @file_list;

#Calls main function
main();
#Exits
0;

#Main function
sub main() {
#Grab list of files
search_dir();
#Parse and rename files
rename_files();
}
#Grabs the list of files that end in .inf
sub search_dir() {
opendir(BIN, $dir) or die "Can't open $dir: $!";

while(defined (my $file = readdir BIN)) {
if($file =~ /inf/) {
print "Adding $file to file_list\n";
push(@file_list, $file);
}
}
closedir(BIN);
}
#Renames the .jpg files using the info in the .inf file
sub rename_files() {
#Parse each inf file
foreach my $file_name (@file_list) {
$file_path = $dir."/".$file_name;
open(FILE, $file_path) or die "Can't open $file_name";
my @lines = ;
#Parse each line of the inf file
foreach $line (@lines) {
if($line =~ /title/) {
#Compose the old picture name
my $old_pic_file = $file_name;
$old_pic_file =~ s/\s+$//;
$old_pic_file =~ s/inf/jpg/;
my $old_pic_path = $dir."/".$old_pic_file;
#Compose the new picture name
my $new_pic_name = $line;
$new_pic_name =~ s/title=//;
$new_pic_name =~ s/\s+$//;
my $new_pic_file = $new_pic_name . ".jpg";

#Rename single digits for numerical sorting purposes
#Looks for *non-digitdigit.jpg and changes to
#*non-digit0digit.jpg
if($new_pic_file =~ m/\D\d.jpg$/) {
$new_pic_file =~ s/.jpg$//;
my $char = chop($new_pic_file);
$new_pic_file = $new_pic_file."0".$char.".jpg";
}

my $new_pic_path = $dir."/".$new_pic_file;
my $cmd = "mv $old_pic_path '$new_pic_path'";
system($cmd);
}
}
}
}

Automating the functionality

Everything needed for the custom functionality of our DPF, from authenticated to the network to downloading the pictures, were called from this single script:


#!/bin/bash
#This program will run every time the laptop wakes up or is turned on.

#Unclutter removes the mouse when idle, so it won't show during the slideshow
#The '&' symbol means unclutter will run in the background, so we can move on
#with the program.
#Unclutter complains if there is already a version of itself running, so
#we use killall to make sure there aren't any.
killall unclutter
unclutter &

#This loading screen runs until we've updated the picture store
feh -r /home/physics/code/DPF_loading.jpg -FZx &

#Set up general wireless networking
sudo ifconfig eth0 down
sudo ifconfig eth1 down
sudo ifconfig eth1 up
sudo dhclient eth1

#This is the script to login to the UCA wireless
ruby /home/physics/code/UCA_wireless_login.rb &

#Wait 15 seconds to make sure we've had a chance to connect to the internet
sleep 15

#Remove all old pictures
rm /home/physics/pictures/*
rm -r /home/physics/pictures/.thumbs

#Webilder-downloader is part of the webilder application, which downloads pictures
#from Flickr based on certain criteria. I've set up webilder to only download
#photos that are posted by the user uca_physics. Webilder usually changes the PC
#background image with those downloaded, but I'm just using it for it's ability
#to grab photos from Flickr.
webilder_downloader

#This little script renames the files from the names given by flickr to the orginal ones,
#so we can sort the pictures in the slideshow.
perl /home/physics/code/parse_pictures.pl

#Kill the old image slideshow
killall feh

#Wait 15 seconds to make sure we've had a chance to kill the old feh, but not kill the new one
sleep 15

#The webilder-downloader saves pictures to /home/physics/pictures
#Feh is a simple image viewer that has many different options
#To view all of the options of feh, type man feh at the command line.
feh -r /home/physics/pictures -FZxD 10 -S name