Automating Location-Triggered Podcasts
In No Agenda's (really, Comic Strip Blogger seems to differ) 31st episode, Adam told John that he would like to do a location-specific podcast, which would play when user arrives at a certain location. Comic Strip Blogger, who, like me, never uses his real name when on the DSC, observes that this is nothing new. Indeed, CSB, how about you point us to a project that accomplishes this task (like this entry :), for example ). There are a number of pseudostandards. Within an item, you'll need to add an enclosure, and the geocode (using the simple format, example below).
-
Today: 0730 Zimbabwe 24 June 08
The UN Security Council declaration on Zimbabwe represents a significant move in the diplomatic pressure on Robert Mugabe. Everyone agreed that the violence there makes it impossible to hold free and fair elections at the moment. But what are the diplomatic prospects? The former leader of the Liberal Democrats, Lord Ashdown, considers what would work.
The UN Security Council declaration on Zimbabwe represents a significant move in the diplomatic pressure on Robert Mugabe. Everyone agreed that the violence there makes it impossible to hold free and fair elections at the moment. But what are the...
The UN Security Council declaration on Zimbabwe represents a significant move in the diplomatic pressure on Robert Mugabe. Everyone agreed that the violence there makes it impossible to hold free and fair elections at the moment. But what are the diplomatic prospects? The former leader of the Liberal Democrats, Lord Ashdown, considers what would work.
Tue, 24 Jun 2008 07:30:00 +0100
8:25
http://downloads.bbc.co.uk/podcasts/radio4/today/today_20080624-0730.mp3 http://downloads.bbc.co.uk/podcasts/radio4/today/today_20080624-0730.mp3
BBC Radio 4
-17.515 31.147
def reactToLocation(location = '-17.515 31.147'):
import feedparser
f=feedparser.parse('rss.xml')
for item in f.entries:
loc = item['georss:point']
if loc == location:
import urllib2, urlparse
parsed = urlparse.parse (item['enclosures'][0]['href'])
data = urllib2.urlopen(item['enclosures'][0]['href']).read()
file = open(parsed[2].split('/')[-1], 'w')
file.write(data)
# open the file in your mp3 player and listen
return True
How to Summarise Auntie's Front Page
My automated news summariser has been enhanced and made faster. I am certain this isn't the most efficient way of solving it, but it does work and does so reasonably fast. Also, I've standardised on using par as the distribution format. If you still prefer the old method, the script's source is pasted below. To run the par, you'll be typing perl -MPAR BBC.par and just let it do its thing.
As for the "auntie" moniker, it is a nickname for the BBC, which is the script's news source.
use strict;
use XML::RSS::Parser::Lite;
use LWP::Simple;
use HTML::TreeBuilder;
my $url = "http://newsrss.bbc.co.uk/rss/newsonline_world_edition/front_page/rss.xml";
my $xml = get($url);
my $rp = new XML::RSS::Parser::Lite;
$rp -> parse($xml);
for (my $count = 0; $count != $rp->count() - 1; $count++) {
my $item = $rp -> get($count);
$url = $item->get('url');
my $h = HTML::TreeBuilder->new_from_content(get($url));
my @links = $h->look_down('_tag','p', sub {
my $paragraph = $_[0]->as_text;
next if not defined($paragraph);
if ( $paragraph =~ /(.*)([!?.])?/ ) {
my $length = split /\s/, $1;
print "$1$2 " if $length > 3;
}
} );
$h->delete;
print "\n--------------------------------------------------------------------------------\n" if $count != 0;
How to Track Pizza Delivery
Someone has put up a Dominoes pizza order tracking script using their XML feed. Cool!
#!/usr/bin/env python
import xml.dom.minidom
import urllib, sys, datetime
class Dominos:
def __init__(self, *args, **kw):
self.__feed_url = "http://trkweb.dominos.com/orderstorage/GetTrackerData"
def get_order_info(self, phone_number):
xml_data = urllib.urlopen('%s?Phone=%s' % (self.__feed_url, phone_number))
dom = xml.dom.minidom.parse(xml_data)
orders_node = dom.getElementsByTagName('OrderStatuses')
order = orders_node[0].getElementsByTagName('OrderStatus')
if order.length > 0:
description = order[0].getElementsByTagName('OrderDescription')[0].firstChild.data
starttime = self.get_time(order[0].getElementsByTagName('StartTime')[0].firstChild)
oventime = self.get_time(order[0].getElementsByTagName('OvenTime')[0].firstChild)
racktime = self.get_time(order[0].getElementsByTagName('RackTime')[0].firstChild)
routetime = self.get_time(order[0].getElementsByTagName('RouteTime')[0].firstChild)
deliverytime = self.get_time(order[0].getElementsByTagName('DeliveryTime')[0].firstChild)
return {'description':description, 'starttime':starttime, 'deliverytime':deliverytime,
'oventime':oventime, 'racktime':racktime, 'routetime':routetime}
else:
return False
def get_time(self, time_node):
if time_node:
[date, time] = time_node.data.split("T")
[hour, minute, second] = time.split(":")
ampm = 'pm'
if hour < 12:
ampm = 'am'
return '%s:%s%s' % (int(hour) % 12, minute, ampm)
else:
return None
if __name__ == "__main__":
if len(sys.argv) != 2:
print 'usage: %s ' % sys.argv[0]
sys.exit(1)
print """Dominos (R) pizza tracker."""
d = Dominos()
order_info = d.get_order_info(sys.argv[1])
if not order_info:
print "No Orders Found for %s" % sys.argv[1]
else:
print order_info['description']
if order_info['starttime']: print "Your pizza is being made! %s" % order_info['starttime']
if order_info['oventime']: print "Your pizza is in the oven! %s" % order_info['oventime']
if order_info['racktime']: print "Your pizza is done and awaiting delivery! %s" % order_info['racktime']
if order_info['routetime']: print "Your pizza is on the way! %s" % order_info['routetime']
if order_info['deliverytime']: print "Your pizza was delivered! %s" % order_info['deliverytime']
How to Search GMail from the Comfort of Your Command-Line
The command-line gmail search is working. Next step: see how to speed it up. It's still taking almost a minute to search 317 messages. Code pasted after the flip, as with the last message.
package com.prolificprogrammer.lucenegmail;
import java.io.File;
import java.util.logging.Logger;
import java.util.logging.Level;
import javax.mail.Folder;
import javax.mail.Message;
import javax.mail.Session;
import javax.mail.Store;
import javax.mail.internet.InternetAddress;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.queryParser.QueryParser;
import org.apache.lucene.search.Hits;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
public class SearchGMail {
private static Logger logger = Logger.getLogger(new SearchGMail().getClass().getCanonicalName());
public static void main (String[] args) throws Exception {
//logger.setLevel(java.util.logging.Level.FINE);
try {
File path = new File(System.getProperty("java.io.tmpdir")+File.separator+"gmail.index");
path.mkdir();
path.deleteOnExit();
long starttime = System.currentTimeMillis();
IndexWriter index = new IndexWriter(path.getAbsolutePath(), new StandardAnalyzer(), true);
Session session = Session.getDefaultInstance(System.getProperties(), null);
Store store = session.getStore("pop3s");
store.connect("pop.gmail.com", args[0], args[1]);
logger.fine("Connected!");
Folder folder = store.getDefaultFolder();
folder = folder.getFolder("INBOX");
folder.open(Folder.READ_ONLY);
logger.fine("Opened INBOX");
Message[] messages = folder.getMessages();
int x;
for (x = 0; x != messages.length; x++) {
try {
Document document = new Document();
String allField = ((InternetAddress)messages[x].getFrom()[0]).getAddress()+"\n"+messages[x].getSubject();
document.add(new Field("all", allField, Field.Store.YES, Field.Index.TOKENIZED));
Field messageNumberField = new Field("messageNumber", new Integer(x).toString(), Field.Store.YES, Field.Index.NO);
messageNumberField.setBoost((float)0.0);
document.add(messageNumberField);
index.addDocument(document);
logger.fine("Message "+x+" added.");
} catch (OutOfMemoryError e) {
index.optimize();
continue;
}
}
index.optimize();
index.close();
logger.info("Index Constructed -- now searching");
IndexSearcher searcher = new IndexSearcher(path.getAbsolutePath());
Analyzer analyzer = new StandardAnalyzer();
String query = args[2];
QueryParser queryParser = new QueryParser("all", analyzer);
Query parsedQuery = queryParser.parse(query);
Hits hits = searcher.search(parsedQuery);
for (int i = 0; i!= hits.length();i++) {
Document doc = hits.doc(i);
System.out.println("Message "+doc.getField("messageNumber").stringValue()+" matches "+query+" with a score of "+hits.score(i));
}
searcher.close();
long endtime = System.currentTimeMillis();
logger.severe("program took "+new Long(endtime-starttime).toString()+" miliseconds to search "+new Integer(x).toString()+" messages, which occupy "+new Long(path.length()).toString()+" bytes.");
java.awt.Toolkit.getDefaultToolkit().beep();
} catch (ArrayIndexOutOfBoundsException e) {
logger.severe("Usage: "+new SearchGMail().getClass().getName()+" [google login] [password] [query]\nAll required");
System.exit(-1);
}
}
}
How to Search Gmail from the comfort of your Keyboard 2
The Java code below leverages Lucene 2.3.1 and javamail to create a command-line search of your GMail inbox. It's actually quite slow, so I'd like to speed it up over time, but it does give updates as it runs, perhaps too many. Any (and all) suggestions appreciated?
package com.prolificprogrammer.lucenegmail;
import java.io.File;
import javax.mail.Folder;
import javax.mail.Message;
import javax.mail.Session;
import javax.mail.Store;
import javax.mail.internet.InternetAddress;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.queryParser.QueryParser;
import org.apache.lucene.search.Hits;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
public class SearchGMail {
public static void main (String[] args) throws Exception {
File path = new File(System.getProperty("java.io.tmpdir")+File.separator+"gmail.index");
path.mkdir();
path.deleteOnExit();
long starttime = System.currentTimeMillis();
IndexWriter index = new IndexWriter(path.getAbsolutePath(), new StandardAnalyzer(), true);
Session session = Session.getDefaultInstance(System.getProperties(), null);
Store store = session.getStore("imaps");
store.connect("imap.gmail.com", args[0], args[1]);
System.err.println("Connected!");
Folder folder = store.getDefaultFolder();
folder = folder.getFolder("INBOX");
folder.open(Folder.READ_ONLY);
System.err.println("Opened INBOX");
Message[] messages = folder.getMessages();
System.err.println("Messages retrieved!");
int x;
for (x = 0; x != messages.length; x++) {
Document document = new Document();
String allField = ((InternetAddress)messages[x].getFrom()[0]).getAddress()+"\n"+messages[x].getSubject();
document.add(new Field("all", allField, Field.Store.YES, Field.Index.TOKENIZED));
document.add(new Field("messageNumber", new Integer(x).toString(), Field.Store.YES, Field.Index.NO));
index.addDocument(document);
System.err.println("Message "+x+" added.");
}
index.optimize();
index.close();
System.err.println("Ok, index constructed with "+x+" messages in "+path.getAbsolutePath()+", now searching it");
IndexSearcher searcher = new IndexSearcher(path.getAbsolutePath());
Analyzer analyzer = new StandardAnalyzer();
String query = args[3];
QueryParser queryParser = new QueryParser("all", analyzer);
Query parsedQuery = queryParser.parse(query);
Hits hits = searcher.search(parsedQuery);
for (int i = 0; i!= hits.length();i++) {
Document doc = hits.doc(i);
System.out.println(doc.getField("messageNumber"));
}
searcher.close();
long endtime = System.currentTimeMillis();
System.err.println("program took "+endtime-starttime+" miliseconds to search "+x+" messages, which occupy "+path.length()+" bytes.");
java.awt.Toolkit.getDefaultToolkit().beep();
}
}
How to Fix Perl Version Problems
You know me, I'm the Prolific Programmer. So prolific am I, that I often encounter problems with my Swiss Army knife of tools. One of my favourite tools in the knife is Perl. So, it was with great sadness when I found that it was having version problems. Apparently, Compress::Zlib had been updated to 2.008 and the author, Paul Marquees had forgotten to update the other modules. Until he does, you need only comment out the versions from the relevant use lines. For example:
use CGI 3.31; # becomes...
use CGI; # 3.31
