<?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>The Kaptain on ... stuff &#187; Application programming interface</title>
	<atom:link href="http://www.kellyrob99.com/blog/tag/application-programming-interface/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.kellyrob99.com/blog</link>
	<description>Tales of development, life and the folly that goes along with both</description>
	<lastBuildDate>Sun, 04 Dec 2011 21:51:34 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=</generator>
		<item>
		<title>A Grails App Demoing the StackExchange API</title>
		<link>http://www.kellyrob99.com/blog/2010/06/02/a-grails-app-demoing-the-stackexchange-api/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=a-grails-app-demoing-the-stackexchange-api</link>
		<comments>http://www.kellyrob99.com/blog/2010/06/02/a-grails-app-demoing-the-stackexchange-api/#comments</comments>
		<pubDate>Thu, 03 Jun 2010 07:12:17 +0000</pubDate>
		<dc:creator>TheKaptain</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[API]]></category>
		<category><![CDATA[Application programming interface]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[Google Reader]]></category>
		<category><![CDATA[Grails]]></category>
		<category><![CDATA[Groovy]]></category>
		<category><![CDATA[HTTP]]></category>
		<category><![CDATA[JSON]]></category>
		<category><![CDATA[kellyrob99]]></category>
		<category><![CDATA[Representational State Transfer]]></category>
		<category><![CDATA[Source code]]></category>
		<category><![CDATA[Stack Overflow]]></category>
		<category><![CDATA[StackApps]]></category>
		<category><![CDATA[StackExchange]]></category>
		<category><![CDATA[theKaptain]]></category>

		<guid isPermaLink="false">http://www.kellyrob99.com/blog/?p=1367</guid>
		<description><![CDATA[So I was making an attempt to catch up on my Google Reader&#8216;ing this weekend and I came across this post on StackOverflow regarding the shiny new StackExchange API. That and a fresh 1.3.1 drop of Grails seemed like as good a reason as any to hack together a little app suitable for seeing what [...]
Related posts:<ol>
<li><a href='http://www.kellyrob99.com/blog/2011/03/27/hooking-into-the-jenkinshudson-api/' rel='bookmark' title='Hooking into the Jenkins(Hudson) API'>Hooking into the Jenkins(Hudson) API</a></li>
<li><a href='http://www.kellyrob99.com/blog/2009/10/25/grails-ui-datatable-using-xml-for-a-model/' rel='bookmark' title='Grails-UI DataTable using XML for a model'>Grails-UI DataTable using XML for a model</a></li>
<li><a href='http://www.kellyrob99.com/blog/2010/03/21/gource-visualizations-of-the-groovygrailsgriffon-projects/' rel='bookmark' title='Gource Visualizations of the Groovy/Grails/Griffon Projects'>Gource Visualizations of the Groovy/Grails/Griffon Projects</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>So I was making an attempt to catch up on my <a class="zem_slink" href="http://www.google.com/reader" title="Google Reader" rel="homepage">Google Reader</a>&#8216;ing this weekend and I came across <a href="http://blog.stackoverflow.com/2010/05/stack-exchange-api-contest/">this post on StackOverflow</a> regarding the shiny new <a class="zem_slink" href="http://www.stackexchange.com" title="StackExchange" rel="homepage">StackExchange</a> <a class="zem_slink" href="http://en.wikipedia.org/wiki/Application_programming_interface" title="Application programming interface" rel="wikipedia">API</a>. That and a fresh 1.3.1 drop of <a class="zem_slink" href="http://grails.org" title="Grails (framework)" rel="homepage">Grails</a> seemed like as good a reason as any to hack together a little app suitable for seeing what you can do with said API.<br />
Turns out it&#8217;s not a whole lot, at least not yet. The minor detraction of having  read-only access and limited connects without an API key are more than offset by seeing such a minimal, clean and easy to use interface. According to the grails stats script, it took about this much effort to implement calls to each and every one of the API endpoints for all of the supported domains:</p>
<pre class="brush: xml; title: ; notranslate">
    +----------------------+-------+-------+
    | Name                 | Files |  LOC  |
    +----------------------+-------+-------+
    | Controllers          |     1 |    42 |
    | Groovy Helpers       |     1 |    47 |
    +----------------------+-------+-------+
    | Totals               |     2 |    89 |
    +----------------------+-------+-------+
</pre>
<p>
Please note that this is about as minimal as you could reasonably get away with(and kinda ugly to boot), but nevertheless it does manage to implement a UI and backend for exercising the entire API in a total of 2 gsp files and 1 controller action.  What&#8217;s noticeably missing are some tailored views for each of the different <a class="zem_slink" href="http://json.org/" title="JSON" rel="homepage">JSON</a> responses and the implementation of additional query parameters on the calls.</p>
<p></p>
<h2>StackExchange API</h2>
<p>This is really <a href="http://api.stackoverflow.com/0.8/help">pretty well documented</a> and &#8220;consistent&#8221;. Calls in some cases require an {id} in the url and that&#8217;s about it. Each of the individual calls has its own help page that describes the options, like the <a href="http://api.stackoverflow.com/0.8/help/method?method=badges">badges page</a> for instance. To make things a little more helpful while exploring the API, each of the implemented endpoints in this app are also hyper-linked to the corresponding manual page on api.stackoverflow.com.</p>
<p></p>
<h2><a class="zem_slink" href="http://en.wikipedia.org/wiki/Representational_State_Transfer" title="Representational State Transfer" rel="wikipedia">RESTful</a> Access</h2>
<p>Couldn&#8217;t be a whole lot easier than using <a href="http://groovy.codehaus.org/modules/http-builder/">HttpBuilder</a>, which provides nice and concise ways to execute the GET request, inspect the response and deal with success/failure of the request. Aside from assigning the root domain and method using variables, this is little different from the <a href="http://groovy.codehaus.org/HTTP+Builder">canonical example on codehaus</a>.</p>
<pre class="brush: groovy; title: ; notranslate">
def http = new HTTPBuilder(&quot;http://api.$domain&quot;)
http.request(GET, JSON) {
    uri.path = &quot;/${VERSION}$method&quot;
    headers.'User-Agent' = 'Mozilla/5.0 Ubuntu/8.10 Firefox/3.0.4'
     response.success = { resp, json -&gt;
        answer = json
    }
     response.failure = { resp -&gt;
        answer = &quot;Unexpected error: ${resp.statusLine.statusCode} : ${resp.statusLine.reasonPhrase}&quot;
    }
}
</pre>
<p>The syntax here could probably get even Groovier using the <a href="http://www.grails.org/plugin/rest">Grails REST client plugin</a> wrappers, and indeed incorporating that plugin is how the HttpBuilder dependency is being provided in this app, but I hit on a working implementation first time out so we&#8217;ll leave that for another day, shall we?</p>
<p></p>
<h2>What&#8217;s it Look Like?</h2>
<p><img src='http://www.kellyrob99.com/blog/wp-content/gallery/stackoverflow-api-grails/stackapps-demo_1275451039026.png' alt='stackapps-demo' class='ngg-singlepic ngg-none'  width='860' height='480'/><br />
Did I mention it was ugly?  Where the API call requires a parameter, you get a text field. Each domain gets its own submit button, officially representing my first attempted usage of g:actionSubmit in Grails. Doesn&#8217;t work quite the way I expected, but it does certainly work. Click a button and you&#8217;re shown the raw JSON result, along with the call you made. In an ugly fashion, or did I say that already? Still, for a couple of hours of hacking, I&#8217;m not unhappy with the result.</p>
<p></p>
<h2>StackApps</h2>
<p>This is where the apps in the contest get shown off and, in a wonderful display of <a href="http://en.wikipedia.org/wiki/Eating_your_own_dog_food">dogfooding</a>, it&#8217;s guess what &#8211; another StackOverflow clone! The page for this application <a href="http://stackapps.com/questions/491/a-grails-app-demoing-the-stackexchange-api">can be found here</a>. And the <a href="http://github.com/kellyrob99/stackoverflow-api-grails">source code is up on github</a> if you&#8217;d like to take a look.</p>
<p></p>
<h2>Next Steps?</h2>
<p>Toying with the idea of porting this to appengine, which would unfortunately mean replacing HttpBuilder and the underlying Apache HttpClient in favor of something that didn&#8217;t use a threaded approach, most likely using <a href="http://code.google.com/appengine/docs/java/urlfetch/">URL fetch</a>. That and some slightly less ugly tabular and/or tree views of the JSON responses would be kinda nice to have.<br />
 <img src='http://www.kellyrob99.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<!-- AdSense Now! V1.95 -->
<!-- Post[count: 2] -->
<div class="adsense adsense-leadout" style="float:right;margin: 12px;"><script type="text/javascript"><!--
google_ad_client = "pub-6955914197200080";
/* 728x90, created 8/3/09 */
google_ad_slot = "4051815125";
google_ad_width = 728;
google_ad_height = 90;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script></div><p>Related posts:<ol>
<li><a href='http://www.kellyrob99.com/blog/2011/03/27/hooking-into-the-jenkinshudson-api/' rel='bookmark' title='Hooking into the Jenkins(Hudson) API'>Hooking into the Jenkins(Hudson) API</a></li>
<li><a href='http://www.kellyrob99.com/blog/2009/10/25/grails-ui-datatable-using-xml-for-a-model/' rel='bookmark' title='Grails-UI DataTable using XML for a model'>Grails-UI DataTable using XML for a model</a></li>
<li><a href='http://www.kellyrob99.com/blog/2010/03/21/gource-visualizations-of-the-groovygrailsgriffon-projects/' rel='bookmark' title='Gource Visualizations of the Groovy/Grails/Griffon Projects'>Gource Visualizations of the Groovy/Grails/Griffon Projects</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.kellyrob99.com/blog/2010/06/02/a-grails-app-demoing-the-stackexchange-api/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Breaking Weak CAPTCHA in&#8230; slightly more than 26 Lines of Groovy Code</title>
		<link>http://www.kellyrob99.com/blog/2010/03/14/breaking-weak-captcha-in-slightly-more-than-26-lines-of-groovy-code/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=breaking-weak-captcha-in-slightly-more-than-26-lines-of-groovy-code</link>
		<comments>http://www.kellyrob99.com/blog/2010/03/14/breaking-weak-captcha-in-slightly-more-than-26-lines-of-groovy-code/#comments</comments>
		<pubDate>Sun, 14 Mar 2010 23:44:59 +0000</pubDate>
		<dc:creator>TheKaptain</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Application programming interface]]></category>
		<category><![CDATA[Graphics]]></category>
		<category><![CDATA[Groovy]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Java2D]]></category>
		<category><![CDATA[maven]]></category>
		<category><![CDATA[Open source]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Source code]]></category>
		<category><![CDATA[tesseract-ocr]]></category>
		<category><![CDATA[theKaptain]]></category>

		<guid isPermaLink="false">http://www.kellyrob99.com/blog/?p=1158</guid>
		<description><![CDATA[I read an interesting article recently about using python and open source software to defeat a particular captcha implementation and I set out to see how hard it would be to do the same in Groovy. In particular, coming from the Java side of the fence, I was impressed by how the available libraries in [...]
Related posts:<ol>
<li><a href='http://www.kellyrob99.com/blog/2009/11/21/different-flavors-of-embedded-groovy-in-java-apps-or-how-to-make-your-java-groovier/' rel='bookmark' title='Different Flavors of Embedded Groovy in Java Apps or &#8220;How To Make your Java Groovier!&#8221;'>Different Flavors of Embedded Groovy in Java Apps or &#8220;How To Make your Java Groovier!&#8221;</a></li>
<li><a href='http://www.kellyrob99.com/blog/2010/05/15/achieving-groovy-like-fluency-in-java-with-google-collections/' rel='bookmark' title='Achieving Groovy-like Fluency in Java with Google Collections'>Achieving Groovy-like Fluency in Java with Google Collections</a></li>
<li><a href='http://www.kellyrob99.com/blog/2010/04/17/groovy-and-hibernate-validator-for-dynamic-constraints/' rel='bookmark' title='Groovy and Hibernate Validator for Dynamic Constraints'>Groovy and Hibernate Validator for Dynamic Constraints</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>I read <a href="http://www.bonsai-sec.com/blog/index.php/breaking-weak-captcha-in-26-lines-of-code/">an interesting article</a> recently about using python and <a class="zem_slink" href="http://www.wikinvest.com/concept/Open_Source" title="Open Source" rel="wikinvest">open source</a> software to defeat a particular captcha implementation and I set out to see how hard it would be to do the same in Groovy. In particular, coming from the <a class="zem_slink" href="http://java.sun.com" title="Java (programming language)" rel="homepage">Java</a> side of the fence, I was impressed by how the available libraries in python made loading, mutating and saving images so easy. Admittedly I have limited experience working with image data, but when I have it has always seemed like a complex(and easy to get wrong) process. Maybe there&#8217;s a Java library out there that provides a simple &#8216;image_resize&#8217; method, but it&#8217;s certainly not in the BufferedImage <a class="zem_slink" href="http://en.wikipedia.org/wiki/Application_programming_interface" title="Application programming interface" rel="wikipedia">API</a>. Still, when porting the 26 lines of code over to Groovy, I was able to get it considerably less verbose than the Java equivalent.</p>
<p></p>
<h2>The Pretty Pictures</h2>
<p>Here are the three images to test against. In order to put them in a suitable format for <a href="http://code.google.com/p/tesseract-ocr">the open source tesseract-ocr program</a> to process we need to make them bigger, remove the background noise and transform them into a &#8216;tif&#8217; format. The python program we&#8217;re porting utilizes the PIL library for image handling and the pytesseract library for wrapping tesseract; I didn&#8217;t look very hard for java equivalents and just coded the required functions directly.</p>
<table>
<tbody>
<tr>
<td>
<a href="http://www.kellyrob99.com/blog/wp-content/gallery/captcha-breaker/9koo.gif" title="Original image for 9koO" class="shutterset_singlepic58" >
	<img class="ngg-singlepic" src="http://www.kellyrob99.com/blog/wp-content/gallery/cache/58__x_9koo.gif" alt="9koo" title="9koo" />
</a>
</td>
<td>
<a href="http://www.kellyrob99.com/blog/wp-content/gallery/captcha-breaker/jxt9.gif" title="Original image for jxt9" class="shutterset_singlepic60" >
	<img class="ngg-singlepic" src="http://www.kellyrob99.com/blog/wp-content/gallery/cache/60__x_jxt9.gif" alt="jxt9" title="jxt9" />
</a>
</td>
<td>
<a href="http://www.kellyrob99.com/blog/wp-content/gallery/captcha-breaker/e4ya.gif" title="Original image for e4ya" class="shutterset_singlepic59" >
	<img class="ngg-singlepic" src="http://www.kellyrob99.com/blog/wp-content/gallery/cache/59__x_e4ya.gif" alt="e4ya" title="e4ya" />
</a>
</td>
</tr>
</tbody>
</table>
<p></p>
<h2>Reading in the Image</h2>
<p>The python code for this is three lines, one to load the image and a couple more to convert it into a format suitable for directly manipulating pixel color through <a class="zem_slink" href="http://en.wikipedia.org/wiki/RGB_color_model" title="RGB color model" rel="wikipedia">RGB</a> values. Groovy takes a bit more to do the same, but being able to use a &#8216;with&#8217; block makes interacting with the Graphics object a lot cleaner than the same Java code</p>
<pre class="brush: groovy; title: ; notranslate">
//python
from PIL import Image
img = Image.open('input.gif')
img = img.convert(&quot;RGBA&quot;)
pixdata = img.load()

//Groovy
BufferedImage image = ImageIO.read(new File(fileName))
BufferedImage dimg = new BufferedImage(image.width, image.height, BufferedImage.TYPE_INT_ARGB)
dimg.createGraphics().with {
    setComposite(AlphaComposite.Src)
    drawImage(image, null, 0, 0)
    dispose()
}
</pre>
<p></p>
<h2>Removing the Background Noise</h2>
<p>In both cases we&#8217;re doing essentially the same thing: finding all non-black pixels and setting them to white. This leaves only the actual embedded text to stand out. Being able to utilize the Java Color constants makes the Groovy version a little more readable, IMO, but otherwise the two pieces of code are generally equivalent.</p>
<pre class="brush: groovy; title: ; notranslate">
//python
for y in xrange(img.size[1]):
    for x in xrange(img.size[0]):
        if pixdata[x, y] != (0, 0, 0, 255):
            pixdata[x, y] = (255, 255, 255, 255)

//Groovy
(0..&lt;dimg.height).each {i=&quot;&quot; -=&quot;&quot;&gt;
    (0..&lt;dimg.width).each {j=&quot;&quot; -=&quot;&quot;&gt;
        if (dimg.getRGB(j, i) != Color.BLACK.RGB)
        {
            dimg.setRGB(j, i, Color.WHITE.RGB)
        }
    }
}
</pre>
<p></p>
<h2>Resizing the Image</h2>
<p><a class="zem_slink" href="http://www.python.org/" title="Python (programming language)" rel="homepage">Python</a>&#8216;s library usage really shines here, making this a one line call. Not quite the same in Java-land, although again there&#8217;s probably a better way to do this(I just don&#8217;t know it offhand).</p>
<pre class="brush: groovy; title: ; notranslate">
//python
big = im_orig.resize((116, 56), Image.NEAREST)

//Groovy
dimg = resizeImage(dimg, 116, 56)
...
def resizeImage = {BufferedImage image, int w, int h -&amp;gt;
    BufferedImage dimg = new BufferedImage(w, h, image.type)
    dimg.createGraphics().with {
        setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR)
        drawImage(image, 0, 0, w, h, 0, 0, image.width, image.height, null)
        dispose()
    }
    return dimg
}
</pre>
<p>By this point the original images now look like this, and are <i>almost</i> ready for OCR.</p>
<table>
<tbody>
<tr>
<td>
<a href="http://www.kellyrob99.com/blog/wp-content/gallery/captcha-breaker/tmp0.gif" title="Resized and cleaned for OCR" class="shutterset_singlepic61" >
	<img class="ngg-singlepic" src="http://www.kellyrob99.com/blog/wp-content/gallery/cache/61__x_tmp0.gif" alt="9koO-readyForOCR" title="9koO-readyForOCR" />
</a>
</td>
<td>
<a href="http://www.kellyrob99.com/blog/wp-content/gallery/captcha-breaker/tmp1.gif" title="Resized and cleaned for OCR" class="shutterset_singlepic62" >
	<img class="ngg-singlepic" src="http://www.kellyrob99.com/blog/wp-content/gallery/cache/62__x_tmp1.gif" alt="jxt9-readyForOCR" title="jxt9-readyForOCR" />
</a>
</td>
<td>
<a href="http://www.kellyrob99.com/blog/wp-content/gallery/captcha-breaker/tmp2.gif" title="Resized and cleaned for OCR" class="shutterset_singlepic63" >
	<img class="ngg-singlepic" src="http://www.kellyrob99.com/blog/wp-content/gallery/cache/63__x_tmp2.gif" alt="e4ya-readyForOCR" title="e4ya-readyForOCR" />
</a>
</td>
</tr>
</tbody>
</table>
<p></p>
<h2>Converting to a tif File</h2>
<p>This one turns out to be a bit of a PITA in Java and particularly on a Mac, and represents the bulk of the Groovy code. Unfortunately it is also the only format that tesseract appears to accept &#8216;out of the box&#8217;.  After googling the fun that is JAI and working with the <a class="zem_slink" href="http://en.wikipedia.org/wiki/Tagged_Image_File_Format" title="Tagged Image File Format" rel="wikipedia">.tif</a>(f) format with it on a Mac,   I ended up taking the code kindly provided in <a href="http://www.ideyatech.com/2009/05/converting-to-tiff-on-mac-using-java-advanced-imaging/">this blog post</a> and Groovified it a bit to make a working transformation. Thanks very much to Allan Tan for that. One more time, there&#8217;s likely a better/easier way to do this, but honestly it&#8217;s more effort than I&#8217;m willing to put in on a weekend afternoon just to satisfy my curiosity.<br />
 <img src='http://www.kellyrob99.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<pre class="brush: groovy; title: ; notranslate">
//python
ext = &quot;.tif&quot;
big.save(&quot;input-NEAREST&quot; + ext)

//Groovy
void convertToTiff(String inputFile, String outputFile)
{
    OutputStream ios
    try
    {
        ios = new BufferedOutputStream(new FileOutputStream(new File(outputFile)))
        ImageEncoder enc = ImageCodec.createImageEncoder(&quot;tiff&quot;, ios, new TIFFEncodeParam(compression: TIFFEncodeParam.COMPRESSION_NONE, littleEndian: false))
        RenderedOp src = JAI.create(&quot;fileload&quot;, inputFile)

        //Apply the color filter and return the result.
        ColorConvertOp filterObj = new ColorConvertOp(ColorSpace.getInstance(ColorSpace.CS_sRGB), null)
        BufferedImage dst = new BufferedImage(src.width, src.height, BufferedImage.TYPE_3BYTE_BGR)
        filterObj.filter(src.getAsBufferedImage(), dst)

        // save the output file
        enc.encode(dst)
    }
    catch (Exception e)
    {
        println e
    }
    finally
    {
        ios.close()
    }
}
</pre>
<p></p>
<h2>OCR with Tesseract-OCR</h2>
<p>Finally we need to pass the processed image to tesseract so it can &#8216;read&#8217; it for us. Again, the python library makes this a breeze, but calling out to a command line program with Groovy is so simple that it ends up being about the same. Tesseract itself is available as a macport, as well in downloadable unix binaries and a windows executable so installing the software is a breeze.</p>
<pre class="brush: groovy; title: ; notranslate">
//python
from pytesser import *
image = Image.open('input-NEAREST.tif')
print image_to_string(image)

//Groovy
def tesseract = ['/opt/local/bin/tesseract', tmpTif, tmpTesseract].execute()
tesseract.waitFor()
return new File(&quot;${tmpTesseract}.txt&quot;).readLines()[0]
</pre>
<p></p>
<h2>Testing it out</h2>
<p>To test it out I implemented the code in a maven project, iterate over the images and write out intermediate results to a temp directory. And it only works on two out of three of the cases. For some reason tesseract insists on consistently seeing &#8216;e4ya&#8217; as &#8216;e4ga&#8217;.  I tried to see if I could get it working by tweaking the image manipulation parameters and the order of operations(resizing before removing the background noise for instance) but that just caused the other cases to fail as well. Since in the final image the &#8216;y&#8217; seems pretty clear, it&#8217;s more likely that tweaking tesseract configuration might yield better results.</p>
<pre class="brush: groovy; title: ; notranslate">
public void testPrintImage()
{
    def breaker = new CaptchaBreaker()
    /* tesseract interprets &quot;e4ya&quot; as &quot;e4ga&quot; unfortunately */
    ['9koO', 'jxt9'/*,'e4ya'*/].each {String imageName -&amp;gt;
        def fileName = &quot;src/test/resources/${imageName}.gif&quot;
        assertEquals(&quot;Testing $imageName&quot;,imageName, breaker.imageToString(fileName))
    }
}
</pre>
<p></p>
<h2>C&#8217;est Finis</h2>
<p>I had some fun playing with areas of Java that I don&#8217;t usually interact with, and gained some appreciation for the diversity and ease-of-use exposed by just a couple of python libraries. It&#8217;s comforting to note that I was able to implement all of the required functionality from those libraries in &lt; 90 lines of Groovy. With a little more effort I think the final product could be tweaked to avoid the intermediate file system reads/writes as well, but that&#8217;s for another day.<br />
Source code is <a href="http://github.com/kellyrob99/catcha-breaker">available on github</a> if you&#8217;d care to take a look, and thanks for stopping by!</p>
<div class="zemanta-pixie"><a class="zemanta-pixie-a" href="http://reblog.zemanta.com/zemified/7a2ae51d-774b-47b5-894b-592c38ebf542/" title="Reblog this post [with Zemanta]"><img class="zemanta-pixie-img" src="http://img.zemanta.com/reblog_c.png?x-id=7a2ae51d-774b-47b5-894b-592c38ebf542" alt="Reblog this post [with Zemanta]" /></a><span class="zem-script more-related pretty-attribution"><script type="text/javascript" src="http://static.zemanta.com/readside/loader.js" defer="defer"></script></span></div>
<p>Related posts:<ol>
<li><a href='http://www.kellyrob99.com/blog/2009/11/21/different-flavors-of-embedded-groovy-in-java-apps-or-how-to-make-your-java-groovier/' rel='bookmark' title='Different Flavors of Embedded Groovy in Java Apps or &#8220;How To Make your Java Groovier!&#8221;'>Different Flavors of Embedded Groovy in Java Apps or &#8220;How To Make your Java Groovier!&#8221;</a></li>
<li><a href='http://www.kellyrob99.com/blog/2010/05/15/achieving-groovy-like-fluency-in-java-with-google-collections/' rel='bookmark' title='Achieving Groovy-like Fluency in Java with Google Collections'>Achieving Groovy-like Fluency in Java with Google Collections</a></li>
<li><a href='http://www.kellyrob99.com/blog/2010/04/17/groovy-and-hibernate-validator-for-dynamic-constraints/' rel='bookmark' title='Groovy and Hibernate Validator for Dynamic Constraints'>Groovy and Hibernate Validator for Dynamic Constraints</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.kellyrob99.com/blog/2010/03/14/breaking-weak-captcha-in-slightly-more-than-26-lines-of-groovy-code/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>WolframAlpha &#8211; Free for personal use but how much to subscribe?</title>
		<link>http://www.kellyrob99.com/blog/2009/05/17/wolframalpha-free-for-personal-use-but-how-much-to-subscribe/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=wolframalpha-free-for-personal-use-but-how-much-to-subscribe</link>
		<comments>http://www.kellyrob99.com/blog/2009/05/17/wolframalpha-free-for-personal-use-but-how-much-to-subscribe/#comments</comments>
		<pubDate>Sun, 17 May 2009 18:07:35 +0000</pubDate>
		<dc:creator>TheKaptain</dc:creator>
				<category><![CDATA[Cool Toys]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Application programming interface]]></category>
		<category><![CDATA[Google Maps]]></category>
		<category><![CDATA[Mathematica]]></category>
		<category><![CDATA[Wolfram Research]]></category>
		<category><![CDATA[Wolfram|Alpha]]></category>

		<guid isPermaLink="false">http://www.kellyrob99.com/blog/?p=417</guid>
		<description><![CDATA[And even more important perhaps, the &#8220;developer APIs&#8221; they&#8217;re hinting at. There seems to be a lot of talk about this being the next &#8216;Google-killer&#8217;, but that really doesn&#8217;t seem to be the point of this service. My personal interpretation of the new Wolfram&#124;Alpha service &#8211; this is the Mathematica guys showing off, and I [...]
No related posts.]]></description>
			<content:encoded><![CDATA[<p>And even more important perhaps, the &#8220;developer <a class="zem_slink" title="Application programming interface" rel="wikipedia" href="http://en.wikipedia.org/wiki/Application_programming_interface">APIs</a>&#8221; they&#8217;re hinting at.  There seems to be a lot of talk about this being the next <a href="http://www.google.ca/search?q=google-killer&amp;ie=utf-8&amp;oe=utf-8&amp;aq=t&amp;rls=org.mozilla:en-US:official&amp;client=firefox-a">&#8216;Google-killer&#8217;</a>, but that really doesn&#8217;t seem to be the point of this service. My personal interpretation of the new <a class="zem_slink" title="Wolfram Research" rel="homepage" href="http://www.wolframalpha.com/">Wolfram|Alpha service</a> &#8211; this is the <a class="zem_slink" title="Mathematica" rel="homepage" href="http://www.wolfram.com/products/mathematica/index.html">Mathematica</a> guys showing off, and I really can&#8217;t blame them. &#8220;10+ trillion of pieces of data, 50,000+ types of algorithms and models, and linguistic capabilities for 1000+ domains.&#8221; Ok, you can stop &#8211; you had me at &#8220;10+ trillion pieces of data&#8221;. Count me geekily intrigued.</p>
<p>For a little background, this is the same company that first released Mathematica almost 21 years ago. They&#8217;ve had a very long time to refine and expand their repertoire as well.  Mathematica, with its somewhat <a href="http://reference.wolfram.com/mathematica/guide/LanguageOverview.html">weird and wonderful syntax</a>, is in general a powerful language and platform for computation and visualization. Or so the PR materials claim.  They also boast that it is &#8220;The world&#8217;s most productive programming language.&#8221; We&#8217;ll just wait and see, now won&#8217;t we &#8211; and potentially have a Groovy showdown to answer that question.<br />
 <img src='http://www.kellyrob99.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /><br />
So what are the Mathematica guys doing now?</p>
<p><span style="font-size: large;">They&#8217;re Giving It Away!</span></p>
<p>Yup. Free, as in beer. The comprehensive knowledge-base and set of algorithms developed in Mathematica are backing the Wolfram|Alpha site(WA from here on in cause it&#8217;s too much to type, tyvm), providing some great visualizations and, at least so far, some pretty good interpretations for natural language queries.&nbsp; While hit and miss for some things that WA doesn&#8217;t know about(yet), what it does know it shows off pretty well. Locations resolve to census and geographical data, and what good mashup would be complete without Google Maps integration.&nbsp; It can give you a comprehensive weather report, for now or for a decade in the past.&nbsp; The part that caught my attention was the easy access to genomic data. I was delighted today to find that they have a fairly comprehensive library of &#8220;<a class="zem_slink" title="Biology" rel="wikipedia" href="http://en.wikipedia.org/wiki/Biology">Life Sciences</a>&#8221; data, algorithms and examples available. If you enter a <a class="zem_slink" href="http://en.wikipedia.org/wiki/Genome" title="Genome" rel="wikipedia">genome sequence</a> such as <a href="http://www78.wolframalpha.com/input/?i=AAGCTAGCTAGC">AAGCTAGCTAGC</a> you get chromosomal matches. Information on proteins, <a class="zem_slink" href="http://en.wikipedia.org/wiki/Single-nucleotide_polymorphism" title="Single-nucleotide polymorphism" rel="wikipedia">SNPs</a> and other biological tidbits is also readily available.</p>
<p>There are a couple of catches here, of course.&nbsp; No robots allowed, although how they will enforce this I do not know. If you use the content somewhere else, give appropriate credit &#8211; citing sources is hardly painful for good info. No <a class="zem_slink" href="http://en.wikipedia.org/wiki/Reverse_engineering" title="Reverse engineering" rel="wikipedia">reverse-engineering</a>, etc to try and steal their product or algorithms. And no commerical use allowed, which stands to reason coming from a company whose flagship product appears to start with a <a href="http://www.wolfram.com/products/mathematicahomeedition/">$295 home edition pricetag</a>. That last one leads me around to the topic of this post.</p>
<p><span style="font-size: large;">How much to subscribe?</span></p>
<p>They&#8217;re not being at all coy about their intent to monetize WA. I couldn&#8217;t find a pricetag anywhere, but you can bet that their subscription link has been clicked a few times today. With promises for API&#8217;s, the potential for companies to purchase/rent their own private WA servers, and delivering the content through a browser powered by a single text input &#8211; these are some pretty compelling selling points, at least IMO.  It&#8217;ll be interesting to see where the bottom line is for this potentially powerful service. In the meantime, they&#8217;ve done a fantastic job of getting the world at large to load test their software for free.  And if they ever put out a free developer version, you&#8217;ll be seeing a future post. In the meantime, I&#8217;ll be looking for some indication of how much it&#8217;s going to cost. If the price matches the hype, it won&#8217;t be cheap, unfortunatley.</p>

<div class="ngg-galleryoverview" id="ngg-gallery-4-417">

	<!-- Slideshow link -->
	<div class="slideshowlink">
		<a class="slideshowlink" href="http://www.kellyrob99.com/blog/2009/05/17/wolframalpha-free-for-personal-use-but-how-much-to-subscribe/?show=slide">
			[Show as slideshow]		</a>
	</div>

	<!-- Piclense link -->
	<div class="piclenselink">
		<a class="piclenselink" href="javascript:PicLensLite.start({feedUrl:'http://www.kellyrob99.com/blog/wp-content/plugins/nextgen-gallery/xml/media-rss.php?gid=4&amp;mode=gallery'});">
			[View with PicLens]		</a>
	</div>
	
	<!-- Thumbnails -->
		
	<div id="ngg-image-21" class="ngg-gallery-thumbnail-box"  >
		<div class="ngg-gallery-thumbnail" >
			<a href="http://www.kellyrob99.com/blog/wp-content/gallery/wolframalpha/genomesequence.png" title=" " class="shutterset_set_4" >
								<img title="genomesequence.png" alt="genomesequence.png" src="http://www.kellyrob99.com/blog/wp-content/gallery/wolframalpha/thumbs/thumbs_genomesequence.png" width="100" height="75" />
							</a>
		</div>
	</div>
	
		
 		
	<div id="ngg-image-22" class="ngg-gallery-thumbnail-box"  >
		<div class="ngg-gallery-thumbnail" >
			<a href="http://www.kellyrob99.com/blog/wp-content/gallery/wolframalpha/lifesciences.png" title=" " class="shutterset_set_4" >
								<img title="lifesciences.png" alt="lifesciences.png" src="http://www.kellyrob99.com/blog/wp-content/gallery/wolframalpha/thumbs/thumbs_lifesciences.png" width="100" height="75" />
							</a>
		</div>
	</div>
	
		
 		
	<div id="ngg-image-23" class="ngg-gallery-thumbnail-box"  >
		<div class="ngg-gallery-thumbnail" >
			<a href="http://www.kellyrob99.com/blog/wp-content/gallery/wolframalpha/location.png" title=" " class="shutterset_set_4" >
								<img title="location.png" alt="location.png" src="http://www.kellyrob99.com/blog/wp-content/gallery/wolframalpha/thumbs/thumbs_location.png" width="100" height="75" />
							</a>
		</div>
	</div>
	
		
 		
	<div id="ngg-image-24" class="ngg-gallery-thumbnail-box"  >
		<div class="ngg-gallery-thumbnail" >
			<a href="http://www.kellyrob99.com/blog/wp-content/gallery/wolframalpha/snp.png" title=" " class="shutterset_set_4" >
								<img title="snp.png" alt="snp.png" src="http://www.kellyrob99.com/blog/wp-content/gallery/wolframalpha/thumbs/thumbs_snp.png" width="100" height="75" />
							</a>
		</div>
	</div>
	
		
 		
	<div id="ngg-image-25" class="ngg-gallery-thumbnail-box"  >
		<div class="ngg-gallery-thumbnail" >
			<a href="http://www.kellyrob99.com/blog/wp-content/gallery/wolframalpha/what-a-lot-of-the-links-are-pointing-to.png" title=" " class="shutterset_set_4" >
								<img title="what-a-lot-of-the-links-are-pointing-to.png" alt="what-a-lot-of-the-links-are-pointing-to.png" src="http://www.kellyrob99.com/blog/wp-content/gallery/wolframalpha/thumbs/thumbs_what-a-lot-of-the-links-are-pointing-to.png" width="100" height="75" />
							</a>
		</div>
	</div>
	
		
 	 	
	<!-- Pagination -->
 	<div class='ngg-clear'></div>
 	
</div>


<div class="zemanta-pixie"><a class="zemanta-pixie-a" href="http://reblog.zemanta.com/zemified/3006f105-d8f8-43f9-b88b-fa566daf2961/" title="Reblog this post [with Zemanta]"><img class="zemanta-pixie-img" src="http://img.zemanta.com/reblog_c.png?x-id=3006f105-d8f8-43f9-b88b-fa566daf2961" alt="Reblog this post [with Zemanta]" /></a><span class="zem-script more-related pretty-attribution"><script type="text/javascript" src="http://static.zemanta.com/readside/loader.js" defer="defer"></script></span></div>
<p>No related posts.</p>]]></content:encoded>
			<wfw:commentRss>http://www.kellyrob99.com/blog/2009/05/17/wolframalpha-free-for-personal-use-but-how-much-to-subscribe/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

