<?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>Mike&#039;s Blabberings &#187; tips &amp; tricks</title>
	<atom:link href="http://www.mike-griffith.com/blog/tag/tips-tricks/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.mike-griffith.com/blog</link>
	<description>on software, testing, and the web.</description>
	<lastBuildDate>Tue, 29 Jun 2010 14:37:52 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Browser history sniffing with Dojo</title>
		<link>http://www.mike-griffith.com/blog/2010/01/browser-history-sniffing-with-dojo/</link>
		<comments>http://www.mike-griffith.com/blog/2010/01/browser-history-sniffing-with-dojo/#comments</comments>
		<pubDate>Thu, 14 Jan 2010 06:40:52 +0000</pubDate>
		<dc:creator>Mike</dc:creator>
				<category><![CDATA[software development]]></category>
		<category><![CDATA[css]]></category>
		<category><![CDATA[dojo]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[tips & tricks]]></category>

		<guid isPermaLink="false">http://www.mike-griffith.com/blog/?p=346</guid>
		<description><![CDATA[Niall Kennedy posted a now-famous article about using some browser trickery to determine what websites a user on your site has visited.  I&#8217;ve taken that concept and created a module that can be used with the Dojo Toolkit javascript framework.
It provides two methods that you can use in your code, isVisited and isAnyVisited.
One important [...]]]></description>
			<content:encoded><![CDATA[<p>Niall Kennedy posted a <a href="http://www.niallkennedy.com/blog/2008/02/browser-history-sniff.html" target="_blank">now-famous article</a> about using some browser trickery to determine what websites a user on your site has visited.  I&#8217;ve taken that concept and created a module that can be used with the <a href="http://www.dojotoolkit.org/" target="_blank">Dojo Toolkit</a> javascript framework.</p>
<p>It provides two methods that you can use in your code, <code>isVisited</code> and <code>isAnyVisited</code>.</p>
<p>One important note about your URL specification is that you must specify an *exact* URL that the user has been to.  So, for example, if someone has visited several twitter profiles, but never actually went to the homepage or signin screen, then it would be difficult/impossible to tell whether or not they were a twitter user without a massive brute-force query.</p>
<p>You can download <a href="/js/dojo1.4/mdg/sniff.js" target="_blank">sniff.js</a>, or <a href="/code/browsersniff.html" target="_blank">view a demo</a>.</p>
<p><strong>Sample usage:</strong></p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">dojo.<span style="color: #660066;">require</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;mdg.sniff&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #003366; font-weight: bold;">var</span> usedYahoo <span style="color: #339933;">=</span> mdg.<span style="color: #660066;">sniff</span>.<span style="color: #660066;">isVisited</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;http://www.yahoo.com&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #003366; font-weight: bold;">var</span> usedGoogleMaps <span style="color: #339933;">=</span> mdg.<span style="color: #660066;">sniff</span>.<span style="color: #660066;">isAnyVisited</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#91;</span>
      <span style="color: #3366CC;">&quot;http://maps.google.com&quot;</span><span style="color: #339933;">,</span>
      <span style="color: #3366CC;">&quot;http://maps.google.com/maps&quot;</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #003366; font-weight: bold;">var</span> usedFacebook <span style="color: #339933;">=</span> mdg.<span style="color: #660066;">sniff</span>.<span style="color: #660066;">isAnyVisited</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#91;</span>
      <span style="color: #3366CC;">&quot;http://www.facebook.com&quot;</span><span style="color: #339933;">,</span>
      <span style="color: #3366CC;">&quot;http://www.facebook.com/index.php&quot;</span><span style="color: #339933;">,</span>
      <span style="color: #3366CC;">&quot;https://login.facebook.com/login.php&quot;</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p><strong>Source code:</strong></p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">dojo.<span style="color: #660066;">provide</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;mdg.sniff&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">//</span>
<span style="color: #006600; font-style: italic;">// Browser history sniffing, based on infamous blog post:</span>
<span style="color: #006600; font-style: italic;">// &lt;http://www.niallkennedy.com/blog/2008/02/browser-history-sniff.html&gt;</span>
<span style="color: #006600; font-style: italic;">//</span>
<span style="color: #006600; font-style: italic;">// Sample usage:</span>
<span style="color: #006600; font-style: italic;">//</span>
<span style="color: #006600; font-style: italic;">//    dojo.require(&quot;mdg.sniff&quot;);</span>
<span style="color: #006600; font-style: italic;">//    var usedYahoo = mdg.sniff.isVisited(&quot;http://www.yahoo.com&quot;);</span>
<span style="color: #006600; font-style: italic;">//    var usedGoogleMaps = mdg.sniff.isAnyVisited([</span>
<span style="color: #006600; font-style: italic;">//          &quot;http://maps.google.com&quot;,</span>
<span style="color: #006600; font-style: italic;">//          &quot;http://maps.google.com/maps&quot;]);</span>
<span style="color: #006600; font-style: italic;">//    var usedFacebook = mdg.sniff.isAnyVisited([</span>
<span style="color: #006600; font-style: italic;">//          &quot;http://www.facebook.com&quot;,</span>
<span style="color: #006600; font-style: italic;">//          &quot;http://www.facebook.com/index.php&quot;,</span>
<span style="color: #006600; font-style: italic;">//          &quot;https://login.facebook.com/login.php&quot;]);</span>
<span style="color: #006600; font-style: italic;">//</span>
<span style="color: #006600; font-style: italic;">// Works with Dojo 1.3 and 1.4 (*may* work with 1.2 as well)</span>
<span style="color: #006600; font-style: italic;">//</span>
&nbsp;
dojo.<span style="color: #660066;">require</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;dojox.html.styles&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
&nbsp;
    <span style="color: #003366; font-weight: bold;">var</span> _this <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">this</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">sniffCache</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
&nbsp;
    dojox.<span style="color: #660066;">html</span>.<span style="color: #660066;">insertCssRule</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;.dojohistorysniff a&quot;</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&quot;color:#000000;&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    dojox.<span style="color: #660066;">html</span>.<span style="color: #660066;">insertCssRule</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;.dojohistorysniff a:visited&quot;</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&quot;color:#ff0000 !important;&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">isAnyVisited</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #006600; font-style: italic;">/*Array*/</span>urls<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000066; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span>i<span style="color: #339933;">=</span><span style="color: #CC0000;">0</span><span style="color: #339933;">;</span> i<span style="color: #339933;">&lt;</span>urls.<span style="color: #660066;">length</span><span style="color: #339933;">;</span> i<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>_this.<span style="color: #660066;">isVisited</span><span style="color: #009900;">&#40;</span>urls<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #003366; font-weight: bold;">true</span><span style="color: #339933;">;</span>
            <span style="color: #009900;">&#125;</span>
        <span style="color: #009900;">&#125;</span>
        <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #003366; font-weight: bold;">false</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">isVisited</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #006600; font-style: italic;">/*String*/</span>url<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">typeof</span><span style="color: #009900;">&#40;</span>_this.<span style="color: #660066;">sniffCache</span><span style="color: #009900;">&#91;</span>url<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">!=</span> <span style="color: #3366CC;">'undefined'</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000066; font-weight: bold;">return</span> _this.<span style="color: #660066;">sniffCache</span><span style="color: #009900;">&#91;</span>url<span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
        <span style="color: #003366; font-weight: bold;">var</span> link <span style="color: #339933;">=</span> _this.<span style="color: #660066;">addLink</span><span style="color: #009900;">&#40;</span>url<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #003366; font-weight: bold;">var</span> color <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> dojo.<span style="color: #660066;">Color</span><span style="color: #009900;">&#40;</span>dojo.<span style="color: #660066;">style</span><span style="color: #009900;">&#40;</span>link<span style="color: #339933;">,</span> <span style="color: #3366CC;">&quot;color&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>color.<span style="color: #660066;">r</span> <span style="color: #339933;">==</span> <span style="color: #CC0000;">255</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            _this.<span style="color: #660066;">sniffCache</span><span style="color: #009900;">&#91;</span>url<span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">true</span><span style="color: #339933;">;</span>
            <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #003366; font-weight: bold;">true</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
        _this.<span style="color: #660066;">sniffCache</span><span style="color: #009900;">&#91;</span>url<span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">false</span><span style="color: #339933;">;</span>
        <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #003366; font-weight: bold;">false</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">insertSniffDiv</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000066; font-weight: bold;">return</span> dojo.<span style="color: #660066;">create</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;div&quot;</span><span style="color: #339933;">,</span> <span style="color: #009900;">&#123;</span>className<span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;dojohistorysniff&quot;</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span> dojo.<span style="color: #660066;">body</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">getSniffDiv</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #003366; font-weight: bold;">var</span> divs <span style="color: #339933;">=</span> dojo.<span style="color: #660066;">query</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;div.dojohistorysniff&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>divs.<span style="color: #660066;">length</span> <span style="color: #339933;">&gt;</span> <span style="color: #CC0000;">0</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000066; font-weight: bold;">return</span> divs<span style="color: #009900;">&#91;</span><span style="color: #CC0000;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
        <span style="color: #000066; font-weight: bold;">return</span> _this.<span style="color: #660066;">insertSniffDiv</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">addLink</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #006600; font-style: italic;">/*String*/</span>url<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #003366; font-weight: bold;">var</span> div <span style="color: #339933;">=</span> _this.<span style="color: #660066;">getSniffDiv</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000066; font-weight: bold;">return</span> dojo.<span style="color: #660066;">create</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;a&quot;</span><span style="color: #339933;">,</span> <span style="color: #009900;">&#123;</span>href<span style="color: #339933;">:</span> url<span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span> div<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #006600; font-style: italic;">/**
     * mdg.sniff.isVisited
     * Check whether or not a URL has been visited
     * @param url String
     * @return boolean
     */</span>
    mdg.<span style="color: #660066;">sniff</span>.<span style="color: #660066;">isVisited</span> <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">isVisited</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #006600; font-style: italic;">/**
     * mdg.sniff.isAnyVisited
     * Check whether or not *any* of the URLs specified have been visited
     * @param urls Array of Strings
     * @return boolean
     */</span>
    mdg.<span style="color: #660066;">sniff</span>.<span style="color: #660066;">isAnyVisited</span> <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">isAnyVisited</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://www.mike-griffith.com/blog/2010/01/browser-history-sniffing-with-dojo/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Batch convert images to sepia tone with python</title>
		<link>http://www.mike-griffith.com/blog/2010/01/batch-convert-images-to-sepia-tone-with-python/</link>
		<comments>http://www.mike-griffith.com/blog/2010/01/batch-convert-images-to-sepia-tone-with-python/#comments</comments>
		<pubDate>Thu, 14 Jan 2010 03:49:20 +0000</pubDate>
		<dc:creator>Mike</dc:creator>
				<category><![CDATA[photography]]></category>
		<category><![CDATA[software development]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[scripts]]></category>
		<category><![CDATA[tips & tricks]]></category>

		<guid isPermaLink="false">http://www.mike-griffith.com/blog/?p=329</guid>
		<description><![CDATA[The Python Imaging Library (PIL) offers easy photo manipulation from python scripts.  There&#8217;s some handy sample code on effbot.org that demonstrates how to alter an image&#8217;s palette to generate a sepia tone effect.  It first desaturates the image, then applies a new palette based on a linear ramp.
I&#8217;ve cleanup up that sample code [...]]]></description>
			<content:encoded><![CDATA[<p>The Python Imaging Library (PIL) offers easy photo manipulation from python scripts.  There&#8217;s some handy <a href="http://effbot.org/zone/pil-sepia.htm" target="_blank">sample code on effbot.org</a> that demonstrates how to alter an image&#8217;s palette to generate a sepia tone effect.  It first desaturates the image, then applies a new palette based on a linear ramp.</p>
<p>I&#8217;ve cleanup up that sample code and tucked it into a script.  You can pass a list of files to the script, and it will apply a sepia effect to each, making sure to backup the originals.</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #808080; font-style: italic;">#!/usr/bin/python</span>
<span style="color: #483d8b;">&quot;&quot;&quot;
Apply sepia filter in batch to images
&nbsp;
Usage:
    python batch_sepia.py [--no-backup] file1 [file2] ...
&quot;&quot;&quot;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">import</span> Image <span style="color: #ff7700;font-weight:bold;">as</span> PIL_Image
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">shutil</span>, <span style="color: #dc143c;">os</span>
<span style="color: #ff7700;font-weight:bold;">from</span> <span style="color: #dc143c;">optparse</span> <span style="color: #ff7700;font-weight:bold;">import</span> OptionParser
&nbsp;
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> open_image<span style="color: black;">&#40;</span>filename<span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;&quot;&quot; grab a PIL image from the given location
    &quot;&quot;&quot;</span>
    image = PIL_Image.<span style="color: #008000;">open</span><span style="color: black;">&#40;</span>filename<span style="color: black;">&#41;</span>
    image.<span style="color: black;">load</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">return</span> image
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> save_image<span style="color: black;">&#40;</span>image, filename, quality=<span style="color: #ff4500;">95</span><span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;&quot;&quot; save the PIL image to disk
    &quot;&quot;&quot;</span>
    image.<span style="color: black;">save</span><span style="color: black;">&#40;</span>filename, <span style="color: #483d8b;">&quot;JPEG&quot;</span>, quality=quality<span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> make_linear_ramp<span style="color: black;">&#40;</span>white<span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;&quot;&quot; generate a palette in a format acceptable for `putpalette`, which
        expects [r,g,b,r,g,b,...]
    &quot;&quot;&quot;</span>
    ramp = <span style="color: black;">&#91;</span><span style="color: black;">&#93;</span>
    r, g, b = white
    <span style="color: #ff7700;font-weight:bold;">for</span> i <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #008000;">range</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">255</span><span style="color: black;">&#41;</span>:
        ramp.<span style="color: black;">extend</span><span style="color: black;">&#40;</span><span style="color: black;">&#40;</span>r<span style="color: #66cc66;">*</span>i/<span style="color: #ff4500;">255</span>, g<span style="color: #66cc66;">*</span>i/<span style="color: #ff4500;">255</span>, b<span style="color: #66cc66;">*</span>i/<span style="color: #ff4500;">255</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">return</span> ramp
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> apply_sepia_filter<span style="color: black;">&#40;</span>image<span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;&quot;&quot; Apply a sepia-tone filter to the given PIL Image
        Based on code at: http://effbot.org/zone/pil-sepia.htm
    &quot;&quot;&quot;</span>
    <span style="color: #808080; font-style: italic;"># make sepia ramp (tweak color as necessary)</span>
    sepia = make_linear_ramp<span style="color: black;">&#40;</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">255</span>, <span style="color: #ff4500;">240</span>, <span style="color: #ff4500;">192</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;"># convert to grayscale</span>
    orig_mode = image.<span style="color: black;">mode</span>
    <span style="color: #ff7700;font-weight:bold;">if</span> orig_mode <span style="color: #66cc66;">!</span>= <span style="color: #483d8b;">&quot;L&quot;</span>:
        image = image.<span style="color: black;">convert</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;L&quot;</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;"># optional: apply contrast enhancement here, e.g.</span>
    <span style="color: #808080; font-style: italic;">#image = ImageOps.autocontrast(image)</span>
&nbsp;
    <span style="color: #808080; font-style: italic;"># apply sepia palette</span>
    image.<span style="color: black;">putpalette</span><span style="color: black;">&#40;</span>sepia<span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;"># convert back to its original mode</span>
    <span style="color: #ff7700;font-weight:bold;">if</span> orig_mode <span style="color: #66cc66;">!</span>= <span style="color: #483d8b;">&quot;L&quot;</span>:
        image = image.<span style="color: black;">convert</span><span style="color: black;">&#40;</span>orig_mode<span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">return</span> image
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> convert_image<span style="color: black;">&#40;</span>filename, make_backup<span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;&quot;&quot; convert an image at the given path to sepia tone.
        @param filename
        @param make_backup - if True, will copy original file to file.bak
    &quot;&quot;&quot;</span>
    <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #ff7700;font-weight:bold;">not</span> <span style="color: #dc143c;">os</span>.<span style="color: black;">path</span>.<span style="color: black;">exists</span><span style="color: black;">&#40;</span>filename<span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">'Skipping %s'</span> <span style="color: #66cc66;">%</span> filename
        <span style="color: #ff7700;font-weight:bold;">return</span>
    <span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">'Processing %s...'</span> <span style="color: #66cc66;">%</span> filename
    <span style="color: #ff7700;font-weight:bold;">if</span> make_backup:
        <span style="color: #dc143c;">shutil</span>.<span style="color: black;">copyfile</span><span style="color: black;">&#40;</span>filename, <span style="color: #483d8b;">'%s.bak'</span> <span style="color: #66cc66;">%</span> filename<span style="color: black;">&#41;</span>
    save_image<span style="color: black;">&#40;</span>apply_sepia_filter<span style="color: black;">&#40;</span>open_image<span style="color: black;">&#40;</span>filename<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>, filename<span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">'Done.'</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> convert_images<span style="color: black;">&#40;</span>files, make_backup=<span style="color: #008000;">True</span><span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;&quot;&quot; convert the list of filenames to sepia tone.
        @param filename
        @param make_backup - if True, will copy original file to file.bak
    &quot;&quot;&quot;</span>
    <span style="color: #008000;">map</span><span style="color: black;">&#40;</span><span style="color: #ff7700;font-weight:bold;">lambda</span> f: convert_image<span style="color: black;">&#40;</span>f, make_backup<span style="color: black;">&#41;</span>, files<span style="color: black;">&#41;</span>
&nbsp;
&nbsp;
<span style="color: #ff7700;font-weight:bold;">if</span> __name__ == <span style="color: #483d8b;">'__main__'</span>:
    <span style="color: #dc143c;">parser</span> = OptionParser<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    <span style="color: #dc143c;">parser</span>.<span style="color: black;">add_option</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;-x&quot;</span>, <span style="color: #483d8b;">&quot;--no-backup&quot;</span>, dest=<span style="color: #483d8b;">&quot;no_backup&quot;</span>, default=<span style="color: #008000;">False</span>,
            action=<span style="color: #483d8b;">&quot;store_true&quot;</span><span style="color: black;">&#41;</span>
    <span style="color: black;">&#40;</span>options, files<span style="color: black;">&#41;</span> = <span style="color: #dc143c;">parser</span>.<span style="color: black;">parse_args</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    convert_images<span style="color: black;">&#40;</span>files, make_backup=<span style="color: #ff7700;font-weight:bold;">not</span> options.<span style="color: black;">no_backup</span><span style="color: black;">&#41;</span></pre></div></div>

<p>You can execute this from the command line as:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ python batch_sepia.py image1.jpg image2.jpg image3.jpg</pre></div></div>

<p>If you want to recursively apply the filter to a bunch of images, you might consider mixing this with some find/xargs-fu:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ <span style="color: #c20cb9; font-weight: bold;">find</span> <span style="color: #007800;">$HOME</span><span style="color: #000000; font-weight: bold;">/</span>pictures <span style="color: #660033;">-name</span> <span style="color: #ff0000;">&quot;*.jpg&quot;</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">xargs</span> python batch_sepia.py</pre></div></div>

<p>Once you&#8217;ve got your photos in order, head over to <a href="http://www.photoworks.com" target="_blank">photoworks.com</a> to get them printed!&lt;/shameless-plug&gt;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.mike-griffith.com/blog/2010/01/batch-convert-images-to-sepia-tone-with-python/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Recent svn commit statistics</title>
		<link>http://www.mike-griffith.com/blog/2010/01/recent-svn-commit-statistics/</link>
		<comments>http://www.mike-griffith.com/blog/2010/01/recent-svn-commit-statistics/#comments</comments>
		<pubDate>Wed, 13 Jan 2010 21:23:36 +0000</pubDate>
		<dc:creator>Mike</dc:creator>
				<category><![CDATA[software development]]></category>
		<category><![CDATA[scripts]]></category>
		<category><![CDATA[tips & tricks]]></category>

		<guid isPermaLink="false">http://www.mike-griffith.com/blog/?p=320</guid>
		<description><![CDATA[Here&#8217;s a little script-fu that can help determine how many lines of code were added vs. deleted for a single Subversion commit.

#!/bin/bash
if &#91; -z &#34;$1&#34; &#93;; then
    echo &#34;usage: $0 revision&#34;
    exit
fi
&#160;
REV=$1
&#160;
# Execute a svn diff on the revision, and search the output for deleted lines
# (begin with a [...]]]></description>
			<content:encoded><![CDATA[<p>Here&#8217;s a little script-fu that can help determine how many lines of code were added vs. deleted for a single Subversion commit.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">#!/bin/bash</span>
<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #660033;">-z</span> <span style="color: #ff0000;">&quot;$1&quot;</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span>; <span style="color: #000000; font-weight: bold;">then</span>
    <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;usage: $0 revision&quot;</span>
    <span style="color: #7a0874; font-weight: bold;">exit</span>
<span style="color: #000000; font-weight: bold;">fi</span>
&nbsp;
<span style="color: #007800;">REV</span>=$<span style="color: #000000;">1</span>
&nbsp;
<span style="color: #666666; font-style: italic;"># Execute a svn diff on the revision, and search the output for deleted lines</span>
<span style="color: #666666; font-style: italic;"># (begin with a '-', but aren't followed by another immediately),</span>
<span style="color: #666666; font-style: italic;"># and likewise with any added lines</span>
<span style="color: #007800;">DIFF</span>=<span style="color: #ff0000;">&quot;<span style="color: #007800;">$(svn diff -c $REV --diff-cmd=/usr/bin/diff)</span>&quot;</span>
<span style="color: #007800;">DEL_COUNTS</span>=$<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #660033;">-e</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">$DIFF</span>&quot;</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">egrep</span> <span style="color: #ff0000;">'^[-][^-]'</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">wc</span> -lm<span style="color: #7a0874; font-weight: bold;">&#41;</span>
<span style="color: #007800;">ADD_COUNTS</span>=$<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #660033;">-e</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">$DIFF</span>&quot;</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">egrep</span> <span style="color: #ff0000;">'^[+][^+]'</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">wc</span> -lm<span style="color: #7a0874; font-weight: bold;">&#41;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">function</span> get_field <span style="color: #7a0874; font-weight: bold;">&#123;</span>
    <span style="color: #666666; font-style: italic;"># given an input string with 2 fields delimited by spaces, possibly with</span>
    <span style="color: #666666; font-style: italic;"># leading whitespace, return the field in the position specified.</span>
    <span style="color: #666666; font-style: italic;"># so,  `get_field &quot;   123   45678&quot; 1`  would return &quot;122&quot;</span>
    <span style="color: #666666; font-style: italic;"># and  `get_field &quot;   123   45678&quot; 2`  would return &quot;45678&quot;</span>
    <span style="color: #007800;">INPUT</span>=$<span style="color: #000000;">1</span>
    <span style="color: #007800;">POSITION</span>=$<span style="color: #000000;">2</span>
    <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #007800;">$INPUT</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">sed</span> <span style="color: #ff0000;">&quot;s/^[ ]*\([0-9]*\)[ ]*\([0-9]*\)/\<span style="color: #000099; font-weight: bold;">\$</span>POSITION/g&quot;</span>
<span style="color: #7a0874; font-weight: bold;">&#125;</span>
&nbsp;
<span style="color: #007800;">DEL_LINES</span>=$<span style="color: #7a0874; font-weight: bold;">&#40;</span>get_field <span style="color: #ff0000;">&quot;<span style="color: #007800;">$DEL_COUNTS</span>&quot;</span> <span style="color: #000000;">1</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>
<span style="color: #007800;">DEL_CHARS</span>=$<span style="color: #7a0874; font-weight: bold;">&#40;</span>get_field <span style="color: #ff0000;">&quot;<span style="color: #007800;">$DEL_COUNTS</span>&quot;</span> <span style="color: #000000;">2</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>
&nbsp;
<span style="color: #007800;">ADD_LINES</span>=$<span style="color: #7a0874; font-weight: bold;">&#40;</span>get_field <span style="color: #ff0000;">&quot;<span style="color: #007800;">$ADD_COUNTS</span>&quot;</span> <span style="color: #000000;">1</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>
<span style="color: #007800;">ADD_CHARS</span>=$<span style="color: #7a0874; font-weight: bold;">&#40;</span>get_field <span style="color: #ff0000;">&quot;<span style="color: #007800;">$ADD_COUNTS</span>&quot;</span> <span style="color: #000000;">2</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>
&nbsp;
<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;Removed <span style="color: #007800;">$DEL_LINES</span> lines (<span style="color: #007800;">$DEL_CHARS</span> characters)&quot;</span>
<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;Added <span style="color: #007800;">$ADD_LINES</span> lines (<span style="color: #007800;">$ADD_CHARS</span> characters)&quot;</span></pre></div></div>

<p>Save this as <code>$HOME/bin/svnstat</code>, then execute it passing in a revision, e.g. <code>$ svnstat 1001</code></p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">$ svnstat 61765
Removed 113 lines (4913 characters)
Added 63 lines (2975 characters)</pre></div></div>

<p>If you want to then see your daily net lines of code, hook this up to an <code>egrep</code>&#8216;d <code>svn log</code>, piped into <code>xargs</code>.</p>
<p><strong>Update 1/13/2010:</strong><br />
I cleaned up the &#8220;get_field&#8221; function to use a single <code>sed</code> command with backreferences rather than piping the string through <code>tr</code>, <code>sed</code>, and <code>cut</code>.</p>
<p>Also updated the initial calculation of <code>DIFF_COUNTS</code> and <code>ADD_COUNTS</code> to only require 1 single <code>svn diff</code> execution.  Used <code>echo -e</code> to solve the newline issue I was having on a first failed attempt.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.mike-griffith.com/blog/2010/01/recent-svn-commit-statistics/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>VIM Tip of the Day: leave python comments indented, don&#8217;t put cursor at beginning of the line</title>
		<link>http://www.mike-griffith.com/blog/2009/05/vim-tip-of-the-day-leave-python-comments-indented-dont-put-cursor-at-beginning-of-the-line/</link>
		<comments>http://www.mike-griffith.com/blog/2009/05/vim-tip-of-the-day-leave-python-comments-indented-dont-put-cursor-at-beginning-of-the-line/#comments</comments>
		<pubDate>Fri, 15 May 2009 17:18:32 +0000</pubDate>
		<dc:creator>Mike</dc:creator>
				<category><![CDATA[software development]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[tips & tricks]]></category>
		<category><![CDATA[vim]]></category>

		<guid isPermaLink="false">http://www.mike-griffith.com/blog/?p=305</guid>
		<description><![CDATA[If you&#8217;re ever been annoyed by VIM throwing your cursor to the left margin when you type &#8220;#&#8221; in a python file, there&#8217;s a simple remedy.  It&#8217;s the fault of &#8220;smartindent&#8221; in VIM, which in reality isn&#8217;t all that smart.  If you want to leave smartindent on but fix the weird hash behavior, [...]]]></description>
			<content:encoded><![CDATA[<p>If you&#8217;re ever been annoyed by VIM throwing your cursor to the left margin when you type &#8220;#&#8221; in a python file, there&#8217;s a simple remedy.  It&#8217;s the fault of &#8220;smartindent&#8221; in VIM, which in reality isn&#8217;t all that smart.  If you want to leave smartindent on but fix the weird hash behavior, throw the following in your $HOME/.vimrc.</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">:inoremap # X&lt;C-H&gt;#</pre></div></div>

<p>See <a href="http://vim.wikia.com/wiki/Restoring_indent_after_typing_hash">http://vim.wikia.com/wiki/Restoring_indent_after_typing_hash</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.mike-griffith.com/blog/2009/05/vim-tip-of-the-day-leave-python-comments-indented-dont-put-cursor-at-beginning-of-the-line/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Fiddler scripting is pretty cool</title>
		<link>http://www.mike-griffith.com/blog/2009/02/fiddler-scripting-is-pretty-cool/</link>
		<comments>http://www.mike-griffith.com/blog/2009/02/fiddler-scripting-is-pretty-cool/#comments</comments>
		<pubDate>Wed, 04 Feb 2009 18:47:56 +0000</pubDate>
		<dc:creator>Mike</dc:creator>
				<category><![CDATA[testing]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[tips & tricks]]></category>

		<guid isPermaLink="false">http://www.mike-griffith.com/blog/?p=216</guid>
		<description><![CDATA[I never really gave Fiddler all the credit it was due.  I guess I should have read the homepage:
Fiddler includes a powerful event-based scripting subsystem, and can be extended using any .NET language.

I had previously only used it as a session inspector &#8212; to review requests and responses as they occurred in the wild. [...]]]></description>
			<content:encoded><![CDATA[<p>I never really gave <a href="http://www.fiddlertool.com/fiddler/">Fiddler</a> all the credit it was due.  I guess I should have read the homepage:</p>
<blockquote><p>Fiddler includes a powerful event-based scripting subsystem, and can be extended using any .NET language.</p></blockquote>
<p><img src="http://www.mike-griffith.com/blog/wp-content/uploads/2009/02/newfiddlermodified2in-194x300.jpg" alt="fiddler_dancing" title="fiddler_dancing" width="129" height="200" class="alignright size-medium wp-image-229" /></p>
<p>I had previously only used it as a session inspector &#8212; to review requests and responses as they occurred in the wild.  As it turns out, you can modify request and response headers very easily.  </p>
<p>For a quick example, let&#8217;s see what it would take to disable connection keep-alive&#8217;s when cache-control is set to no-cache.  Fire up Fiddler, click Rules, then click &#8220;Customize Rules&#8230;&#8221;.  It will pop open CustomRules.js, a JScript file with a Handler class.  Scroll down to the OnBeforeResponse static function.</p>
<p>Just after the m_DisableCaching block that is probably already defined, let&#8217;s add a simple clause:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>m_DisableCaching<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
    oSession.<span style="color: #660066;">oResponse</span>.<span style="color: #660066;">headers</span>.<span style="color: #660066;">Remove</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;Expires&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    oSession.<span style="color: #660066;">oResponse</span><span style="color: #009900;">&#91;</span><span style="color: #3366CC;">&quot;Cache-Control&quot;</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #3366CC;">&quot;no-cache&quot;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>oSession.<span style="color: #660066;">oResponse</span><span style="color: #009900;">&#91;</span><span style="color: #3366CC;">&quot;Cache-Control&quot;</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">==</span> <span style="color: #3366CC;">&quot;no-cache&quot;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #006600; font-style: italic;">// Disable keep-alive by setting Connection: close header</span>
    oSession.<span style="color: #660066;">oResponse</span><span style="color: #009900;">&#91;</span><span style="color: #3366CC;">&quot;Connection&quot;</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #3366CC;">&quot;close&quot;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Fire up IE, visit a page, and look at the Fiddler session logs to see the difference.  That easy.  Have fun playing with headers!</p>
<p><em>On a side-note: thank God for Wordpress auto-save.  Not that I had much in this article, but I &#8220;tabbed&#8221; out of the text editor accidentally, hit backspace (forcing the browser to go back), and cursed at the keyboard.  Luckily, it was sitting 95% complete in my drafts folder!</em></p>
]]></content:encoded>
			<wfw:commentRss>http://www.mike-griffith.com/blog/2009/02/fiddler-scripting-is-pretty-cool/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Firefox tips and tricks</title>
		<link>http://www.mike-griffith.com/blog/2008/08/firefox-tips-and-tricks/</link>
		<comments>http://www.mike-griffith.com/blog/2008/08/firefox-tips-and-tricks/#comments</comments>
		<pubDate>Tue, 26 Aug 2008 11:34:23 +0000</pubDate>
		<dc:creator>Mike</dc:creator>
				<category><![CDATA[software development]]></category>
		<category><![CDATA[tips & tricks]]></category>

		<guid isPermaLink="false">http://bikegriffith.webfactional.com/blog/?p=14</guid>
		<description><![CDATA[I want to eventually post about some of the great things I&#8217;ve learned about Firefox and how to become a power user.  I get a lot of value out of plugins and Greasemonkey scripts.
For another day&#8230;
]]></description>
			<content:encoded><![CDATA[<p>I want to eventually post about some of the great things I&#8217;ve learned about <a href="http://www.getfirefox.com/" target="_blank">Firefox</a> and how to become a power user.  I get a lot of value out of plugins and <a href="http://www.userscripts.org/" target="_blank">Greasemonkey</a> scripts.</p>
<p>For another day&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.mike-griffith.com/blog/2008/08/firefox-tips-and-tricks/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
