<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>A Little Off &#187; data</title>
	<atom:link href="http://www.bemasher.net/archives/tag/data/feed" rel="self" type="application/rss+xml" />
	<link>http://www.bemasher.net</link>
	<description>Code, Computers, Photography and Guns</description>
	<lastBuildDate>Mon, 21 Nov 2011 06:38:44 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3</generator>
		<item>
		<title>Automagic TV Show Calendar</title>
		<link>http://www.bemasher.net/archives/914?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=automagic-tv-show-calendar</link>
		<comments>http://www.bemasher.net/archives/914#comments</comments>
		<pubDate>Sat, 04 Dec 2010 13:11:57 +0000</pubDate>
		<dc:creator>bemasher</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[Calendar]]></category>
		<category><![CDATA[data]]></category>
		<category><![CDATA[ElementTree]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[iCal]]></category>
		<category><![CDATA[json]]></category>
		<category><![CDATA[JSON-C]]></category>
		<category><![CDATA[Protocol]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Show]]></category>
		<category><![CDATA[Thread]]></category>
		<category><![CDATA[Threading]]></category>
		<category><![CDATA[tv]]></category>
		<category><![CDATA[tvrage]]></category>
		<category><![CDATA[xml]]></category>

		<guid isPermaLink="false">http://www.bemasher.net/?p=914</guid>
		<description><![CDATA[A little while ago I was browsing the web and discovered a website called tvrage.com[1] which seems to be the definitive online TV guide. I didn't originally enter the site on the main index but on a page describing the functionality of an XML API[2] they host for accessing their database of TV shows. To [...]]]></description>
			<content:encoded><![CDATA[<p>A little while ago I was browsing the web and discovered a website called tvrage.com<sup>[<a href="http://www.bemasher.net/archives/914#footnote_0_914" id="identifier_0_914" class="footnote-link footnote-identifier-link" title="http://tvrage.com/">1</a>]</sup> which seems to be the definitive online TV guide. I didn't originally enter the site on the main index but on a page describing the functionality of an XML API<sup>[<a href="http://www.bemasher.net/archives/914#footnote_1_914" id="identifier_1_914" class="footnote-link footnote-identifier-link" title="http://services.tvrage.com/">2</a>]</sup> they host for accessing their database of TV shows.</p>
<p>To me, this is like opening presents on christmas day. Just imagine the possibilities! I immediately began exploring the kind of data they provide. The very first idea I had was to use this to create events on my google calendar automatically for unaired episodes of my favorite TV shows.</p>
<p>I've previously written python scripts that interface with gdata but I find their implementation for python to be kind of cumbersome to deal with so I began researching their Protocol API<sup>[<a href="http://www.bemasher.net/archives/914#footnote_2_914" id="identifier_2_914" class="footnote-link footnote-identifier-link" title="Data API Developer&#039;s Guide: The Protocol">3</a>]</sup>. At first I wasted a lot of time attempting to build the necessary XML structures to add events and the like. This got old very fast and I decided to just give JSON-C<sup>[<a href="http://www.bemasher.net/archives/914#footnote_3_914" id="identifier_3_914" class="footnote-link footnote-identifier-link" title="Google&#039;s own flavor of JSON which is almost identical to plain old JSON.">4</a>]</sup> a try. Turns out you can use the built-in JSON module in python for creating the necessary structures.</p>
<p>For parsing the results I got from tvrage I ended up using python's xml.etree.ElementTree which was simple enough to setup to retrieve only the information for each episode I was interested in.<sup>[<a href="http://www.bemasher.net/archives/914#footnote_4_914" id="identifier_4_914" class="footnote-link footnote-identifier-link" title="I only really needed the  original air date, title, season number and episode number.">5</a>]</sup></p>
<p>I had a bit of trouble initially with adding events to google calendar. This stemmed from the fact that google often will return an HTTP Redirect which includes a url with an appended gsession attribute which you're supposed to resubmit the exact data from the first request to. Once I figured this out it was turtles all the way down. I even managed to get the whole script multi-threaded to speed things up since it's impossible to perform batch-requests with JSON-C.</p>
<p>I should note that for the configuration file the calendar should be the "Calendar ID" for the calendar that can be found by looking at the settings page for the individual calendar, it is grouped with the XML and iCal feeds.</p>
<p>ShowList.txt:<sup>[<a href="http://www.bemasher.net/archives/914#footnote_5_914" id="identifier_5_914" class="footnote-link footnote-identifier-link" title="You can find the show_id via the show search found on their XML API page.">6</a>]</sup></p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">Castle&nbsp; 19267<br />
House &nbsp; 3908<br />
Bones &nbsp; 2870<br />
Big Bang Theory, The&nbsp; &nbsp; 8511<br />
Mentalist, The&nbsp; 18967<br />
Rizzoli &amp; Isles 24996<br />
Venture Bros., The&nbsp; 6270<br />
Top Gear&nbsp; &nbsp; 6753<br />
Mythbusters 4605<br />
Archer&nbsp; 23354<br />
NCIS&nbsp; &nbsp; 4628<br />
Community &nbsp; 22589</div></td></tr></tbody></table></div>
<p>Config.cfg:</p>
<div class="codecolorer-container ini default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br /></div></td><td><div class="ini codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000066; font-weight:bold;"><span style="">&#91;</span>Credentials<span style="">&#93;</span></span><br />
<span style="color: #000099;">username</span> <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;"> someuser@gmail.com</span><br />
<span style="color: #000099;">password</span> <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;"> somebase64encodedpassword</span><br />
<span style="color: #000099;">calendar</span> <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;"> somecalendarid@group.calendar.google.com</span></div></td></tr></tbody></table></div>
<p>AirDate.py:</p>
<div class="codecolorer-container python default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;height:300px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br />28<br />29<br />30<br />31<br />32<br />33<br />34<br />35<br />36<br />37<br />38<br />39<br />40<br />41<br />42<br />43<br />44<br />45<br />46<br />47<br />48<br />49<br />50<br />51<br />52<br />53<br />54<br />55<br />56<br />57<br />58<br />59<br />60<br />61<br />62<br />63<br />64<br />65<br />66<br />67<br />68<br />69<br />70<br />71<br />72<br />73<br />74<br />75<br />76<br />77<br />78<br />79<br />80<br />81<br />82<br />83<br />84<br />85<br />86<br />87<br />88<br />89<br />90<br />91<br />92<br />93<br />94<br />95<br />96<br />97<br />98<br />99<br />100<br />101<br />102<br />103<br />104<br />105<br />106<br />107<br />108<br />109<br />110<br />111<br />112<br />113<br />114<br />115<br />116<br />117<br />118<br />119<br />120<br />121<br />122<br />123<br />124<br />125<br />126<br />127<br />128<br />129<br />130<br />131<br />132<br />133<br />134<br />135<br />136<br />137<br />138<br />139<br />140<br />141<br />142<br />143<br />144<br />145<br />146<br />147<br />148<br />149<br />150<br />151<br />152<br />153<br />154<br />155<br />156<br />157<br />158<br />159<br />160<br />161<br />162<br />163<br />164<br />165<br />166<br />167<br />168<br />169<br />170<br />171<br />172<br />173<br />174<br />175<br />176<br />177<br />178<br />179<br />180<br />181<br />182<br />183<br />184<br />185<br />186<br />187<br />188<br />189<br />190<br />191<br />192<br /></div></td><td><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">urllib2</span><span style="color: #66cc66;">,</span> <span style="color: #dc143c;">urllib</span><span style="color: #66cc66;">,</span> json<span style="color: #66cc66;">,</span> <span style="color: #dc143c;">ConfigParser</span><span style="color: #66cc66;">,</span> <span style="color: #dc143c;">base64</span><br />
<span style="color: #ff7700;font-weight:bold;">from</span> <span style="color: #dc143c;">datetime</span> <span style="color: #ff7700;font-weight:bold;">import</span> date<br />
<span style="color: #ff7700;font-weight:bold;">from</span> <span style="color: #dc143c;">xml</span>.<span style="color: black;">etree</span> <span style="color: #ff7700;font-weight:bold;">import</span> ElementTree<br />
<span style="color: #ff7700;font-weight:bold;">from</span> <span style="color: #dc143c;">threading</span> <span style="color: #ff7700;font-weight:bold;">import</span> Thread<br />
<br />
<span style="color: #dc143c;">calendar</span> <span style="color: #66cc66;">=</span> <span style="color: #483d8b;">&quot;&quot;</span><br />
header <span style="color: #66cc66;">=</span> <span style="color: black;">&#123;</span><span style="color: black;">&#125;</span><br />
<br />
<span style="color: #808080; font-style: italic;"># Thread for retrieving a list of episodes for a given show_id</span><br />
<span style="color: #ff7700;font-weight:bold;">class</span> airDate<span style="color: black;">&#40;</span>Thread<span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; <span style="color: #808080; font-style: italic;"># Initialize thread and set some local attributes</span><br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: #66cc66;">,</span> show_name<span style="color: #66cc66;">,</span> show_id<span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; Thread.<span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">self</span>.<span style="color: black;">show_name</span> <span style="color: #66cc66;">=</span> show_name<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">self</span>.<span style="color: black;">show_id</span> <span style="color: #66cc66;">=</span> show_id<br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #808080; font-style: italic;"># Get episode list from tvrage.com based on the show_id</span><br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">def</span> run<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;"># Retrieve XML episode_list from tvrage.com</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; xml_data <span style="color: #66cc66;">=</span> <span style="color: #dc143c;">urllib2</span>.<span style="color: black;">urlopen</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;http://services.tvrage.com/feeds/episode_list.php?sid=%s&quot;</span> % <span style="color: #008000;">self</span>.<span style="color: black;">show_id</span><span style="color: black;">&#41;</span>.<span style="color: black;">read</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;"># Pares XML into ElementTree.Element()</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; xml_tree <span style="color: #66cc66;">=</span> ElementTree.<span style="color: black;">fromstring</span><span style="color: black;">&#40;</span>xml_data<span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">self</span>.<span style="color: black;">result</span> <span style="color: #66cc66;">=</span> <span style="color: black;">&#91;</span><span style="color: black;">&#93;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;"># For each season</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">for</span> season <span style="color: #ff7700;font-weight:bold;">in</span> xml_tree.<span style="color: black;">findall</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;Episodelist/Season&quot;</span><span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;"># Get the season number</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; season_num <span style="color: #66cc66;">=</span> <span style="color: #008000;">int</span><span style="color: black;">&#40;</span>season.<span style="color: black;">get</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;no&quot;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;"># For each episode in the episode list</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">for</span> episode <span style="color: #ff7700;font-weight:bold;">in</span> season.<span style="color: black;">findall</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;episode&quot;</span><span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;"># Get episode number and title</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; episode_num <span style="color: #66cc66;">=</span> <span style="color: #008000;">int</span><span style="color: black;">&#40;</span>episode.<span style="color: black;">find</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;seasonnum&quot;</span><span style="color: black;">&#41;</span>.<span style="color: black;">text</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; episode_title <span style="color: #66cc66;">=</span> episode.<span style="color: black;">find</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;title&quot;</span><span style="color: black;">&#41;</span>.<span style="color: black;">text</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;"># Build the episode code S##E##</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; episode_code <span style="color: #66cc66;">=</span> <span style="color: #483d8b;">&quot;S%02dE%02d&quot;</span> % <span style="color: black;">&#40;</span>season_num<span style="color: #66cc66;">,</span> episode_num<span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;"># Parse the airdate into year, month and day</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; year<span style="color: #66cc66;">,</span> month<span style="color: #66cc66;">,</span> day <span style="color: #66cc66;">=</span> <span style="color: #008000;">map</span><span style="color: black;">&#40;</span><span style="color: #ff7700;font-weight:bold;">lambda</span> x: <span style="color: #008000;">int</span><span style="color: black;">&#40;</span>x<span style="color: black;">&#41;</span><span style="color: #66cc66;">,</span> episode.<span style="color: black;">find</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;airdate&quot;</span><span style="color: black;">&#41;</span>.<span style="color: black;">text</span>.<span style="color: black;">split</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;-&quot;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">try</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; episode_airdate <span style="color: #66cc66;">=</span> date<span style="color: black;">&#40;</span>year<span style="color: #66cc66;">,</span> month<span style="color: #66cc66;">,</span> day<span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; today <span style="color: #66cc66;">=</span> date.<span style="color: black;">today</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;"># If episode hasn't aired yet </span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">if</span> episode_airdate <span style="color: #66cc66;">&gt;=</span> today:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;"># Add episode to results list</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">self</span>.<span style="color: black;">result</span>.<span style="color: black;">append</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;%s %s - %s&quot;</span> % <span style="color: black;">&#40;</span><span style="color: #008000;">str</span><span style="color: black;">&#40;</span>episode_airdate<span style="color: black;">&#41;</span><span style="color: #66cc66;">,</span> <span style="color: #008000;">self</span>.<span style="color: black;">show_name</span><span style="color: #66cc66;">,</span> episode_code<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">except</span> <span style="color: #008000;">ValueError</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;"># If the airdate is invalid (tvrage.com sometimes</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;"># includes 00's for unknown sections of the date</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">pass</span><br />
<br />
<span style="color: #ff7700;font-weight:bold;">class</span> addEvent<span style="color: black;">&#40;</span>Thread<span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; <span style="color: #808080; font-style: italic;"># Thread for adding events to google calendar</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #808080; font-style: italic;"># Initialize thread and set local episode variable</span><br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: #66cc66;">,</span> episode<span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; Thread.<span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">self</span>.<span style="color: black;">episode</span> <span style="color: #66cc66;">=</span> episode<br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #808080; font-style: italic;"># Add new entry to google calendar</span><br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">def</span> run<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;"># Build entry structure</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; entry <span style="color: #66cc66;">=</span> <span style="color: black;">&#123;</span><span style="color: #483d8b;">&quot;data&quot;</span>: <span style="color: black;">&#123;</span><span style="color: #483d8b;">&quot;details&quot;</span>: <span style="color: #008000;">self</span>.<span style="color: black;">episode</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">&quot;quickAdd&quot;</span>: <span style="color: #008000;">True</span><span style="color: black;">&#125;</span><span style="color: black;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;"># Convert to JSON</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; entry <span style="color: #66cc66;">=</span> json.<span style="color: black;">dumps</span><span style="color: black;">&#40;</span>entry<span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;"># Build request including necessary headers and data</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; calReq <span style="color: #66cc66;">=</span> <span style="color: #dc143c;">urllib2</span>.<span style="color: black;">Request</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;http://www.google.com/calendar/feeds/%s/private/full?alt=jsonc&quot;</span> % <span style="color: black;">&#40;</span><span style="color: #dc143c;">calendar</span><span style="color: black;">&#41;</span><span style="color: #66cc66;">,</span> entry<span style="color: #66cc66;">,</span> header<span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;"># Execute the request</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; calRes <span style="color: #66cc66;">=</span> <span style="color: #dc143c;">urllib2</span>.<span style="color: black;">urlopen</span><span style="color: black;">&#40;</span>calReq<span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;"># Get the redirect url (gsession appended)</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; redirectReq <span style="color: #66cc66;">=</span> <span style="color: #dc143c;">urllib2</span>.<span style="color: black;">Request</span><span style="color: black;">&#40;</span>calRes.<span style="color: black;">geturl</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: #66cc66;">,</span> entry<span style="color: #66cc66;">,</span> header<span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">try</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; redirectRes <span style="color: #66cc66;">=</span> <span style="color: #dc143c;">urllib2</span>.<span style="color: black;">urlopen</span><span style="color: black;">&#40;</span>redirectReq<span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">except</span> HTTPError:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;"># If we get some sort of HTTP error code</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;"># skip entry, can always run again</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">pass</span><br />
&nbsp; &nbsp; <br />
<span style="color: #808080; font-style: italic;"># Get list of events already added to</span><br />
<span style="color: #808080; font-style: italic;"># the calendar from previous executions</span><br />
<span style="color: #ff7700;font-weight:bold;">def</span> getExistingEpisodes<span style="color: black;">&#40;</span>header<span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; <span style="color: #808080; font-style: italic;"># Get JSON-C representation of calendar</span><br />
&nbsp; &nbsp; calReq <span style="color: #66cc66;">=</span> <span style="color: #dc143c;">urllib2</span>.<span style="color: black;">Request</span><span style="color: black;">&#40;</span>url<span style="color: #66cc66;">=</span><span style="color: #483d8b;">&quot;https://www.google.com/calendar/feeds/%s/private/full?alt=jsonc&quot;</span> % <span style="color: black;">&#40;</span><span style="color: #dc143c;">calendar</span><span style="color: black;">&#41;</span><span style="color: #66cc66;">,</span> headers<span style="color: #66cc66;">=</span>header<span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; calRes <span style="color: #66cc66;">=</span> <span style="color: #dc143c;">urllib2</span>.<span style="color: black;">urlopen</span><span style="color: black;">&#40;</span>calReq<span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #808080; font-style: italic;"># Parse JSON-C</span><br />
&nbsp; &nbsp; data <span style="color: #66cc66;">=</span> json.<span style="color: black;">loads</span><span style="color: black;">&#40;</span>calRes.<span style="color: black;">read</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #808080; font-style: italic;"># If the calendar has events on it</span><br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #483d8b;">&quot;items&quot;</span> <span style="color: #ff7700;font-weight:bold;">in</span> data<span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;data&quot;</span><span style="color: black;">&#93;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;"># Get the list of events</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; events <span style="color: #66cc66;">=</span> data<span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;data&quot;</span><span style="color: black;">&#93;</span><span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;items&quot;</span><span style="color: black;">&#93;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; existing_episodes <span style="color: #66cc66;">=</span> <span style="color: black;">&#91;</span><span style="color: black;">&#93;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;"># For each event</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">for</span> event <span style="color: #ff7700;font-weight:bold;">in</span> events:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;"># Append just the title of the event to the results</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; existing_episodes.<span style="color: black;">append</span><span style="color: black;">&#40;</span>event<span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;title&quot;</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">return</span> existing_episodes<br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">else</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;"># We don't have any events on this calendar</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;"># so just return an empty list</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: black;">&#91;</span><span style="color: black;">&#93;</span><br />
<br />
<span style="color: #ff7700;font-weight:bold;">if</span> __name__ <span style="color: #66cc66;">==</span> <span style="color: #483d8b;">'__main__'</span>:<br />
&nbsp; &nbsp; <span style="color: #808080; font-style: italic;"># Open the configuration file and get the necessary</span><br />
&nbsp; &nbsp; <span style="color: #808080; font-style: italic;"># credentials and settings</span><br />
&nbsp; &nbsp; config <span style="color: #66cc66;">=</span> <span style="color: #dc143c;">ConfigParser</span>.<span style="color: #dc143c;">ConfigParser</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; config.<span style="color: black;">readfp</span><span style="color: black;">&#40;</span><span style="color: #008000;">open</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;Config.cfg&quot;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; username <span style="color: #66cc66;">=</span> config.<span style="color: black;">get</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;Credentials&quot;</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">&quot;username&quot;</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; password <span style="color: #66cc66;">=</span> config.<span style="color: black;">get</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;Credentials&quot;</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">&quot;password&quot;</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #808080; font-style: italic;"># Password is stored as base64 encoded string just so</span><br />
&nbsp; &nbsp; <span style="color: #808080; font-style: italic;"># we don't have our password sitting out in plain sight</span><br />
&nbsp; &nbsp; password <span style="color: #66cc66;">=</span> <span style="color: #dc143c;">base64</span>.<span style="color: black;">b64decode</span><span style="color: black;">&#40;</span>password<span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #dc143c;">calendar</span> <span style="color: #66cc66;">=</span> config.<span style="color: black;">get</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;Credentials&quot;</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">&quot;calendar&quot;</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #808080; font-style: italic;"># Build loginData structure, this is used to get</span><br />
&nbsp; &nbsp; <span style="color: #808080; font-style: italic;"># authentication data from google</span><br />
&nbsp; &nbsp; loginData <span style="color: #66cc66;">=</span> <span style="color: black;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #483d8b;">&quot;Email&quot;</span>: username<span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #483d8b;">&quot;Passwd&quot;</span>: password<span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #483d8b;">&quot;source&quot;</span>: <span style="color: #483d8b;">&quot;BeMasher-ETR-2&quot;</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #483d8b;">&quot;service&quot;</span>: <span style="color: #483d8b;">&quot;cl&quot;</span><br />
&nbsp; &nbsp; <span style="color: black;">&#125;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #808080; font-style: italic;"># Encode the loginData for usage in a url</span><br />
&nbsp; &nbsp; loginData <span style="color: #66cc66;">=</span> <span style="color: #dc143c;">urllib</span>.<span style="color: black;">urlencode</span><span style="color: black;">&#40;</span>loginData<span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #808080; font-style: italic;"># Get authentication data</span><br />
&nbsp; &nbsp; gdataLogin <span style="color: #66cc66;">=</span> <span style="color: #dc143c;">urllib2</span>.<span style="color: black;">urlopen</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;https://www.google.com/accounts/ClientLogin&quot;</span><span style="color: #66cc66;">,</span> data<span style="color: #66cc66;">=</span>loginData<span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; SID<span style="color: #66cc66;">,</span> LSID<span style="color: #66cc66;">,</span> Auth <span style="color: #66cc66;">=</span> gdataLogin.<span style="color: black;">read</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>.<span style="color: black;">splitlines</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #808080; font-style: italic;"># Build header structure, this will be used for</span><br />
&nbsp; &nbsp; <span style="color: #808080; font-style: italic;"># all requests to google calendar from now on</span><br />
&nbsp; &nbsp; header <span style="color: #66cc66;">=</span> <span style="color: black;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #483d8b;">&quot;Authorization&quot;</span>: <span style="color: #483d8b;">&quot;GoogleLogin %s&quot;</span> % <span style="color: black;">&#40;</span>Auth<span style="color: black;">&#41;</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #483d8b;">&quot;GData-Version&quot;</span>: <span style="color: #ff4500;">2</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #483d8b;">&quot;Content-Type&quot;</span>: <span style="color: #483d8b;">&quot;application/json&quot;</span><br />
&nbsp; &nbsp; <span style="color: black;">&#125;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #808080; font-style: italic;"># Open a list of the shows we're interested in</span><br />
&nbsp; &nbsp; <span style="color: #808080; font-style: italic;"># Stored as &quot;show_name\tshow_id&quot;, one per line</span><br />
&nbsp; &nbsp; show_list <span style="color: #66cc66;">=</span> <span style="color: #008000;">open</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;ShowList.txt&quot;</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; jobs <span style="color: #66cc66;">=</span> <span style="color: black;">&#91;</span><span style="color: black;">&#93;</span><br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">for</span> line <span style="color: #ff7700;font-weight:bold;">in</span> show_list:<br />
&nbsp; &nbsp; &nbsp; &nbsp; show <span style="color: #66cc66;">=</span> line.<span style="color: black;">strip</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>.<span style="color: black;">split</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;<span style="color: #000099; font-weight: bold;">\t</span>&quot;</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; jobs.<span style="color: black;">append</span><span style="color: black;">&#40;</span>show<span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #808080; font-style: italic;"># Get a list of existing events from previous</span><br />
&nbsp; &nbsp; <span style="color: #808080; font-style: italic;"># executions so we don't wind up with duplicates</span><br />
&nbsp; &nbsp; existingEpisodes <span style="color: #66cc66;">=</span> getExistingEpisodes<span style="color: black;">&#40;</span>header<span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; threadQueue <span style="color: #66cc66;">=</span> <span style="color: black;">&#91;</span><span style="color: black;">&#93;</span><br />
&nbsp; &nbsp; <span style="color: #808080; font-style: italic;"># For each episode we've retrieved that is unaired</span><br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">for</span> job <span style="color: #ff7700;font-weight:bold;">in</span> jobs:<br />
&nbsp; &nbsp; &nbsp; &nbsp; show_name<span style="color: #66cc66;">,</span> show_id <span style="color: #66cc66;">=</span> job<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;"># Create an instance of the airDate thread</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #dc143c;">thread</span> <span style="color: #66cc66;">=</span> airDate<span style="color: black;">&#40;</span>show_name<span style="color: #66cc66;">,</span> show_id<span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;"># Start it</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #dc143c;">thread</span>.<span style="color: black;">start</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;"># Add it to the threadQueue</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; threadQueue.<span style="color: black;">append</span><span style="color: black;">&#40;</span><span style="color: #dc143c;">thread</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; episodes <span style="color: #66cc66;">=</span> <span style="color: black;">&#91;</span><span style="color: black;">&#93;</span><br />
&nbsp; &nbsp; <span style="color: #808080; font-style: italic;"># While we've still got running threads</span><br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">while</span> <span style="color: #008000;">len</span><span style="color: black;">&#40;</span>threadQueue<span style="color: black;">&#41;</span> <span style="color: #66cc66;">&gt;</span> <span style="color: #ff4500;">0</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;"># Get a thread from the queue</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #dc143c;">thread</span> <span style="color: #66cc66;">=</span> threadQueue.<span style="color: black;">pop</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;"># Block until it completes</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #dc143c;">thread</span>.<span style="color: black;">join</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;"># For each episode in the results</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">for</span> episode <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #dc143c;">thread</span>.<span style="color: black;">result</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;"># If it hasn't already been added to google calendar</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">if</span> episode<span style="color: black;">&#91;</span><span style="color: #ff4500;">11</span>:<span style="color: black;">&#93;</span> <span style="color: #ff7700;font-weight:bold;">not</span> <span style="color: #ff7700;font-weight:bold;">in</span> existingEpisodes:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">print</span> episode<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;"># Add to list of episodes that need events created</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; episodes.<span style="color: black;">append</span><span style="color: black;">&#40;</span>episode<span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #808080; font-style: italic;"># For each episode that doesn't have an</span><br />
&nbsp; &nbsp; <span style="color: #808080; font-style: italic;"># event on google calendar already</span><br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">for</span> episode <span style="color: #ff7700;font-weight:bold;">in</span> episodes:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;"># Create an addEvent thread, start it</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;"># and add it to the threadQueue</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #dc143c;">thread</span> <span style="color: #66cc66;">=</span> addEvent<span style="color: black;">&#40;</span>episode<span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #dc143c;">thread</span>.<span style="color: black;">start</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; threadQueue.<span style="color: black;">append</span><span style="color: black;">&#40;</span><span style="color: #dc143c;">thread</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #808080; font-style: italic;"># While we still have threads running</span><br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">while</span> <span style="color: #008000;">len</span><span style="color: black;">&#40;</span>threadQueue<span style="color: black;">&#41;</span> <span style="color: #66cc66;">&gt;</span> <span style="color: #ff4500;">0</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;"># Get a thread from the queue</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #dc143c;">thread</span> <span style="color: #66cc66;">=</span> threadQueue.<span style="color: black;">pop</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;"># Block until it completes</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #dc143c;">thread</span>.<span style="color: black;">join</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></div></td></tr></tbody></table></div>
<p>This was all done shortly before I discovered that tvrage.com also provides iCal feeds for your favorite shows provided that you register and add some to your list. Unfortunately the iCal feed they generate creates events for exact air times of each episode which I'm not really all that concerned about. So I use this script still to add all-day events for each episode which is easier to view//see when there's a new episode.</p>
<p>I did write another script using their XML API but that will have to wait for another post.</p>
<ol class="footnotes"><li id="footnote_0_914" class="footnote"><a href="http://tvrage.com/">http://tvrage.com/</a></li><li id="footnote_1_914" class="footnote"><a href="http://services.tvrage.com/">http://services.tvrage.com/</a></li><li id="footnote_2_914" class="footnote"><a href="http://code.google.com/apis/calendar/docs/2.0/developers_guide_protocol.html">Data API Developer's Guide: The Protocol</a></li><li id="footnote_3_914" class="footnote">Google's own flavor of JSON which is almost identical to plain old JSON.</li><li id="footnote_4_914" class="footnote">I only really needed the  original air date, title, season number and episode number.</li><li id="footnote_5_914" class="footnote">You can find the show_id via the show search found on their XML API page.</li></ol>]]></content:encoded>
			<wfw:commentRss>http://www.bemasher.net/archives/914/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Matplotlib and Live Data: A Tale of Two Technologies</title>
		<link>http://www.bemasher.net/archives/813?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=matplotlib-and-live-data-the-tale-of-two-technologies</link>
		<comments>http://www.bemasher.net/archives/813#comments</comments>
		<pubDate>Thu, 29 Jul 2010 04:46:53 +0000</pubDate>
		<dc:creator>bemasher</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Arduino]]></category>
		<category><![CDATA[data]]></category>
		<category><![CDATA[DS18B20]]></category>
		<category><![CDATA[DS18S20]]></category>
		<category><![CDATA[DS18X20]]></category>
		<category><![CDATA[gtk]]></category>
		<category><![CDATA[Live]]></category>
		<category><![CDATA[matplotlib]]></category>
		<category><![CDATA[OneWire]]></category>
		<category><![CDATA[pySerial]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[temperature]]></category>

		<guid isPermaLink="false">http://www.bemasher.net/?p=813</guid>
		<description><![CDATA[Being unemployed over the summer is never usually a good thing for me. I get bored very easily if I don't have something to occupy myself with. This last bout of boredom led me to unpack some of my electronics. Dusted off my multimeter, Arduino and a digital thermometer I bought a little while ago. [...]]]></description>
			<content:encoded><![CDATA[<p>Being unemployed over the summer is never usually a good thing for me. I get bored very easily if I don't have something to occupy myself with. This last bout of boredom led me to unpack some of my electronics. Dusted off my multimeter, Arduino and a digital thermometer I bought a little while ago. Figured I could use these to solve one of my current problems.</p>
<p>Living in Laramie usually subjects people to harsh winters which leaves most housing developments without central air conditioning installed since, well it's never really needed except maybe one or two days over the summer where it gets above 85 <sup>o</sup>F. This summer has apparently been hotter than previous summers and It's left my condo in an "uncomfortable state". Mind you I'm used to living in hot weather so this isn't such a terrible thing to me, I'm used to it. </p>
<p>What I'm not used to is not having AC and it cooling off enough at night that it's worthwhile to open a few windows and stick a fan in one of them. Which leaves me with this problem: When is the optimal time to open the windows and turn on the fan to get my condo cooled off earliest//fastest?</p>
<p>In comes my Arduino + digital thermometer<sup>[<a href="http://www.bemasher.net/archives/813#footnote_0_813" id="identifier_0_813" class="footnote-link footnote-identifier-link" title="DS18S20 Digital Thermometer Datasheet">1</a>]</sup>. Once I rigged up the proper power//data connections on a breadboard for my Arduino I set out to find code for the thermometer. I've setup the thermometer with a sketch on my Arduino before I just didn't feel like wasting a few hours trying to do it from scratch again. Soon enough I found some code<sup>[<a href="http://www.bemasher.net/archives/813#footnote_1_813" id="identifier_1_813" class="footnote-link footnote-identifier-link" title="Temperature Measurement using the Dallas DS18B20 by Peter H. Anderson">2</a>]</sup> that worked perfectly. So I trimmed out some code I didn't need for the project and set it up to just write the temperature as fast as possible<sup>[<a href="http://www.bemasher.net/archives/813#footnote_2_813" id="identifier_2_813" class="footnote-link footnote-identifier-link" title="Somewhere in the range of 750ms between readings since it is in parasite mode, may change this later to run in non-parasite mode.">3</a>]</sup> to the serial port it's connected to.</p>
<p>After that I wrote a logging program on my desktop in Python to record temperatures sent via serial to my desktop. The program is incredibly simple and uses the pySerial library<sup>[<a href="http://www.bemasher.net/archives/813#footnote_3_813" id="identifier_3_813" class="footnote-link footnote-identifier-link" title="pySerial Python Library">4</a>]</sup> to read temperatures from the serial port of my desktop and append them to a temperature log. I used a simple windows command to do this since it wouldn't lock the file so I could read data from it simultaneously. There are still occasionally collisions with the processing program locking the file and the logger not being able to write the data to the file but these are rare enough that it's negligible in my situation.</p>
<div class="codecolorer-container python default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br /></div></td><td><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #ff7700;font-weight:bold;">import</span> serial<span style="color: #66cc66;">,</span> <span style="color: #dc143c;">os</span><br />
<br />
ser <span style="color: #66cc66;">=</span> serial.<span style="color: black;">Serial</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">2</span><span style="color: black;">&#41;</span><br />
<span style="color: #ff7700;font-weight:bold;">while</span> <span style="color: #008000;">True</span>:<br />
&nbsp; &nbsp; <span style="color: #dc143c;">os</span>.<span style="color: black;">system</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;echo %s&gt;&gt;out.txt&quot;</span> % <span style="color: black;">&#40;</span>ser.<span style="color: #dc143c;">readline</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>.<span style="color: black;">strip</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span></div></td></tr></tbody></table></div>
<p>The next step in this project was visualizing the data. I've used matplotlib<sup>[<a href="http://www.bemasher.net/archives/813#footnote_4_813" id="identifier_4_813" class="footnote-link footnote-identifier-link" title="matplotlib Python Library">5</a>]</sup> before and I was thinking this time I would like to see if I could write the program to update data live as it recieves it. My first foray into this goal was a miserable disaster. Most of the solutions I could find involved just setting up an infinite loop with a short time delay in it. Which works great except that it sleeps the thread running the plot which makes it impossible to resize the plot or do anything at all with the GUI for that matter. So obviosly this wouldn't work at all.</p>
<p>After poking around for different solutions to this and crashing my computer once from spawning an infinite number of instances of the plot I gave up for a bit, only to discover that there was an example in the documentation which wasn't obviously named. I quickly discovered the best way to do this. I even added some pretty annotations and such.</p>
<div class="codecolorer-container python default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;height:300px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br />28<br />29<br />30<br />31<br />32<br />33<br />34<br />35<br />36<br />37<br />38<br />39<br />40<br />41<br />42<br />43<br />44<br />45<br />46<br />47<br />48<br />49<br />50<br />51<br />52<br />53<br />54<br />55<br />56<br />57<br />58<br />59<br />60<br />61<br />62<br />63<br />64<br />65<br />66<br />67<br />68<br />69<br />70<br />71<br />72<br />73<br />74<br />75<br />76<br />77<br />78<br />79<br />80<br />81<br />82<br />83<br />84<br />85<br /></div></td><td><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #ff7700;font-weight:bold;">import</span> gobject<br />
<span style="color: #ff7700;font-weight:bold;">import</span> matplotlib<br />
matplotlib.<span style="color: black;">use</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'GTKAgg'</span><span style="color: black;">&#41;</span><br />
<br />
<span style="color: #ff7700;font-weight:bold;">import</span> matplotlib.<span style="color: black;">pyplot</span> <span style="color: #ff7700;font-weight:bold;">as</span> plt<br />
<br />
current_pos <span style="color: #66cc66;">=</span> <span style="color: #ff4500;">0</span><br />
temps <span style="color: #66cc66;">=</span> <span style="color: black;">&#91;</span><span style="color: black;">&#93;</span><br />
pad <span style="color: #66cc66;">=</span> <span style="color: #ff4500;">5.0</span><br />
<br />
f <span style="color: #66cc66;">=</span> plt.<span style="color: black;">figure</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><br />
<br />
<span style="color: #ff7700;font-weight:bold;">def</span> update<span style="color: black;">&#40;</span><span style="color: #008000;">vars</span><span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; <span style="color: #808080; font-style: italic;"># Unpack variables that need to be persistent between</span><br />
&nbsp; &nbsp; <span style="color: #808080; font-style: italic;"># executions of this method.</span><br />
&nbsp; &nbsp; temps <span style="color: #66cc66;">=</span> <span style="color: #008000;">vars</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span><br />
&nbsp; &nbsp; current_pos <span style="color: #66cc66;">=</span> <span style="color: #008000;">vars</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span><br />
&nbsp; &nbsp; pad <span style="color: #66cc66;">=</span> <span style="color: #008000;">vars</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">2</span><span style="color: black;">&#93;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #808080; font-style: italic;"># Open the data file and get any new data points since</span><br />
&nbsp; &nbsp; <span style="color: #808080; font-style: italic;"># the last time we read from this file</span><br />
&nbsp; &nbsp; data <span style="color: #66cc66;">=</span> <span style="color: #008000;">open</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;out.txt&quot;</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">&quot;r&quot;</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; data.<span style="color: black;">seek</span><span style="color: black;">&#40;</span>current_pos<span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; new_temps <span style="color: #66cc66;">=</span> <span style="color: #008000;">map</span><span style="color: black;">&#40;</span><span style="color: #ff7700;font-weight:bold;">lambda</span> x:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">float</span><span style="color: black;">&#40;</span>x<span style="color: black;">&#41;</span> * <span style="color: black;">&#40;</span><span style="color: #ff4500;">1</span> + <span style="color: #ff4500;">4.0</span>/<span style="color: #ff4500;">5.0</span><span style="color: black;">&#41;</span> + <span style="color: #ff4500;">32.0</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; data.<span style="color: black;">read</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>.<span style="color: black;">split</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: black;">&#41;</span><span style="color: black;">&#91;</span>:-<span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; current_pos <span style="color: #66cc66;">=</span> data.<span style="color: black;">tell</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; data.<span style="color: black;">close</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #808080; font-style: italic;"># If we got new data then append it to the list of</span><br />
&nbsp; &nbsp; <span style="color: #808080; font-style: italic;"># temperatures and trim to 750 points</span><br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #008000;">len</span><span style="color: black;">&#40;</span>new_temps<span style="color: black;">&#41;</span> <span style="color: #66cc66;">&gt;</span> <span style="color: #ff4500;">0</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; temps.<span style="color: black;">extend</span><span style="color: black;">&#40;</span>new_temps<span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; temps <span style="color: #66cc66;">=</span> temps<span style="color: black;">&#91;</span>-<span style="color: #ff4500;">750</span>:<span style="color: black;">&#93;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; f.<span style="color: black;">clear</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; f.<span style="color: black;">suptitle</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;Live Temperature&quot;</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; a <span style="color: #66cc66;">=</span> f.<span style="color: black;">add_subplot</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">111</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; a.<span style="color: black;">grid</span><span style="color: black;">&#40;</span><span style="color: #008000;">True</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; l<span style="color: #66cc66;">,</span> <span style="color: #66cc66;">=</span> a.<span style="color: black;">plot</span><span style="color: black;">&#40;</span>temps<span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; plt.<span style="color: black;">xlabel</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;Time (Seconds)&quot;</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; plt.<span style="color: black;">ylabel</span><span style="color: black;">&#40;</span>r<span style="color: #483d8b;">'Temperature $^{<span style="color: #000099; font-weight: bold;">\c</span>irc}$F'</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #808080; font-style: italic;"># Get the minimum and maximum temperatures these are</span><br />
&nbsp; &nbsp; <span style="color: #808080; font-style: italic;"># used for annotations and scaling the plot of data</span><br />
&nbsp; &nbsp; min_t <span style="color: #66cc66;">=</span> <span style="color: #008000;">min</span><span style="color: black;">&#40;</span>temps<span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; max_t <span style="color: #66cc66;">=</span> <span style="color: #008000;">max</span><span style="color: black;">&#40;</span>temps<span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #808080; font-style: italic;"># Add annotations for minimum and maximum temperatures</span><br />
&nbsp; &nbsp; a.<span style="color: black;">annotate</span><span style="color: black;">&#40;</span>r<span style="color: #483d8b;">'Min: %0.2f$^{<span style="color: #000099; font-weight: bold;">\c</span>irc}$F'</span> % <span style="color: black;">&#40;</span>min_t<span style="color: black;">&#41;</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; xy<span style="color: #66cc66;">=</span><span style="color: black;">&#40;</span>temps.<span style="color: black;">index</span><span style="color: black;">&#40;</span>min_t<span style="color: black;">&#41;</span><span style="color: #66cc66;">,</span> min_t<span style="color: black;">&#41;</span><span style="color: #66cc66;">,</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; xycoords<span style="color: #66cc66;">=</span><span style="color: #483d8b;">'data'</span><span style="color: #66cc66;">,</span> xytext<span style="color: #66cc66;">=</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">20</span><span style="color: #66cc66;">,</span> -<span style="color: #ff4500;">20</span><span style="color: black;">&#41;</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; textcoords<span style="color: #66cc66;">=</span><span style="color: #483d8b;">'offset points'</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; bbox<span style="color: #66cc66;">=</span><span style="color: #008000;">dict</span><span style="color: black;">&#40;</span>boxstyle<span style="color: #66cc66;">=</span><span style="color: #483d8b;">&quot;round&quot;</span><span style="color: #66cc66;">,</span> fc<span style="color: #66cc66;">=</span><span style="color: #483d8b;">&quot;0.8&quot;</span><span style="color: black;">&#41;</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; arrowprops<span style="color: #66cc66;">=</span><span style="color: #008000;">dict</span><span style="color: black;">&#40;</span>arrowstyle<span style="color: #66cc66;">=</span><span style="color: #483d8b;">&quot;-&gt;&quot;</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; shrinkA<span style="color: #66cc66;">=</span><span style="color: #ff4500;">0</span><span style="color: #66cc66;">,</span> shrinkB<span style="color: #66cc66;">=</span><span style="color: #ff4500;">1</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; connectionstyle<span style="color: #66cc66;">=</span><span style="color: #483d8b;">&quot;angle,angleA=0,angleB=90,rad=10&quot;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span><br />
<br />
&nbsp; &nbsp; a.<span style="color: black;">annotate</span><span style="color: black;">&#40;</span>r<span style="color: #483d8b;">'Max: %0.2f$^{<span style="color: #000099; font-weight: bold;">\c</span>irc}$F'</span> % <span style="color: black;">&#40;</span>max_t<span style="color: black;">&#41;</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; xy<span style="color: #66cc66;">=</span><span style="color: black;">&#40;</span>temps.<span style="color: black;">index</span><span style="color: black;">&#40;</span>max_t<span style="color: black;">&#41;</span><span style="color: #66cc66;">,</span> max_t<span style="color: black;">&#41;</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; xycoords<span style="color: #66cc66;">=</span><span style="color: #483d8b;">'data'</span><span style="color: #66cc66;">,</span> xytext<span style="color: #66cc66;">=</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">20</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">20</span><span style="color: black;">&#41;</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; textcoords<span style="color: #66cc66;">=</span><span style="color: #483d8b;">'offset points'</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; bbox<span style="color: #66cc66;">=</span><span style="color: #008000;">dict</span><span style="color: black;">&#40;</span>boxstyle<span style="color: #66cc66;">=</span><span style="color: #483d8b;">&quot;round&quot;</span><span style="color: #66cc66;">,</span> fc<span style="color: #66cc66;">=</span><span style="color: #483d8b;">&quot;0.8&quot;</span><span style="color: black;">&#41;</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; arrowprops<span style="color: #66cc66;">=</span><span style="color: #008000;">dict</span><span style="color: black;">&#40;</span>arrowstyle<span style="color: #66cc66;">=</span><span style="color: #483d8b;">&quot;-&gt;&quot;</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; shrinkA<span style="color: #66cc66;">=</span><span style="color: #ff4500;">0</span><span style="color: #66cc66;">,</span> shrinkB<span style="color: #66cc66;">=</span><span style="color: #ff4500;">1</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; connectionstyle<span style="color: #66cc66;">=</span><span style="color: #483d8b;">&quot;angle,angleA=0,angleB=90,rad=10&quot;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #808080; font-style: italic;"># Set the axis limits to make the data more readable</span><br />
&nbsp; &nbsp; a.<span style="color: black;">axis</span><span style="color: black;">&#40;</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: #66cc66;">,</span><span style="color: #008000;">len</span><span style="color: black;">&#40;</span>temps<span style="color: black;">&#41;</span><span style="color: #66cc66;">,</span> min_t - pad<span style="color: #66cc66;">,</span>max_t + pad<span style="color: black;">&#93;</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; f.<span style="color: black;">canvas</span>.<span style="color: black;">draw_idle</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #808080; font-style: italic;"># Repack variables that need to be persistent between</span><br />
&nbsp; &nbsp; <span style="color: #808080; font-style: italic;"># executions of this method</span><br />
&nbsp; &nbsp; <span style="color: #008000;">vars</span> <span style="color: #66cc66;">=</span> <span style="color: black;">&#123;</span><span style="color: #ff4500;">0</span>: temps<span style="color: #66cc66;">,</span> <span style="color: #ff4500;">1</span>: current_pos<span style="color: #66cc66;">,</span> <span style="color: #ff4500;">2</span>: pad<span style="color: black;">&#125;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #008000;">True</span><br />
<br />
<span style="color: #008000;">vars</span> <span style="color: #66cc66;">=</span> <span style="color: black;">&#123;</span><span style="color: #ff4500;">0</span>: temps<span style="color: #66cc66;">,</span> <span style="color: #ff4500;">1</span>: current_pos<span style="color: #66cc66;">,</span> <span style="color: #ff4500;">2</span>: pad<span style="color: black;">&#125;</span><br />
<br />
<span style="color: #808080; font-style: italic;"># Execute update method every 500ms</span><br />
gobject.<span style="color: black;">timeout_add</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">500</span><span style="color: #66cc66;">,</span> update<span style="color: #66cc66;">,</span> <span style="color: #008000;">vars</span><span style="color: black;">&#41;</span><br />
<br />
<span style="color: #808080; font-style: italic;"># Display the plot</span><br />
plt.<span style="color: black;">show</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></div></td></tr></tbody></table></div>
<p>This code generates a plot which updates every 500ms. This is based on an example in the matplotlib examples<sup>[<a href="http://www.bemasher.net/archives/813#footnote_5_813" id="identifier_5_813" class="footnote-link footnote-identifier-link" title="Animation example code: simple_anim_gtk.py">6</a>]</sup>. An example of the program's output can be seen below.</p>
<p><center><img src="http://lh4.ggpht.com/_67X_BsG0Kiw/TFEFttg0AlI/AAAAAAAAHxk/mwXxOtaC_tQ/s800/Output.png" /></center></p>
<p>I imagine that I could have made this simpler by not using the GTK libraries which are a pain to install since there are 3 or 4 modules you have to install in order to make all this work including the GTK+ runtime. I may come back later and post a version written using TK since it can be used without installing extra modules and stuff.</p>
<ol class="footnotes"><li id="footnote_0_813" class="footnote"><a href="http://datasheets.maxim-ic.com/en/ds/DS18S20.pdf">DS18S20 Digital Thermometer Datasheet</a></li><li id="footnote_1_813" class="footnote"><a href="http://www.phanderson.com/arduino/ds18b20_1.html">Temperature Measurement using the Dallas DS18B20 by Peter H. Anderson</a></li><li id="footnote_2_813" class="footnote">Somewhere in the range of 750ms between readings since it is in parasite mode, may change this later to run in non-parasite mode.</li><li id="footnote_3_813" class="footnote"><a href="http://pyserial.sourceforge.net/">pySerial Python Library</a></li><li id="footnote_4_813" class="footnote"><a href="http://matplotlib.sourceforge.net/">matplotlib Python Library</a></li><li id="footnote_5_813" class="footnote"><a href="http://matplotlib.sourceforge.net/examples/animation/simple_anim_gtk.html">Animation example code: simple_anim_gtk.py</a></li></ol>]]></content:encoded>
			<wfw:commentRss>http://www.bemasher.net/archives/813/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Comcast&#8217;s Data Usage Meter</title>
		<link>http://www.bemasher.net/archives/679?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=comcasts-data-usage-meter</link>
		<comments>http://www.bemasher.net/archives/679#comments</comments>
		<pubDate>Wed, 02 Dec 2009 23:38:53 +0000</pubDate>
		<dc:creator>bemasher</dc:creator>
				<category><![CDATA[Networking]]></category>
		<category><![CDATA[ack]]></category>
		<category><![CDATA[bandwidth]]></category>
		<category><![CDATA[bittorrent]]></category>
		<category><![CDATA[comcast]]></category>
		<category><![CDATA[data]]></category>
		<category><![CDATA[data usage]]></category>
		<category><![CDATA[dd-wrt]]></category>
		<category><![CDATA[gauge]]></category>
		<category><![CDATA[linksys]]></category>
		<category><![CDATA[router]]></category>
		<category><![CDATA[traffic]]></category>

		<guid isPermaLink="false">http://www.bemasher.net/?p=679</guid>
		<description><![CDATA[It looks like Comcast is starting to roll out a data usage meter to customers in the Portland, OR area so they can gauge how far along they are in their 250GB per year limit. According to Gizmodo, Comcast says their median data usage is 2-4GB per month. I thought this was hilarious so I [...]]]></description>
			<content:encoded><![CDATA[<p>It looks like Comcast is starting to roll out a data usage meter to customers in the Portland, OR area so they can gauge how far along they are in their 250GB per year limit. According to Gizmodo, Comcast says their median data usage is 2-4GB per month. I thought this was hilarious so I decided to do a little calculating of my own.</p>
<p>I've got a Linksys WRT-something-or-other router which I've installed DD-WRT on. Recent versions of the firmware have a section that keeps track of overall traffic through WAN that your router handles. It also makes it pretty easy to do a little calculation of your own with it since you can download the data in text format. It logs in terms of total data in and out per day of each month. November was my first full month of data excluding the the first of the month (something broke that day I guess), so I downloaded the log and looked at November's data.</p>
<p>On average we downloaded 1917MB per day and uploaded 562MB per day. This is the total traffic between 3 people. Grand total we downloaded 54GB and uploaded 16GB. If we take a look at the ratio between the two I can approximate what our actual bandwidth is. We're supposed to have a 20Mb down connection and the ratio suggests that our up bandwidth is ~5.86Mb which means our maximum upload rate is 750KB/s which we've never achieved before. When I use bittorrent to download Linux ISO's I assume that in order to not choke our router with ACK's I need to throttle the upload rate to about 70% of the maximum which hovers around about 120-130KB/s which is ~1Mb/s even and that's only 70% of the max.</p>
<p>Basically I wouldn't survive if I had Comcast and a 250GB limit per year.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bemasher.net/archives/679/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

