<?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>Francis Shanahan[.com] &#187; General Computing</title>
	<atom:link href="http://francisshanahan.com/index.php/category/computing/feed/" rel="self" type="application/rss+xml" />
	<link>http://francisshanahan.com</link>
	<description>Thoughts on technology from a citizen scientist</description>
	<lastBuildDate>Fri, 27 Jan 2012 14:18:12 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Sencha Touch 2.0 MVC in 5 minutes or less</title>
		<link>http://francisshanahan.com/index.php/2011/sencha-touch-2-0-mvc-in-5-minutes-or-less/</link>
		<comments>http://francisshanahan.com/index.php/2011/sencha-touch-2-0-mvc-in-5-minutes-or-less/#comments</comments>
		<pubDate>Fri, 21 Oct 2011 15:06:45 +0000</pubDate>
		<dc:creator>Francis</dc:creator>
				<category><![CDATA[Featured]]></category>
		<category><![CDATA[Headline]]></category>
		<category><![CDATA[html5]]></category>
		<category><![CDATA[Web Development]]></category>

		<guid isPermaLink="false">http://francisshanahan.com/?p=3274</guid>
		<description><![CDATA[I&#8217;ve shied away from JS frameworks on the mobile platform primarily due to performance. I had not been able to find one that came close to native performance on Android. This changed last weekend when I tried out the Sencha Touch 2.0 dev preview. Performance is vastly improved over Touch 1.0. Animations and transitions are smooth, even on my Android 2.2 device and I was able to get up and running very fast. 
Grab the Sencha Touch 2.0 Dev Preview here: http://www.sencha.com/blog/sencha-touch-2-developer-preview/
While I was able to get a basic app ...]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve shied away from JS frameworks on the mobile platform primarily due to performance. I had not been able to find one that came close to native performance on Android. This changed last weekend when I tried out the Sencha Touch 2.0 dev preview. Performance is vastly improved over Touch 1.0. Animations and transitions are smooth, even on my Android 2.2 device and I was able to get up and running very fast. </p>
<p>Grab the Sencha Touch 2.0 Dev Preview here: <a href="http://www.sencha.com/blog/sencha-touch-2-developer-preview/" target="_blank">http://www.sencha.com/blog/sencha-touch-2-developer-preview/</a></p>
<p>While I was able to get a basic app up and running quickly, unfortunately I spent a lot of time re-factoring into a proper MVC structure. The documentation on how to do this in Touch 2.0 is not there yet and there are some albeit small but killer differences between Touch1.0 and 2.0. To a novice like me they cost me a few hours. </p>
<p>Everything here was based off the Sencha ExtJS 4.0 walkthrough available here: </p>
<ul>
<li><a href="http://www.sencha.com/learn/architecting-your-app-in-ext-js-4-part-1/">http://www.sencha.com/learn/architecting-your-app-in-ext-js-4-part-1/</a></li>
<li><a href="http://www.sencha.com/learn/architecting-your-app-in-ext-js-4-part-2/">http://www.sencha.com/learn/architecting-your-app-in-ext-js-4-part-2/</a></li>
<li><a href="http://www.sencha.com/learn/architecting-your-app-in-ext-js-4-part-3/">http://www.sencha.com/learn/architecting-your-app-in-ext-js-4-part-3/</a></li>
</ul>
<p>The sample code is available on Github and you can go here and download the entire project in a single ZIP/TAR: <a href="https://github.com/FrancisShanahan/SenchaTouch2MVCHelloworld" target="_blank">https://github.com/FrancisShanahan/SenchaTouch2MVCHelloworld</a></p>
<p>Or you can fork the repo using git: <a href="http://help.github.com/fork-a-repo/" target="_blank">http://help.github.com/fork-a-repo/</a></p>
<p>Here are a few key points:</p>
<p>a) Let the app instantiate your controllers and any global stores your app needs. Notice how the initial layout is created using xtypes? These are created as aliases in the views.<br />
<script src="https://gist.github.com/1303996.js"> </script></p>
<p>b) Let your controllers instantiate your views and stores.<br />
<script src="https://gist.github.com/1304002.js"> </script></p>
<p>c) Use Component Queries instead of Ext.getCmp(&#8216;id goes here&#8217;). This&#8217;ll keep your code more manageable as the code base grows. Note, the &#8220;ref&#8221; name here is important as it&#8217;s used to generate getters for the view instances. E.g. a ref of &#8220;stationList&#8221; will create a getter on the controller of &#8220;getStationList&#8221;. </p>
<p><script src="https://gist.github.com/1304014.js"> </script></p>
<p>I&#8217;ve already heard from a few folks so it looks like this project is helpful. It&#8217;s also ready for dropping into a Phonegap shell. Fork it and update or let me know if there&#8217;s anything you&#8217;d like to see added. </p>
<p>Attribution: Today&#8217;s photo comes from Anxo Resúa&#8217;s stream on Flickr <a href="http://www.flickr.com/photos/anxoresua/4652943076/">http://www.flickr.com/photos/anxoresua/4652943076/</a></p>
]]></content:encoded>
			<wfw:commentRss>http://francisshanahan.com/index.php/2011/sencha-touch-2-0-mvc-in-5-minutes-or-less/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>Stream a webcam using Javascript, NodeJS, Android, Opera Mobile, Web Sockets and HTML5</title>
		<link>http://francisshanahan.com/index.php/2011/stream-a-webcam-using-javascript-nodejs-android-opera-mobile-web-sockets-and-html5/</link>
		<comments>http://francisshanahan.com/index.php/2011/stream-a-webcam-using-javascript-nodejs-android-opera-mobile-web-sockets-and-html5/#comments</comments>
		<pubDate>Mon, 19 Sep 2011 20:29:04 +0000</pubDate>
		<dc:creator>Francis</dc:creator>
				<category><![CDATA[Cool & Future Tech]]></category>
		<category><![CDATA[Featured]]></category>
		<category><![CDATA[Headline]]></category>
		<category><![CDATA[html5]]></category>
		<category><![CDATA[Things I've Made]]></category>

		<guid isPermaLink="false">http://francisshanahan.com/?p=3265</guid>
		<description><![CDATA[With all the recent Goruck-ness it&#8217;s time to throw out a tech post. I&#8217;ve been prepping for a NodeJS presentation recently and wanted a unique demo. I had also come across the experimental build of Opera which supports accessing the native webcam of a mobile device. So I threw these two technologies together and came up with a Javascript powered way to stream a video camera from a mobile device to a bunch of desktop (or mobile) clients. 
HTML5 had originally laid out support for a new element (the &#8220;device&#8221; ...]]></description>
			<content:encoded><![CDATA[<p>With all the recent Goruck-ness it&#8217;s time to throw out a tech post. I&#8217;ve been prepping for a NodeJS presentation recently and wanted a unique demo. I had also come across the experimental build of Opera which supports accessing the native webcam of a mobile device. So I threw these two technologies together and came up with a Javascript powered way to stream a video camera from a mobile device to a bunch of desktop (or mobile) clients. </p>
<p>HTML5 had originally laid out support for a new element (the &#8220;device&#8221; element) but it appears this element has been scrapped now in favour of the &#8220;getUserMedia&#8221; API. So far I have only seen the Opera Mobile Experimental build support this but hopefully it&#8217;ll get into Dolphin and other mobile browsers soon. </p>
<p><a href="http://my.opera.com/core/blog/2011/03/23/webcam-orientation-preview">http://my.opera.com/core/blog/2011/03/23/webcam-orientation-preview</a></p>
<p>If you just want to cut to the chase here&#8217;s a video of the final result:<br />
<iframe width="560" height="315" src="http://www.youtube.com/embed/cjmuwA8l1LQ" frameborder="0" allowfullscreen></iframe></p>
<p>There are three moving parts here</p>
<ul>
<li>a) The client page which captures the video</li>
<li>b) the server which is a simple Node broadcast server </li>
<li>c) and the Client which is just a web page that renders the output. </li>
</ul>
<p>The client is just a copy-paste from Opera&#8217;s website. I take the video stream, render it to a canvas, then grab the canvas as a base64 encoded image. One image per frame. I could not find a way to limit the video&#8217;s size so the resulting image is fairly large (240&#215;400 on an HTC Incredible).  I down-sampled, cutting the image data to reduce the traffic over the wire. Framerates are still pretty poor but this is just an experiment. </p>
<p>The server is a generic websockets server and gets a message which is a raw data/base64 stream. It broadcasts this down the any connected clients. </p>
<p>The client then is the simplest of all, just connects to the socket server and renders whatever it gets to an <img> tag. </p>
<p>It&#8217;s all Javascript. </p>
<p>Client (this is a jade view). </p>
<pre class="brush: javascript">

h1
    Remote Webcam using NodeJS, Opera, Web Sockets and HTML5/Canvas
video(autoplay=true,id=&quot;sourcevid&quot;)
canvas(id=&quot;output&quot;)
div(id=&quot;log&quot;)
script
    var log = function(msg) {
       document.getElementById(&#039;log&#039;).innerHTML = document.getElementById(&#039;log&#039;).innerHTML + msg + &quot;&lt;br/&gt;&quot;;
    };
    var video = document.getElementsByTagName(&#039;video&#039;)[0],
        heading = document.getElementsByTagName(&#039;h1&#039;)[0];
    if(navigator.getUserMedia) {
        navigator.getUserMedia(&#039;video&#039;, successCallback, errorCallback);

        function successCallback( stream ) {
            video.src = stream;
        };

        function errorCallback( error ) {
            heading.textContent = &quot;An error occurred: [CODE &quot; + error.code + &quot;]&quot;;
        };
    } else {
        heading.textContent = &quot;Native web camera streaming is not supported in this browser!&quot;;
    };

    var back = document.createElement(&#039;canvas&#039;);
    var backcontext = back.getContext(&#039;2d&#039;);

    var ws;

    if(&#039;WebSocket&#039; in window){
        connect(&#039;ws://192.168.2.100:8080/&#039;);
    } else {
        log (&#039;web sockets not supported&#039;);
     }

    function connect(host) {
        ws = new WebSocket(host);
        ws.onopen = function () {
            log(&#039;connected&#039;);
        };

        ws.onclose = function () {
            log(&#039;socket closed&#039;);
        };

        ws.onerror = function (evt) {
            log(&#039;&lt;span style=&quot;color: red;&quot;&gt;ERROR:&lt;/span&gt; &#039; + evt.data);
        };
    };

    function send(msg){
        if (ws != null) {
            if(ws.readyState === 1) {
               ws.send(msg);
            }
        } else {
            //log (&#039;not ready yet&#039;);
        }
    }    

    cw = 120;//240;//video.clientWidth;
    ch = 200;//400;//video.clientHeight;
    log(&#039;width = &#039; + ch);
    back.width = cw;
    back.height = ch;
    draw(video, backcontext, cw, ch);

    function draw(v, bc, w, h) {

        // First, draw it into the backing canvas
        bc.drawImage(v, 0, 0, w, h);

        // Grab the pixel data from the backing canvas
        var stringData=back.toDataURL();

        // send it on the wire
        send(stringData);

        // Start over! 10 frames a second = 100milliseconds
        setTimeout(function(){ draw(v, bc, w, h); });
    }
</pre>
<p>The server. Simple Broadcast app.</p>
<pre class="brush: javascript">

var sys = require(&quot;sys&quot;),
    ws = require(&quot;./ws.js&quot;);

var clients = [];

ws.createServer(
	function (websocket) {

		clients.push(websocket);

		websocket.addListener(&quot;connect&quot;, function (resource) {
			// emitted after handshake
			sys.debug(&quot;connect: &quot; + resource);
		}).addListener(&quot;data&quot;, function (data) {

		// handle incoming data
		// send data to ALL clients whenever ANY client send up data
		for (var i = 0 ; i &lt; clients.length ; i ++ ) {
			clients[i].write(data);
		}

    }).addListener(&quot;close&quot;, function () {

		// emitted when server or client closes connection
		sys.debug(&quot;close&quot;);
    });
  }).listen(8080);

  sys.debug(&quot;Listening on port 8080&quot;);
</pre>
<p>The client. </p>
<pre class="brush: javascript">

&lt;img src=&quot;&quot; id=&quot;frame&quot; style=&quot;width:240px;height:400px&quot;/&gt;

&lt;div id=&quot;log&quot;&gt;&lt;/div&gt;

&lt;script type=&quot;text/javascript&quot;&gt;

	var img; 

	function Init() {

		img = document.getElementById(&quot;frame&quot;);	

	}

	$(document).ready(function () {

		Init();

	});

// Web socket connection stuff is next...	

	if(&#039;WebSocket&#039; in window){

		connect(&#039;ws://localhost:8080/&#039;);		

	} else {

		log (&#039;web sockets not supported&#039;);

	}

	var ws;

	function connect(host) {

		ws = new WebSocket(host);

		ws.onopen = function () {

			log(&#039;connected&#039;);

		};

		ws.onmessage = function (evt) {  	

            if (evt.data != null) {		

			  if ((evt.data[0]=== &quot;d&quot;) &amp;amp;amp;amp;amp;&amp;amp;amp;amp;amp; (evt.data[1]===&quot;a&quot;) ) img.src=evt.data;	//log(&#039;got&#039; + evt.data);

			}

		};

		ws.onclose = function () {

			log(&#039;socket closed&#039;);

		};

		ws.onerror = function (evt) { 

			log(&#039;&lt;span style=&quot;color: red;&quot;&gt;ERROR:&lt;/span&gt; &#039; + evt.data); 

		};

	};

	function log(msg){

		document.getElementById(&#039;log&#039;).innerHTML = msg + &quot;&lt;br/&gt;&quot; + document.getElementById(&#039;log&#039;).innerHTML ;

	}
&lt;/script&gt;
</pre>
<p>Instead of broadcasting, you could store these frames in a MongoDB for assembly later. This would make the ultimate, storage independent video camera. Never run out of storage again!</p>
<p>I really need to start storing these snippets on github&#8230;</p>
<p>P.S. Everyone knows insects are clockwork which is why god made so many of them. Today&#8217;s image is from <a href="http://www.insectlabstudio.com/">http://www.insectlabstudio.com/</a></p>
]]></content:encoded>
			<wfw:commentRss>http://francisshanahan.com/index.php/2011/stream-a-webcam-using-javascript-nodejs-android-opera-mobile-web-sockets-and-html5/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Mycellium Source Code Available</title>
		<link>http://francisshanahan.com/index.php/2011/mycellium-source-code-available/</link>
		<comments>http://francisshanahan.com/index.php/2011/mycellium-source-code-available/#comments</comments>
		<pubDate>Wed, 06 Jul 2011 14:08:35 +0000</pubDate>
		<dc:creator>Francis</dc:creator>
				<category><![CDATA[Featured]]></category>
		<category><![CDATA[Headline]]></category>
		<category><![CDATA[html5]]></category>
		<category><![CDATA[canvas]]></category>

		<guid isPermaLink="false">http://francisshanahan.com/?p=3158</guid>
		<description><![CDATA[Last time [LINK] I discussed how virtual Worms could &#8220;eat&#8221; a picture, seeking out the lighter or darker areas as food and leaving a trail in their wake. I&#8217;ve dumped the source here: http://francisshanahan.com/demos/worms/test.html so you can interact, create your own images and figure out how it&#8217;s done. To be honest I haven&#8217;t had much time to clean this up as I&#8217;ve been focusing on other things and doing a bit of travel for work so be gentle. 
Just enter a URL of an image and click &#8220;create drawing&#8221; to ...]]></description>
			<content:encoded><![CDATA[<p>Last time [<a href="http://francisshanahan.com/index.php/2011/emulating-mycelium-hyphae-with-html5/">LINK</a>] I discussed how virtual Worms could &#8220;eat&#8221; a picture, seeking out the lighter or darker areas as food and leaving a trail in their wake. I&#8217;ve dumped the source here: <a href="http://francisshanahan.com/demos/worms/test.html">http://francisshanahan.com/demos/worms/test.html</a> so you can interact, create your own images and figure out how it&#8217;s done. To be honest I haven&#8217;t had much time to clean this up as I&#8217;ve been focusing on other things and doing a bit of travel for work so be gentle. </p>
<p>Just enter a URL of an image and click &#8220;create drawing&#8221; to being. The page will load that image into a hidden canvas and use it as reference to draw the picture. You should use Chrome of course but this should work in all HTML5 compatible browsers. </p>
<p>Room for improvement might be to place the code in an enclosure, cleaning up the global DOM namespace or  multi-thread it this using Web Workers although the current speed is acceptable. Web Workers in this instance might be overkill. </p>
<p>Enjoy. </p>
]]></content:encoded>
			<wfw:commentRss>http://francisshanahan.com/index.php/2011/mycellium-source-code-available/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Using Node.js, Cygwin and Web Sockets</title>
		<link>http://francisshanahan.com/index.php/2011/using-node-js-cygwin-and-web-sockets/</link>
		<comments>http://francisshanahan.com/index.php/2011/using-node-js-cygwin-and-web-sockets/#comments</comments>
		<pubDate>Thu, 23 Jun 2011 20:40:28 +0000</pubDate>
		<dc:creator>Francis</dc:creator>
				<category><![CDATA[Cool & Future Tech]]></category>
		<category><![CDATA[Featured]]></category>
		<category><![CDATA[Headline]]></category>
		<category><![CDATA[html5]]></category>
		<category><![CDATA[Web Development]]></category>

		<guid isPermaLink="false">http://francisshanahan.com/?p=2995</guid>
		<description><![CDATA[If you have not heard of Node.js (or &#8220;Node&#8221; as Ryan Dahl calls it) [LINK] it is more fun than a barrel full of monkeys and faster than stink. Node.js is built around the Google V8 javascript engine and aims to solve the issues of concurrency and blocking IO which are prevalent in todays web servers. It also improves over traditional OS threading by using an event model to handle requests. This leads to the ability to handle many more concurrent requests but also handle them faster since less memory ...]]></description>
			<content:encoded><![CDATA[<p>If you have not heard of Node.js (or &#8220;Node&#8221; as Ryan Dahl calls it) [<a href="http://nodejs.org">LINK</a>] it is more fun than a barrel full of monkeys and faster than stink. Node.js is built around the Google V8 javascript engine and aims to solve the issues of concurrency and blocking IO which are prevalent in todays web servers. It also improves over traditional OS threading by using an event model to handle requests. This leads to the ability to handle many more concurrent requests but also handle them faster since less memory is allocated on the heap for each new call. </p>
<p>I spent some time last week looking at Web Sockets as a way to push information to the client. Web sockets need a custom server, not an HTTP server, so I used Nugget which is an open source implementation of the web socket protocol on CodePlex (http://nugget.codeplex.com/). Nugget worked great but with all the hype and interest around Node I felt I was missing something so I built the same thing again, this time around using Node.js on the server side. </p>
<p>Before get started you&#8217;ll need to build Node. This can be done </p>
<blockquote><p>&#8220;on Linux, Macintosh, and Solaris. It also runs on Windows/Cygwin, FreeBSD, and OpenBSD. The build system requires Python 2.4 or better. V8, on which Node is built, supports only IA-32, x64, and ARM processors. V8 is included in the Node distribution. To use TLS, OpenSSL is required. There are no other dependencies.&#8221;</p></blockquote>
<p>I used Cygwin on Wintel and installed g++, Python 2.7 and GNU Make. You also need OpenSSL if you plan on using Node with Web Sockets.</p>
<p>Here&#8217;s a comprehensive walkthrough of installing Cygwin and building Node from scratch: [<a href="https://github.com/joyent/node/wiki/Building-node.js-on-Cygwin-%28Windows%29">LINK</a>]</p>
<p>Web Sockets uses a funky little handshake protocol [<a href="http://en.wikipedia.org/wiki/WebSockets#WebSocket_Protocol_Handshake">LINK</a>] to establish the connection which I didn&#8217;t feel like implementing so I came across a WS Server implementation using Node.JS up on GitHub [<a href="https://github.com/miksago/node-websocket-server/">https://github.com/miksago/node-websocket-server/</a>]. This worked well with Node 0.2.5  testing from Chrome 12 which uses v-76 of the Hixie protocol.</p>
<p>Here&#8217;s my client which is based off the Dive into HTML5 example:</p>
<pre class="brush: javascript">
if(Modernizr.websockets){
	    connect(&#039;ws://localhost:3400/service&#039;);
	} else {
		log (&#039;web sockets not supported&#039;);
	}
	var ws;

	function connect(host) {
		ws = new WebSocket(host);
		ws.onopen = function () {
			log(&#039;connected&#039;);
		};

		ws.onmessage = function (evt) {
			log(&#039;recv :&#039; + evt.data);
			showNotification(evt.data);
		};

		ws.onclose = function () {
			log(&#039;socket closed&#039;);
		};

		ws.onerror = function (evt) {
			log(&#039;&lt;span style=&quot;color: red;&quot;&gt;ERROR:&lt;/span&gt; &#039; + evt.data);
		};
	};

	function log(msg){
		document.getElementById(&#039;log&#039;).innerHTML += msg + &quot;&lt;br/&gt;&quot;;
	}

	function send(){
		var msg = document.getElementById(&#039;status&#039;).value;
		ws.send(msg);
	}

	function RequestPermission (callback) {
		window.webkitNotifications.requestPermission(callback);
	}

	function showNotification(msg){
		if (window.webkitNotifications.checkPermission() &gt; 0) {
			RequestPermission(showNotification);
		}
		else {
			window.webkitNotifications.createNotification(&quot;alert.jpg&quot;, &quot;Test Notification&quot;, msg).show();
		}
	}
</pre>
<p>With this client-side scripe and Node running the ws-socket server I was able to get a simple echo running forth between the web page and the server.</p>
<p>Node has gained some ground since I first looked at it (back when Chrome was on version 8). Even Microsoft has announced plans to port it over to Windows [<a href="http://blogs.msdn.com/b/interoperability/archive/2011/06/23/microsoft-working-with-joyent-and-the-node-community-to-bring-node-js-to-windows.aspx">LINK</a>]. In the coming weeks I plan on looking at some of the templating engines (Like http://jade-lang.com/ and http://mustache.github.com/)  and web frameworks (like http://expressjs.com and http://geddyjs.org/ ) which have cropped up around it and will report back on whether it&#8217;s ready for prime time or not. Watch this space. </p>
<p>Attribution: Today&#8217;s image by Casch52 on Flickr [<a href="http://www.flickr.com/photos/casch/470563640/">LINK</a>]</p>
]]></content:encoded>
			<wfw:commentRss>http://francisshanahan.com/index.php/2011/using-node-js-cygwin-and-web-sockets/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Emulating Mycelium Hyphae with HTML5</title>
		<link>http://francisshanahan.com/index.php/2011/emulating-mycelium-hyphae-with-html5/</link>
		<comments>http://francisshanahan.com/index.php/2011/emulating-mycelium-hyphae-with-html5/#comments</comments>
		<pubDate>Mon, 09 May 2011 21:00:23 +0000</pubDate>
		<dc:creator>Francis</dc:creator>
				<category><![CDATA[Featured]]></category>
		<category><![CDATA[Headline]]></category>
		<category><![CDATA[html5]]></category>
		<category><![CDATA[canvas]]></category>
		<category><![CDATA[fungus]]></category>

		<guid isPermaLink="false">http://francisshanahan.com/?p=3084</guid>
		<description><![CDATA[Mycelium (plural mycelia) is the vegetative part of a fungus, consisting of a mass of branching, thread-like hyphae. Hyphae are any of the threadlike filaments forming the mycelium of a fungus. And YES I had to look both of those up. 
Typically they travel and branch along a source of nutrients, following the source. I came across this awesome work of Ryan Alexander [LINK] whilst messing around with Processing one evening. Ryan used Processing which is similar to Java. Processing is a great sketch-language which makes whipping up graphical wonders ...]]></description>
			<content:encoded><![CDATA[<p>Mycelium (plural mycelia) is the vegetative part of a fungus, consisting of a mass of branching, thread-like hyphae. Hyphae are any of the threadlike filaments forming the mycelium of a fungus. And YES I had to look both of those up. </p>
<p>Typically they travel and branch along a source of nutrients, following the source. I came across this awesome work of Ryan Alexander [<a href="http://onecm.com/" target="_blank">LINK</a>] whilst messing around with Processing one evening. Ryan used Processing which is similar to Java. Processing is a great sketch-language which makes whipping up graphical wonders a doddle and is a favourite of interactive media artists. It&#8217;s really cool and I&#8217;ve been messing with it for a few years now. Check out &#8220;http://processing.org/&#8221; for more. </p>
<p>A few hours later I had the same thing implemented in Javascript and HTML5 using the Canvas element although mine is not as sophisticated as Ryan&#8217;s.</p>
<blockquote><p>Disclaimer: I know nothing of Mycelium or of Hyphae or how they branch and form. I merely tried to emulate how the branching works.</p></blockquote>
<p>Basically you take an image as input and a number of threads are created, I called them &#8220;worms&#8221; since &#8220;hyphae&#8221; seemed a but over the top. The worms have a trajectory and will move along it in search of food. Each iteration the worm decides where to move, favouring the light or dark portions of the image. Just as in Ryan&#8217;s Processing application the image acts as a source of food. If the worm ventures into a dark portion of the image, after a while without food, he dies.</p>
<p>I&#8217;m sure there&#8217;s a lot more to say on how this Mycelium stuff grows than what I&#8217;ve modeled here. For example I didn&#8217;t consider the amount of food contributing to the speed of the &#8220;worm&#8221; nor did I attempt to make the worms avoid each other. This was primarily an artistic endeavor and a creative outlet written over a beer one night. </p>
<p>I made a bunch of different images, Martin Luthor King, Bob Dylan, Willie Nelson, Clint Eastwood. For Clint&#8217;s I made a slight adjustment where any worm that died I&#8217;d re-spawn inside his eyes. Results were pretty nice. Here&#8217;s the Flickr Album: <a href="http://www.flickr.com/photos/10277648@N03/with/5704290009/" target="_blank">http://www.flickr.com/photos/10277648@N03/with/5704290009/</a></p>
<p><a href="http://www.flickr.com/photos/10277648@N03/5704290009/" title="clintbig3 by francisshanahan, on Flickr"><img src="http://farm4.static.flickr.com/3137/5704290009_9fd5455ccd.jpg" width="371" height="500" alt="clintbig3"></a></p>
<p>This technique works best on images with high-contrasting areas. Basically wrinkled old men. You&#8217;ll notice how the hyphae follow the wrinkles in Clint&#8217;s face.</p>
<p><a href="http://www.flickr.com/photos/10277648@N03/5704288959/" title="dylan by francisshanahan, on Flickr"><img src="http://farm4.static.flickr.com/3099/5704288959_58e2448027.jpg" width="393" height="500" alt="dylan"></a></p>
<p>Bob Dylan was surprising as the threads were never able to &#8220;break through&#8221; into the darker areas around his eyes. He just didn&#8217;t have enough wrinkles to feed them. </p>
<p><a href="http://www.flickr.com/photos/10277648@N03/5704856326/" title="willie2 by francisshanahan, on Flickr"><img src="http://farm4.static.flickr.com/3274/5704856326_d715484ccd.jpg" width="402" height="500" alt="willie2"></a></p>
<p>Willie Nelson, looking down. You can start to see his two braids forming in the weeds. </p>
<p>If you like these click over to the Flickr Album for more: <a href="http://www.flickr.com/photos/10277648@N03/with/5704290009/">http://www.flickr.com/photos/10277648@N03/with/5704290009/</a></p>
<p>Interesting factoid: At one point Mycelium was considered the largest living organism in the world! From Wikipedia:</p>
<blockquote><p>This 2,400-acre (9.7 km2) site in eastern Oregon had a contiguous growth of mycelium before logging roads cut through it. Estimated at 1,665 football fields in size and 2,200 years old, this one fungus has killed the forest above it several times over, and in so doing has built deeper soil layers that allow the growth of ever-larger stands of trees. Mushroom-forming forest fungi are unique in that their mycelial mats can achieve such massive proportions.</p></blockquote>
<p>In the coming days I&#8217;ll clean up the code and try to make it configurable so you can upload your own photos and play along. More to come on this one&#8230;</p>
<p>[UPDATE] Source code is now available here: <a href="http://francisshanahan.com/index.php/2011/mycellium-source-code-available/">http://francisshanahan.com/index.php/2011/mycellium-source-code-available/</a></p>
]]></content:encoded>
			<wfw:commentRss>http://francisshanahan.com/index.php/2011/emulating-mycelium-hyphae-with-html5/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Android Development Cheatsheet</title>
		<link>http://francisshanahan.com/index.php/2011/android-development-cheatsheet/</link>
		<comments>http://francisshanahan.com/index.php/2011/android-development-cheatsheet/#comments</comments>
		<pubDate>Thu, 07 Apr 2011 20:09:12 +0000</pubDate>
		<dc:creator>Francis</dc:creator>
				<category><![CDATA[Cool & Future Tech]]></category>
		<category><![CDATA[Featured]]></category>
		<category><![CDATA[General Computing]]></category>
		<category><![CDATA[Headline]]></category>
		<category><![CDATA[android]]></category>
		<category><![CDATA[mobile]]></category>

		<guid isPermaLink="false">http://francisshanahan.com/?p=3070</guid>
		<description><![CDATA[Here&#8217;s a rundown of everything I ran into when hacking my way through android development.
Setup Eclipse, run the Android SDK installer, install the correct USB drivers and finally check your device setup with &#8220;adb devices&#8221;. Your device should be listed. 
If you don&#8217;t have an android device, be prepared for the emulator to be extremely slow especially during startup/shutdown. Be sure to mark your emulator as &#8220;Snapshot&#8221; (accessible from the ADB/AVD SDK Manager-> Start button). Also, don&#8217;t connect your device whilst the emulator is running. Adb gets confused. 
I had ...]]></description>
			<content:encoded><![CDATA[<p>Here&#8217;s a rundown of everything I ran into when hacking my way through android development.</p>
<p>Setup Eclipse, run the Android SDK installer, install the <a href="http://developer.android.com/sdk/oem-usb.html" target="_blank" >correct USB drivers</a> and finally check your device setup with &#8220;adb devices&#8221;. Your device should be listed. </p>
<p>If you don&#8217;t have an android device, be prepared for the emulator to be extremely slow especially during startup/shutdown. Be sure to mark your emulator as &#8220;Snapshot&#8221; (accessible from the ADB/AVD SDK Manager-> Start button). Also, don&#8217;t connect your device whilst the emulator is running. Adb gets confused. </p>
<p>I had one occurrence where the drawable resources to my project failed to get copied over properly to the device and I spent 20 minutes trying to figure out what I&#8217;d changed in my code. Turning out the emulator was running in the background. I did shut the emulator off and did an adb uninstall &#8220;myApp&#8221; and then redeployed to fix it. </p>
<p>Android works on Intents, Activities and Services. If you want to access the hardware, e.g. the Camera, you&#8217;ll need to fire off an Intent. Here&#8217;s an example of launching an Intent to get a Bitmap back from the camera: </p>
<p><a href="http://mobile.tutsplus.com/tutorials/android/android-sdk-quick-tip-launching-the-camera/" target="_blank" >http://mobile.tutsplus.com/tutorials/android/android-sdk-quick-tip-launching-the-camera/</a></p>
<p>You&#8217;ll also need to mark your application with the right permissions in the AndroidManifest.xml file. Here&#8217;s a good reference to all the <a href="http://developer.android.com/reference/android/Manifest.permission.html" target="_blank">Available Permissions</a>. </p>
<p>Use Drawables and Styles in your layout from Day 1. Use RelativeLayout from Day 1 also and attributes such as &#8220;layout_alignRight&#8221;, &#8220;layout_alignTop&#8221; as necessary to get the achieved UI. Rather than set a bunch of things invisible/visible, use a Viewgroup such as a nested Relative Layout. Yes you can do Forms this way and if you have a lot of labels/fields to hide/show based on other fields this can be really useful. </p>
<p>Don&#8217;t forget you can define gradients and shapes in Drawables also. This saved me a bunch of time trying to create graphics. </p>
<p>In general wrap your root Layout in a ScrollView. This will ensure your screen is usable when you rotate the device. </p>
<p>To Launch a new screen that you need to get something back from (like a Modal dialog) use &#8220;StartActivityForResult&#8221;, otherwise just use &#8220;StartActivity&#8221;</p>
<p>Sample code to launch an Activity: </p>
<pre class="brush: java">
Intent i = new Intent(this, MyActivity.class);
startActivityForResult(i, SCREEN_A);
</pre>
<p>The constant SCREEN_A just helps you identify in the onActivityResult method which one returned. </p>
<pre class="brush: java">

public void onActivityResult(int requestCode, int resultCode, Intent intent) {
	super.onActivityResult(requestCode, resultCode, intent);
	if (resultCode == RESULT_OK) {
		Bundle extras = intent.getExtras();
		switch (requestCode) {
		case SCREEN_A: // do something with the return values
			break;
		}
	}
}
</pre>
<p>Remember your screen can be cancelled by the user using the Back button so only check the intent if the resultCode is &#8220;RESULT_OK&#8221;, otherwise you&#8217;ll get an exception. </p>
<p>Inside your child Activity do this to send data back to the parent:  </p>
<pre class="brush: java">

Intent myReturnIntent = new Intent();
Bundle myBundle = new Bundle();
myReturnIntent.putExtras(myBundle);
setResult(RESULT_OK, myReturnIntent);
finish();
</pre>
<p>Use Log.d(TAG, &#8220;Something&#8221;) combined with &#8220;ADB LOGCAT&#8221; to debug. Define a TAG constant in every class, it&#8217;ll help you filter the Log by defining an environment variable named &#8220;android_log_tags&#8221; with the relevant tags included. <a href="http://developer.android.com/guide/developing/tools/adb.html" target="_blank">http://developer.android.com/guide/developing/tools/adb.html</a></p>
<p>If you need to display a Message box, typically use a &#8220;Toast&#8221; message, here&#8217;s a good reference on Toast: <a href="http://developer.android.com/guide/topics/ui/notifiers/toasts.html" target="_blank">http://developer.android.com/guide/topics/ui/notifiers/toasts.html</a></p>
<p>If you need a dialog box, try this: </p>
<pre class="brush: java">

public static void ShowAlert(String text, String title, Context activity) {

	AlertDialog.Builder myBuilder = new AlertDialog.Builder(activity);
	myBuilder.setMessage(text).setCancelable(false)
		.setPositiveButton(&quot;Ok&quot;, new DialogInterface.OnClickListener() {
			public void onClick(DialogInterface dialog, int id) {
                                // just close
				dialog.cancel();
		        }
		});

	AlertDialog alert = myBuilder.create();
	alert.setIcon(R.drawable.myIcon);
	alert.setTitle(title);
	alert.show();
}
</pre>
<p>and you can add a &#8220;.setNegativeButton&#8221; if you need more control. </p>
<p>If you need to store simple string name-value pairs use preferences use the built in UI and Preference manager. Good tutorial is here: <a href="http://www.kaloer.com/android-preferences" target="_blank">http://www.kaloer.com/android-preferences</a>.</p>
<p>If you don&#8217;t want to use a Menu you can always use a TabView and I found Google&#8217;s example to be complete and easy to follow: <a href="http://developer.android.com/resources/tutorials/views/hello-tabwidget.html" target="_blank">http://developer.android.com/resources/tutorials/views/hello-tabwidget.html</a></p>
<p>For background, long running processing use a Service. Great simple complete example here:  <a href="http://marakana.com/forums/android/examples/60.html" target="_blank">http://marakana.com/forums/android/examples/60.html</a></p>
<p>That should be plenty to help you get your first android app up and running. </p>
]]></content:encoded>
			<wfw:commentRss>http://francisshanahan.com/index.php/2011/android-development-cheatsheet/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Evidence Based Architecture</title>
		<link>http://francisshanahan.com/index.php/2011/evidence-based-architecture/</link>
		<comments>http://francisshanahan.com/index.php/2011/evidence-based-architecture/#comments</comments>
		<pubDate>Thu, 17 Mar 2011 14:48:39 +0000</pubDate>
		<dc:creator>Francis</dc:creator>
				<category><![CDATA[Featured]]></category>
		<category><![CDATA[General Computing]]></category>
		<category><![CDATA[Headline]]></category>

		<guid isPermaLink="false">http://francisshanahan.com/?p=3059</guid>
		<description><![CDATA[I&#8217;m a big fan of cross-pollinating disciplines, taking two silos which rarely interact and swapping best practices. In the field of medicine before prescribing any treatment there has to be a quantitative benefit demonstrated which outweighs the risks associated to that treatment. In many cases this is black and white: You broke your arm? Let me fix it with a cast. In cases of long-term illness such as cancer the lines get blurred: You have 15 tumors in multiple locations? Yes I can arrest their growth with chemotherapy but I ...]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m a big fan of cross-pollinating disciplines, taking two silos which rarely interact and swapping best practices. In the field of medicine before prescribing any treatment there has to be a quantitative benefit demonstrated which outweighs the risks associated to that treatment. In many cases this is black and white: You broke your arm? Let me fix it with a cast. In cases of long-term illness such as cancer the lines get blurred: You have 15 tumors in multiple locations? Yes I can arrest their growth with chemotherapy but I cannot kill them entirely and your quality of life will be reduced ergo let me leave you alone. </p>
<p>So you can only prescribe a treatment if it can be shown to have a significant associated benefit which outweighs the impact that treatment will have on the patients&#8217; health. This is known as the Risk/Reward Ratio. </p>
<p>Reward must be proven, typically through Clinical Trials and typically more than one. Your results must be documented, peer reviewed, repeatable. In short you must follow the Scientific Method. </p>
<p>In technology there can be a tendency to ignore the &#8220;burden of proof&#8221; as it were and simply go with what sounds right. I admit I&#8217;m making a sweeping generalization here but it&#8217;s one I grapple with on a daily basis so I don&#8217;t feel too bad about it. </p>
<p>Example: Should a website implement caching? the natural reaction being &#8220;of course it should, everyone knows caching is a good thing&#8221;. Caching removes load from the database, speeds up requests by avoiding data access and generally makes the site run quicker. The right answer is &#8220;maybe, let&#8217;s look at the evidence&#8221;.</p>
<p>An evidence based approach to answering this question would ask the following questions: </p>
<ul>
<li>What&#8217;s the expected cache-seek time? Is it faster or slower than going directly to the database? Databases are pretty darn fast. Will I need to execute complex queries against my cache? What&#8217;s my cache key?
</li>
<li>How big will the cache grow? Am I caching per user? per client? per entitlement? Does caching sensitive data in the web tier impact my system&#8217;s security profile (yes)? How big can I <em>let</em> the cache grow? </li>
<li>What&#8217;s the mechanism for flushing the cache? How stale can the data get? </li>
<li>Will caching reduce functionality? Or will it flat-out break functionality by not reflecting changes right away? </li>
<li>
How will caching influence my test cycle? Testing becomes more complex now because I need to test w/cache populated, w/cache empty, w/cache service down, the number of destructive test cases just increased. </li>
<li>What&#8217;s the benefit? Am I shaving milliseconds off an already acceptable page-rendering time? Or is the page already breaking the SLA and I need to do something? </li>
<li>What is the cost of implementing caching? this includes writing the code, writing the test cases, maintaining the code, etc. </li>
</ul>
<p>Based on <em>evidence</em> we may very well find that caching is not a good idea, in spite of how attractive it sounds on the surface. </p>
<p>I see similar things in the security world: Should we implement one-way SSL with IP restriction between the app and web tier or should we use mutual SSL? Is one more secure than the other? On paper, yes, in practice depending on how you store the keys, who can access the box etc. maybe not. </p>
<p>Evidence Based Architecture supports the K.I.S.S. principle, basically Occams&#8217; Razor said a different way. </p>
<p>So let me be the first to coin the term &#8220;Evidence Based Architecture&#8221;. Perhaps we should make architects/engineers take the equivalent of the Hippocratic Oath. How different would your system look if the designer started each day with &#8220;I shall do no harm&#8221;. </p>
]]></content:encoded>
			<wfw:commentRss>http://francisshanahan.com/index.php/2011/evidence-based-architecture/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Fixing the ePub problem with Docbook-XSL/A2X/Asciidoc</title>
		<link>http://francisshanahan.com/index.php/2011/fixing-epub-problem-docbook-xsl-asciidoc-a2x/</link>
		<comments>http://francisshanahan.com/index.php/2011/fixing-epub-problem-docbook-xsl-asciidoc-a2x/#comments</comments>
		<pubDate>Tue, 01 Mar 2011 16:06:41 +0000</pubDate>
		<dc:creator>Francis</dc:creator>
				<category><![CDATA[Featured]]></category>
		<category><![CDATA[General Computing]]></category>
		<category><![CDATA[Headline]]></category>

		<guid isPermaLink="false">http://francisshanahan.com/?p=3045</guid>
		<description><![CDATA[If you are using AsciiDoc (and A2X) to convert documentation to ePub you'll probably have run into a problem where a2x runs xsltproc and fails trying to locate the ePub docbook xsl style sheet. 

This post shows you how to fix it.]]></description>
			<content:encoded><![CDATA[<p>If you are using AsciiDoc (and A2X) to convert documentation to ePub you&#8217;ll probably have run into a problem as follows: </p>
<p>In CygWin, to generate an epub file I use this command:<br />
<code>a2x -fepub myFile.txt --no-xmllint --verbose</code></p>
<p>This was giving me this error: </p>
<blockquote><p>>> warning: failed to load external entity<br />
>> &#8220;http://docbook.sourceforge.net/release/xsl/current/epub/docbook.xsl&#8221;;<br />
>> compilation error: file /etc/asciidoc/docbook-xsl/epub.xsl line 13<br />
>> element import<br />
>> xsl:import : unable to load<br />
>> http://docbook.sourceforge.net/release/xsl/current/epub/docbook.xsl
</p></blockquote>
<p>Note I am using Docbook-XSL 1.75.2. </p>
<p>The issue was reported on the Arch Linux distro recently here:<br />
<a href="https://bugs.archlinux.org/task/22746?project=1&#038;string=docbook-xsl">https://bugs.archlinux.org/task/22746?project=1&#038;string=docbook-xsl</a></p>
<p>and on Google Groups here: </p>
<p><a href="http://groups.google.com/group/asciidoc/browse_thread/thread/fdd5194c09bd4b87">http://groups.google.com/group/asciidoc/browse_thread/thread/fdd5194c09bd4b87</a></p>
<p>Typically there is a mapping from URIs in XML/XSL sheets to local versions of those files. Xslt-proc uses this to speed up processing by avoiding the download. The issue in this case is the mapping for ePub files did not exist (not sure why). </p>
<p><strong>The Fix</strong>: It turns out the fix is simple but took a while to figure out. I downloaded the latest DocBook-XSL version &#8211; (<a href="http://sourceforge.net/projects/docbook/files/docbook-xsl">http://sourceforge.net/projects/docbook/files/docbook-xsl</a>) and unzipped. This will contain a folder for ePub/docbook.xsl. </p>
<p>Next locate the mapping file, this is usually /etc/xml/catalog. </p>
<p>Inside it&#8217;ll have mappings from web-URIs to local-URIs. Something like this: </p>
<blockquote><p>&lt;rewriteURI uriStartString=&#8221;http://docbook.sourceforge.net/release/xsl/current&#8221; rewritePrefix=&#8221;/usr/share/xml/docbook/xsl-stylesheets-1.76.1/&#8221;/&gt;
</p></blockquote>
<p>You just need to ensure your ePub folder is included as a sub-folder off of this local path. Manually copy it from wherever you unzipped to the right spot (in my case /usr/share/xml/docbook/xsl-stylesheets-1.76.1/epub) and you&#8217;re done. </p>
<p>Now you can generate ePub format for all those non-Kindle book readers. </p>
]]></content:encoded>
			<wfw:commentRss>http://francisshanahan.com/index.php/2011/fixing-epub-problem-docbook-xsl-asciidoc-a2x/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>How To Theme Sencha Touch with SASS on Windows</title>
		<link>http://francisshanahan.com/index.php/2011/how-to-theme-sencha-touch-sass-windows/</link>
		<comments>http://francisshanahan.com/index.php/2011/how-to-theme-sencha-touch-sass-windows/#comments</comments>
		<pubDate>Fri, 14 Jan 2011 22:55:44 +0000</pubDate>
		<dc:creator>Francis</dc:creator>
				<category><![CDATA[Featured]]></category>
		<category><![CDATA[Headline]]></category>
		<category><![CDATA[Web Development]]></category>

		<guid isPermaLink="false">http://francisshanahan.com/?p=3030</guid>
		<description><![CDATA[A good architect stays current with technology to better enable their team&#8217;s productivity. One often overlooked area is that of CSS, there have been many improvements. In this post I record the steps taken to successfully setup SASS (Syntactically Awesome Style Sheets) with Sencha Touch on Windows.
If you&#8217;re building a website with a non-trivial CSS file (aren&#8217;t we all),  SASS  makes managing the CSS a lot simpler.
&#8220;Sass is a meta-language on top of CSS that’s used to describe the style of a document cleanly and structurally, with more power than ...]]></description>
			<content:encoded><![CDATA[<p>A good architect stays current with technology to better enable their team&#8217;s productivity. One often overlooked area is that of CSS, there have been many improvements. In this post I record the steps taken to successfully setup SASS (Syntactically Awesome Style Sheets) with Sencha Touch on Windows.</p>
<p>If you&#8217;re building a website with a non-trivial CSS file (aren&#8217;t we all),  SASS  makes managing the CSS a lot simpler.</p>
<blockquote><p>&#8220;Sass is a meta-language on top of CSS that’s used to describe the style of a document cleanly and structurally, with more power than flat CSS allows. Sass both provides a simpler, more elegant syntax for CSS and implements various features that are useful for creating manageable stylesheets.&#8221;</p></blockquote>
<p>Sencha Touch uses SASS to manage its stylesheets. I&#8217;ve been researching this in my evenings and weekends and am at the point where I want to change how Sencha Touch looks. It&#8217;s not as simple as you&#8217;d think. Essentially I need to create a new theme. Hence a little SASS is warranted. </p>
<p>Unfortunately both the instructions on the Sencha site [<a href="http://www.sencha.com/blog/2010/12/17/an-introduction-to-theming-sencha-touch/" target="_blank">LINK</a>] and the SASS site [<a href="http://sass-lang.com/docs.html" target="_blank">LINK</a>] are a little out of date and buggy. Here now are the steps I followed to get this working on windows:</p>
<ol>
<li>Start by installing Ruby &#8211; <a href="http://rubyforge.org">http://rubyforge.org</a> grab the latest rubyinstaller-1.9.2-p136.exe &#8211; nothing to it and you&#8217;ll end up with c:\ruby192 and some Start-Menu items.</li>
<li>This comes with Gems  so you can skips the gems install. There is one snag though with Ruby 1.9.2-p136 that the install sets up an incorrect folder &#8211; c:\ruby192\lib\ruby\site_ruby &#8211; remove this one (just rename it to be safe) and gems will work. Maybe they&#8217;ll fix this in the next release.</li>
<li>Install Compass: at a Ruby command prompt type &#8220;gem install compass&#8221;. If you&#8217;re behind a proxy I found this works: &#8220;gem install &#8211;http-proxy &lt;proxyAddress:Port&gt; compass&#8221;</li>
</ol>
<p>Next create a new folder in your Sencha folders. If your directories look like this</p>
<p>c:\myWebsite\js\sencha-touch-1.0.1\resources\css</p>
<p>c:\myWebsite\js\sencha-touch-1.0.1\resources\sass</p>
<p>You&#8217;ll want to create this one:</p>
<p>c:\myWebsite\js\sencha-touch-1.0.1\resources\SCSS</p>
<p>Inside that create two files as per the Sencha website:</p>
<p>Config.Rb (a ruby file)</p>
<pre class="brush: csharp">
# Delineate the directory for our SASS/SCSS files (this directory)
sass_path = File.dirname(__FILE__)

# Delineate the CSS directory (under resources/css in this demo)
css_path = File.join(sass_path, &quot;..&quot;, &quot;css&quot;)

# Delinate the images directory
images_dir = File.join(sass_path, &quot;..&quot;, &quot;img&quot;)

# Load the sencha-touch framework
load File.join(sass_path, &#039;..&#039;, &#039;..&#039;, &#039;..&#039;, &#039;..&#039;, &#039;resources&#039;, &#039;themes&#039;)

# Specify the output style/environment
output_style = :compressed
environment = :production
</pre>
<p>No changes are needed to config.rb</p>
<p>Next create Application.scss(The file extension is important here)</p>
<pre class="brush: csharp">
// 1. Variable overrides, example:
// $base-color: #af2584;

// 2. Include Sencha Touch styles
@import &#039;c:\myWebsite\js\sencha-touch-1.0.1\resources\themes\stylesheets\sencha-touch\default\all&#039;;
@include sencha-panel;
@include sencha-buttons;
@include sencha-sheet;
@include sencha-picker;
@include sencha-toolbar-forms;
@include sencha-tabs;
@include sencha-toolbar;
@include sencha-carousel;
@include sencha-indexbar;
@include sencha-list;
@include sencha-layout;
@include sencha-form;
@include sencha-loading-spinner;

// 3. Define custom styles (can use SASS/Compass), example:
// .mybox {
//     @include border-radius(4px);
// }
</pre>
<p>The @import line is important. I changed it to the location of the default theme in Sencha Touch with the &#8220;all&#8221; appended. </p>
<p>Lastly, run SASS using &#8220;compass compile&#8221;. You&#8217;ll end up with a new file names &#8220;application.css&#8221; located under</p>
<p>c:\myWebsite\js\sencha-touch-1.0.1\resources\css\application.css</p>
<p>Now reference that new CSS file in your Sencha website and you&#8217;re all set. Refer to Sencha&#8217;s site for tips on customizing the Theme itself [<a href="http://www.sencha.com/blog/2010/12/17/an-introduction-to-theming-sencha-touch/">http://www.sencha.com/blog/2010/12/17/an-introduction-to-theming-sencha-touch/</a>].</p>
<p>SASS on its own is a boon if you&#8217;re doing serious CSS work. If not it&#8217;s probably over kill. You can do things like define variables and have those determine your CSS based on functions, you can nest elements for easier maintenance and even remove whitespace and combine multiple CSS files into one automatically. </p>
<p>Definitely one for the toolbox. </p>
]]></content:encoded>
			<wfw:commentRss>http://francisshanahan.com/index.php/2011/how-to-theme-sencha-touch-sass-windows/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>RSS with SyndicationItem, Entity Framework and AutoMapper</title>
		<link>http://francisshanahan.com/index.php/2010/rss-syndicationitem-entity-framework-automapper/</link>
		<comments>http://francisshanahan.com/index.php/2010/rss-syndicationitem-entity-framework-automapper/#comments</comments>
		<pubDate>Fri, 31 Dec 2010 16:24:24 +0000</pubDate>
		<dc:creator>Francis</dc:creator>
				<category><![CDATA[Featured]]></category>
		<category><![CDATA[General Computing]]></category>
		<category><![CDATA[Headline]]></category>
		<category><![CDATA[Web Development]]></category>

		<guid isPermaLink="false">http://francisshanahan.com/?p=2999</guid>
		<description><![CDATA[The otherwise excellent Kindle 3 doesn&#8217;t natively let you subscribe to RSS feeds. To me this is a major failing but we can write a simple service to aggregate feeds into an HTML file. If you email this file to @free.amazon.com Amazon will convert (for free) into an AZW file and deliver to your Kindle. Presto, free feed aggregation.  This is essentially what http://kindlefeeder.com does and I recommend this service if you don&#8217;t feel like writing your own. 
Since switching to WordPress I hadn&#8217;t looked at RSS in a ...]]></description>
			<content:encoded><![CDATA[<p>The otherwise excellent Kindle 3 doesn&#8217;t natively let you subscribe to RSS feeds. To me this is a major failing but we can write a simple service to aggregate feeds into an HTML file. If you email this file to <username>@free.amazon.com Amazon will convert (for free) into an AZW file and deliver to your Kindle. Presto, free feed aggregation.  This is essentially what <a href="http://kindlefeeder.com">http://kindlefeeder.com</a> does and I recommend this service if you don&#8217;t feel like writing your own. </p>
<p>Since switching to WordPress I hadn&#8217;t looked at RSS in a while. It&#8217;s not as Simple as it used to be. This was also a good opportunity to try the Entity Framework [<a href="http://msdn.microsoft.com/en-us/library/aa697427(v=vs.80).aspx">LINK</a>] with Automapper (<a href="http://automapper.codeplex.com/">http://automapper.codeplex.com/</a>). I created a simple EDMX file to store the feeds (draft below). </p>
<p><img src="http://francisshanahan.com/wp-content/uploads/2010/12/feedEdmx.png" alt="Simple Edmx to store Feeds" /></p>
<p>Then to read the feed I used System.ServiceModel.Syndication objects. Initially I used Argotic and NuGet (http://nuget.codeplex.com/) made this a snap to setup. (if you haven&#8217;t tried NuGet I highly recommend it). Argotic turned out to be overkill so I reverted to the native .NET classes within System.ServiceModel.Syndication.</p>
<pre class="brush: csharp">

// Load feed
SyndicationFeed  feed = SyndicationFeed.Load(XmlReader.Create(url));
</pre>
<p>You can augment your Entity Framework classes with partial classes and DataAnnotations like so: </p>
<pre class="brush: csharp">

 [MetadataType(typeof(FeedMetadata))]
    public partial class Feed
    {
        public Feed()
        {
            this.Created = System.DateTime.Now;
        }
    }
</pre>
<p>Then specify the DataAnnotations Metadata in the associated class: </p>
<pre class="brush: csharp">

public class FeedMetadata
    {
        [Display(Name=&quot;Feed (RSS) Url&quot;, Prompt=&quot;Enter a URL&quot;), DataType(DataType.Url, ErrorMessage = &quot;Invalid URL (try including the http://)&quot;), Required(ErrorMessage = &quot;Url is a required field&quot;),
        RegularExpression(&quot;^(http)\\://[a-zA-Z0-9\\-\\.]+\\.[a-zA-Z]{2,3}(:[a-zA-Z0-9]*)?/?([a-zA-Z0-9\\-\\._\\?\\,\\&#039;/\\\\\\+&amp;amp;amp;amp;amp;amp;amp;%\\$#\\=~])*$&quot;, ErrorMessage = &quot;Must be in the form &#039;http://&#039; and be a valid URL&quot;)]     

        public string Url { get; set; }

    }
</pre>
<p>So now we get to the meat of the post. Once the feed was loaded I needed to map to the SyndicationFeed object my Entity Framework Feed object and it made sense to use AutoMapper for this purpose. AutoMapper is very smart and can almost intuitively map your objects based on property name. </p>
<p>The feed items are loaded into SyndicationItem objects which have a Content property. Unfortunately in RSS2.0 there&#8217;s no such property. Here&#8217;s what the XML looks like: </p>
<pre class="brush: xml">
&lt;item&gt;
....
&lt;description&gt;&lt;![CDATA[Summary content...]]&gt;&lt;/description&gt;
&lt;content:encoded&gt;&lt;![CDATA[&lt;p&gt; Actual content here &lt;/p&gt;]]&lt;/content:encoded&gt;
...
&lt;/item&gt;
</pre>
<p>Notice the Content is actually an RSS extension, within the namespace of &#8220;http://purl.org/rss/1.0/modules/content&#8221;, so how to map this using Automapper?<br />
To access the extensions use the &#8220;ReadElementExtensions&#8221; generic on the ElementExtensions collection. Once I figured that out I could build the map like this: </p>
<pre class="brush: csharp">

Mapper.CreateMap&lt;SyndicationItem, Item&gt;()
   .ForMember(dest =&gt; dest.Content,
      opt =&gt; opt.MapFrom(
         src =&gt; src.ElementExtensions
            .ReadElementExtensions&lt;string&gt;(&quot;encoded&quot;, &quot;http://purl.org/rss/1.0/modules/content/&quot;).FirstOrDefault()));
                    Mapper.CreateMap&lt;SyndicationFeed, Feed&gt;();

Mapper.Map(sourceFeed, dbFeed);
</pre>
<p>So this is pretty clean, Entity Framework combined with AutoMapper and native .NET 4.0 Syndication Assemblies. </p>
<p>I tried Googling and looks like a number of folks have trouble even accessing the <strong>content:encoded</strong> element of the RSS so hopefully this post will help those folks as well as folks looking to setup a slightly complex map in AutoMapper. </p>
<p>Happy New Year!</p>
<p>* Bug picture from John Hallmen at <a href="http://www.morfa.se/">http://www.morfa.se/</a></p>
]]></content:encoded>
			<wfw:commentRss>http://francisshanahan.com/index.php/2010/rss-syndicationitem-entity-framework-automapper/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

