<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss 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/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>Carbon Silk</title>
	
	<link>http://www.carbonsilk.com</link>
	<description>Developing Ideas by James Broad</description>
	<lastBuildDate>Tue, 08 Jan 2013 00:00:38 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.2</generator>
		<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/carbonsilk" /><feedburner:info uri="carbonsilk" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><feedburner:feedFlare href="http://add.my.yahoo.com/rss?url=http%3A%2F%2Ffeeds.feedburner.com%2Fcarbonsilk" src="http://us.i1.yimg.com/us.yimg.com/i/us/my/addtomyyahoo4.gif">Subscribe with My Yahoo!</feedburner:feedFlare><feedburner:feedFlare href="http://www.newsgator.com/ngs/subscriber/subext.aspx?url=http%3A%2F%2Ffeeds.feedburner.com%2Fcarbonsilk" src="http://www.newsgator.com/images/ngsub1.gif">Subscribe with NewsGator</feedburner:feedFlare><feedburner:feedFlare href="http://feeds.my.aol.com/add.jsp?url=http%3A%2F%2Ffeeds.feedburner.com%2Fcarbonsilk" src="http://o.aolcdn.com/favorites.my.aol.com/webmaster/ffclient/webroot/locale/en-US/images/myAOLButtonSmall.gif">Subscribe with My AOL</feedburner:feedFlare><feedburner:feedFlare href="http://www.bloglines.com/sub/http://feeds.feedburner.com/carbonsilk" src="http://www.bloglines.com/images/sub_modern11.gif">Subscribe with Bloglines</feedburner:feedFlare><feedburner:feedFlare href="http://www.netvibes.com/subscribe.php?url=http%3A%2F%2Ffeeds.feedburner.com%2Fcarbonsilk" src="http://www.netvibes.com/img/add2netvibes.gif">Subscribe with Netvibes</feedburner:feedFlare><feedburner:feedFlare href="http://fusion.google.com/add?feedurl=http%3A%2F%2Ffeeds.feedburner.com%2Fcarbonsilk" src="http://buttons.googlesyndication.com/fusion/add.gif">Subscribe with Google</feedburner:feedFlare><feedburner:feedFlare href="http://www.pageflakes.com/subscribe.aspx?url=http%3A%2F%2Ffeeds.feedburner.com%2Fcarbonsilk" src="http://www.pageflakes.com/ImageFile.ashx?instanceId=Static_4&amp;fileName=ATP_blu_91x17.gif">Subscribe with Pageflakes</feedburner:feedFlare><item>
		<title>Recently launched – Met.nu</title>
		<link>http://feedproxy.google.com/~r/carbonsilk/~3/bd5aremDwtk/</link>
		<comments>http://www.carbonsilk.com/development/met-nu/#comments</comments>
		<pubDate>Sat, 05 Jan 2013 21:38:06 +0000</pubDate>
		<dc:creator>James Broad</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[networking]]></category>
		<category><![CDATA[social]]></category>
		<category><![CDATA[startup]]></category>
		<category><![CDATA[twitter]]></category>

		<guid isPermaLink="false">http://www.carbonsilk.com/?p=23539</guid>
		<description><![CDATA[The Short Version I made a service to attach information about Twitter users, Install the Met.nu Chrome extension. The Longer Version Every wonder why you follow someone on Twitter? Twitter is a great way to have light connections with people, but in it&#8217;s simplicity, it&#8217;s easy to loose track of how you know the people [...]]]></description>
			<content:encoded><![CDATA[<p><iframe src="http://player.vimeo.com/video/56948016" width="500" height="313" frameborder="0" webkitAllowFullScreen mozallowfullscreen allowFullScreen></iframe></p>
<h3>The Short Version</h3>
<p>I made a service to attach information about Twitter users, <a href="http://bit.ly/met-chrome">Install the Met.nu Chrome extension</a>.</p>
<h3>The Longer Version</h3>
<p>Every wonder why you follow someone on Twitter?</p>
<p>Twitter is a great way to have light connections with people, but in it&#8217;s simplicity, it&#8217;s easy to loose track of how you know the people you follow.</p>
<p>I wanted a way of attaching additional information to Twitter users to allow me to better understand the people I follow, and, more specifically, why I follow them. I looked around to find a tool/service to facilitate this desire but sadly I couldn&#8217;t find anything. That&#8217;s when the idea for <a href="http://met.nu">Met</a> was hatched.</p>
<p><a href="http://met.nu">Met</a> is a web service that uses browser extensions, currently Chrome, to overlay information about users, designed to fit into your everyday flow.</p>
<p>Here are some of the views where you can see and attach Met information:</p>
<h4>User Profile</h4>
<p>View and add annotations in the popup or full page profile.</p>
<p><img src="http://www.carbonsilk.com/wp-content/uploads/2013/01/profile2.png" alt="" title="profile" width="536" height="582" class="alignnone size-full wp-image-23574" /></p>
<h4>Tweet Stream</h4>
<p>Hovering over a tweet provides you with a Met button to view and create annotations.</p>
<p><img src="http://www.carbonsilk.com/wp-content/uploads/2013/01/stream1.png" alt="" title="stream" width="536" height="582" class="alignnone size-full wp-image-23561" /></p>
<h4>Following List</h4>
<p>Clearly see users that have been annotated which will appear red, un-annotated users buttons will appear gray.</p>
<p><img src="http://www.carbonsilk.com/wp-content/uploads/2013/01/following1.png" alt="" title="following" width="536" height="582" class="alignnone size-full wp-image-23559" /></p>
<p>The future for Met is looking exciting! There are plans to provide a search &#038; browse interface, private &#038; public notes and additional aggregated information about users when you click on the Met buttons. Follow the <a href="http://twitter.com/hellomet">Met Twitter feed</a> for feature announcements and service updates.</p>
<p>Why not give the Chrome extension a go now? <a href="http://bit.ly/met-chrome">Install the Met.nu Chrome extension</a>.</p>
<iframe src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fwww.carbonsilk.com%2Fdevelopment%2Fmet-nu%2F&amp;layout=standard&amp;show_faces=true&amp;width=450&amp;action=like&amp;colorscheme=light" scrolling="no" frameborder="0" allowTransparency="true" style="border:none; overflow:hidden; width:450px;height:30px;margin-top:5px;"></iframe>]]></content:encoded>
			<wfw:commentRss>http://www.carbonsilk.com/development/met-nu/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.carbonsilk.com/development/met-nu/</feedburner:origLink></item>
		<item>
		<title>What are you working on?</title>
		<link>http://feedproxy.google.com/~r/carbonsilk/~3/fTs4dagv8LM/</link>
		<comments>http://www.carbonsilk.com/development/workdon/#comments</comments>
		<pubDate>Sat, 03 Nov 2012 15:39:03 +0000</pubDate>
		<dc:creator>James Broad</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[architecture]]></category>
		<category><![CDATA[frameworks]]></category>
		<category><![CDATA[Node]]></category>
		<category><![CDATA[Productivity]]></category>
		<category><![CDATA[release]]></category>
		<category><![CDATA[shipping]]></category>
		<category><![CDATA[workdon]]></category>

		<guid isPermaLink="false">http://www.carbonsilk.com/?p=23479</guid>
		<description><![CDATA[Solving a problem Earlier this year (May 2012), I embarked on building a site to allow myself and others to document what they are shipping and getting done. At the time I was working at the BBC on their Weather website and we were releasing so many things I was proud of that I wanted [...]]]></description>
			<content:encoded><![CDATA[<p><img src="https://img.skitch.com/20120627-bhwi4w18efd7eh6i797c9kfbhx.jpg" alt="Workdon Screenshot" style="width:100%" /></p>
<h3>Solving a problem</h3>
<p>Earlier this year (May 2012), I embarked on building a site to allow myself and others to document what they are shipping and getting done. At the time I was working at the <a href="http://bbc.co.uk">BBC</a> on their <a href="http://bbc.co.uk/weather">Weather</a> website and we were releasing so many things I was proud of that I wanted a way to capture and present them.</p>
<p>I felt <a href="http://dribbble.com">Dribbble</a> &amp; <a href="http://github.com">Github</a> were great tools for design and code, but that there was a void of documenting the top level progress made on projects.</p>
<p><a href="http://workdon.com">Workdon.com</a> stands to make the work you do look great for future work leads. Workdon also serves as an <a href="http://blog.idonethis.com/post/28555575176/the-power-of-the-done-list">anti-todo list</a>, realise your productivity, not remind you of your task debt.</p>
<p>I have thus far been working hard to ensure a smooth operation of reading, posting and updating updates. The next phases of development will bring exciting automatic updating of your projects from services like Dribble and Github to keep your portfolio looking fresh without having to lift a finger.</p>
<h3>Looking good!</h3>
<p>Once you have signed up for an account, you have access to a personalised standalone portfolio site. An example of this can be found at <a href="http://kulor.workdon.com">kulor.workdon.com</a>. This portfolio site is theme powered and may have the option to upload your own design (<a href="http://handlebarsjs.com/">Handlebars</a> templates) or choose from some predefined designs.</p>
<p>Social networking has been added as a complementary feature where you can track other Workdon user&#8217;s updates. This is useful for finding out what people are working on. An application this could work well would be to serve as an agile standup alternative.</p>
<p>I&#8217;d love to hear your thoughts of Workdon so please add a  comment or get in touch directly at <a href="mailto:james@workdon.com">james@workdon.com</a>.</p>
<iframe src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fwww.carbonsilk.com%2Fdevelopment%2Fworkdon%2F&amp;layout=standard&amp;show_faces=true&amp;width=450&amp;action=like&amp;colorscheme=light" scrolling="no" frameborder="0" allowTransparency="true" style="border:none; overflow:hidden; width:450px;height:30px;margin-top:5px;"></iframe>]]></content:encoded>
			<wfw:commentRss>http://www.carbonsilk.com/development/workdon/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.carbonsilk.com/development/workdon/</feedburner:origLink></item>
		<item>
		<title>Convert vector images to web font icons</title>
		<link>http://feedproxy.google.com/~r/carbonsilk/~3/GEtYx7rq4bQ/</link>
		<comments>http://www.carbonsilk.com/development/convert-images-to-web-font-icons/#comments</comments>
		<pubDate>Sun, 16 Sep 2012 09:58:27 +0000</pubDate>
		<dc:creator>James Broad</dc:creator>
				<category><![CDATA[Design]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[convert]]></category>
		<category><![CDATA[font]]></category>
		<category><![CDATA[fonts]]></category>
		<category><![CDATA[icons]]></category>
		<category><![CDATA[svg]]></category>
		<category><![CDATA[webfonts]]></category>

		<guid isPermaLink="false">http://www.carbonsilk.com/?p=23153</guid>
		<description><![CDATA[@font-face { font-family: 'icomoon'; src:url('/fonts/icomoon.eot'); src:url('/fonts/icomoon.eot?#iefix') format('embedded-opentype'), url('/fonts/icomoon.svg#icomoon') format('svg'), url('/fonts/icomoon.woff') format('woff'), url('/fonts/icomoon.ttf') format('truetype'); font-weight: normal; font-style: normal; } .icon:before{ content:"\21"; font-family: 'icomoon'; font-style: normal; speak: none; font-weight: normal; font-size: 300px; line-height: 1; -webkit-font-smoothing: antialiased; } .icon-container{ text-align: center; } Using fonts for icons are great for allowing you to: Cater to all screen densities including [...]]]></description>
			<content:encoded><![CDATA[<style>
@font-face {
	font-family: 'icomoon';
	src:url('/fonts/icomoon.eot');
	src:url('/fonts/icomoon.eot?#iefix') format('embedded-opentype'),
		url('/fonts/icomoon.svg#icomoon') format('svg'),
		url('/fonts/icomoon.woff') format('woff'),
		url('/fonts/icomoon.ttf') format('truetype');
	font-weight: normal;
	font-style: normal;
}
.icon:before{
        content:"\21";
        font-family: 'icomoon';
	font-style: normal;
	speak: none;
	font-weight: normal;
        font-size: 300px;
        line-height: 1;
	-webkit-font-smoothing: antialiased;
}
.icon-container{
     text-align: center;
}
</style>
<p class="icon-container">
    <a href="http://thenounproject.com/noun/share/#icon-No2146"><span class="icon" aria-hidden="true"></span></a>
</p>
<p>Using fonts for icons are great for allowing you to:</p>
<ul>
<li>Cater to all screen densities including <a href="http://en.wikipedia.org/wiki/Retina_Display">Retina displays</a></li>
<li>Bundle a set of icons together in one font to save space and in turn <a href="http://developer.yahoo.com/performance/rules.html#num_http">reduce HTTP requests</a></li>
<li>Allows you to change the icon colour on the fly</li>
</ul>
<p>Icons can be layered if you require multiple colours in your graphic and the general method would be to absolute position individual glyphs inside a wrapper. Take a look at <a href="http://bbc-news-prototypes.heroku.com/weather-icons/index.html">Dan Scotton&#8217;s BBC Weather Icons</a> to see how it can be done.</p>
<p>I discovered <a href="http://icomoon.io">icomoon.io</a> which lets you import your own graphics and will create all the various font files required to support IE (6+), iOS Devices, Android, Chrome, Firefox, Opera, Safari and others. IcoMoon requires an SVG file format (or font file) for import but this is where I came unstuck as Adobe Fireworks (Mac CS5) doesn&#8217;t offer a native SVG export option and that is where my vector images were stored. Luckily with a quick google around I discovered and downloaded an <a href="http://fireworks.abeall.com/extensions/commands/Export/">SVG exporter plugin</a> for Fireworks. The command to export is in an unfamiliar menu (Commands > Export > Export SVG) in case, like me, you can&#8217;t find it at first.</p>
<p>To get going, head to <a href="http://icomoon.io/app/">http://icomoon.io/app/</a> and use the &#8220;Import Icons&#8221; feature.</p>
<p>Once you have downloaded and extracted your assets, you will notice handy index.html included which is a really good point of reference to see how to go about implementing the font as an icon. I thought I&#8217;d summarise the basic method employed to implement your new font icons with inline comments:</p>
<pre name="code" class="html">
&lt;style&gt;
/* This registers your new custom font (feel free to change the name to something of your own naming) */
@font-face {
    font-family: 'icomoon';
    src:url('fonts/icomoon.eot');
    src:url('fonts/icomoon.eot?#iefix') format('embedded-opentype'),
        url('fonts/icomoon.svg#icomoon') format('svg'),
        url('fonts/icomoon.woff') format('woff'),
        url('fonts/icomoon.ttf') format('truetype');
    font-weight: normal;
    font-style: normal;
}

/* Using the before prepends a 'fake' element to your target element */
.icon:before{
    content: "\22"; /* Your unicode character (icomoon provides this) */
    font-family: 'icomoon'; /* Reference your custom font */
    speak: none; /* Ensure screenreaders skip over what is essentially garbage to them. */
    -webkit-font-smoothing: antialiased; /* Force antialiasing */
    font-style: normal;
    font-weight: normal;
}
&lt;/style&gt;
<span class="icon"> Your Icon Text</span>
</pre>
<p>With all this newfound awesomeness, sites that offer SVG downloads like <a href="http://thenounproject.com/">thenounproject.com</a> (where I went to to get the icon for this post) means you can have an elegant way of implementing icons on your sites.</p>
<iframe src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fwww.carbonsilk.com%2Fdevelopment%2Fconvert-images-to-web-font-icons%2F&amp;layout=standard&amp;show_faces=true&amp;width=450&amp;action=like&amp;colorscheme=light" scrolling="no" frameborder="0" allowTransparency="true" style="border:none; overflow:hidden; width:450px;height:30px;margin-top:5px;"></iframe>]]></content:encoded>
			<wfw:commentRss>http://www.carbonsilk.com/development/convert-images-to-web-font-icons/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		<feedburner:origLink>http://www.carbonsilk.com/development/convert-images-to-web-font-icons/</feedburner:origLink></item>
		<item>
		<title>Automated deployment of node.js apps</title>
		<link>http://feedproxy.google.com/~r/carbonsilk/~3/WWkdcFlmaJY/</link>
		<comments>http://www.carbonsilk.com/node/deploying-nodejs-apps/#comments</comments>
		<pubDate>Sun, 20 Mar 2011 00:28:11 +0000</pubDate>
		<dc:creator>James Broad</dc:creator>
				<category><![CDATA[node]]></category>
		<category><![CDATA[ci]]></category>
		<category><![CDATA[continuous integration]]></category>
		<category><![CDATA[express]]></category>
		<category><![CDATA[git]]></category>
		<category><![CDATA[Jenkins]]></category>
		<category><![CDATA[JS]]></category>
		<category><![CDATA[Make]]></category>
		<category><![CDATA[Node]]></category>
		<category><![CDATA[npm]]></category>
		<category><![CDATA[Ubuntu]]></category>
		<category><![CDATA[upstart]]></category>

		<guid isPermaLink="false">http://www.carbonsilk.com/?p=9919</guid>
		<description><![CDATA[This article has a simple aim to improve the process of developing and deploying node.js web applications. The Continuous Integration folks will refer to what I am covering as an aptly named Automated Deployment. As you explore this guide you will learn: How to run a node.js script using Upstart. How to manage Jenkins (was [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://farm5.static.flickr.com/4038/4302501803_957d51a01a.jpg" alt="Delivering the goods" /></p>
<p class="clear">This article has a simple aim to improve the process of developing and deploying <a href="http://nodejs.org/">node.js</a> web applications. The Continuous Integration folks will refer to what I am covering as an aptly named <a href="http://en.wikipedia.org/wiki/Continuous_integration#Automate_deployment">Automated Deployment</a>. As you explore this guide you will learn:</p>
<ul>
<li>How to run a node.js script using Upstart.</li>
<li>How to manage Jenkins (was Hudson) with Git.</li>
<li>How to make and use Makefiles.</li>
</ul>
<p>Lets crack on&#8230;</p>
<p>I have detailed an environment scheme below which works well for me. You are free to assign your machine names what you please but following this guide will be easiest if you follow my conventions.</p>
<table>
<thead>
<tr>
<th>Hostname</th>
<th>Description</th>
<th>Operating System</th>
</tr>
</thead>
<tr>
<td><em class="localhost">localhost</em></td>
<td>Your machine you develop from</td>
<td>Mac / Windows / Linux</td>
</tr>
<tr class="odd">
<td><em class="ci-app">ci.app</em></td>
<td>Jenkins and Git Server</td>
<td>Ubuntu</td>
</tr>
<tr>
<td><em class="int-app">int.app</em></td>
<td>node.js application server</td>
<td>Ubuntu</td>
</tr>
</table>
<h3>Getting a working node.js app and environment</h3>
<p>You will need to have an environment to run your app in. To save on resources I prefer using virtual machines hosted on my <em class="localhost">localhost</em>. This also means you are not tied to a network in order to develop (great for coding on the train/in a coffee shop).</p>
<p>You can run node.js apps on your <em class="localhost">localhost</em> but for this article we are just focusing the deployment process to an integration server (<em class="int-app">int.app</em>).</p>
<p>The correct development flow for a node.js app should be that you test on <em class="localhost">localhost</em>, then checkin when you are happy with your changes. The checkin will then trigger a build and automatically get built to <em class="int-app">int.app</em>. We will be in this sweet spot by the end of this article.</p>
<h4>Setting up your virtual machines</h4>
<p>It is fairly straightforward (and free) to get a Linux virtual machine up and running these days. Following the steps on <a href="https://help.ubuntu.com/community/VirtualBox">https://help.ubuntu.com/community/VirtualBox</a> should be a good starting point.<br />
I suggest you set up one machine (<em class="int-app">int.app</em>) first with a barebones configuration and clone it to create <em class="ci-app">ci.app</em>, changing the hostname (<code>sudo hostname newhostname</code>) and getting a new IP address <code>sudo dhclient</code> on the cloned machine.</p>
<h4>Configuring <em class="int-app">int.app</em></h4>
<p>Our initial development centric dependencies are <a href="http://git-scm.com/">Git</a>, <a href="http://nodejs.org/">node.js</a>, <a href="http://expressjs.com/">Express</a> and <a href="http://npmjs.org/">NPM</a>.</p>
<p>Login to <em class="int-app">int.app</em></p>
<pre>
ssh int.app
</pre>
<p>Install Git</p>
<pre>
apt-get install git git-core
</pre>
<p>Install node.js</p>
<pre>
cd /tmp/
git clone https://github.com/joyent/node.git
cd node
./configure
make
make install
</pre>
<p>Install NPM</p>
<pre>
apt-get install curl
curl http://npmjs.org/install.sh | sudo sh
</pre>
<p>Install Express</p>
<pre>
npm install express
</pre>
<p>Now you have everything you need to get a node.js app up and running. Let&#8217;s create our demo app.</p>
<pre>
mkdir -p /data/apps/hello_world
</pre>
<p>Add these contents to <code>/data/apps/hello_world/app.js</code>.</p>
<pre>
var express = require('express')
  , app = express.createServer()

app.get('/', function(req, res){
  res.send([
      '&lt;h1&gt;Hello World&lt;/h1&gt;'
  ].join('\n'));
});

app.listen(3000);
console.log('Express app started on port 3000');
</pre>
<h4>Run your node.js app</h4>
<pre>
node /data/apps/hello_world/app.js
</pre>
<h4>Getting and using the IP address of <em class="int-app">int.app</em></h4>
<p>SSH into <em class="int-app">int.app</em> and run:</p>
<pre>
ifconfig -a
</pre>
<ol>
<li>Grab the IP address from &#8216;inet addr&#8217;. This should look something like: <code>192.188.0.23</code>.</li>
<li>Add this to your <code>/etc/hosts</code> file on your <em class="localhost">localhost</em> like: <code>192.188.0.23 int.app</code></li>
</ol>
<h4>Testing the app</h4>
<p>Now let&#8217;s test if everything is running ok. Open up <a href="http://int.app:3000/">http://int.app:3000/</a>. With any luck you should be seeing the text &#8220;Hello World&#8221;.</p>
<h3>Getting a build process working</h3>
<p>We will be using Git as our source control management tool (<a href="http://en.wikipedia.org/wiki/Source_Code_Management">VCS</a>). Have a read of Joel Spolsky&#8217;s <a href="http://www.joelonsoftware.com/items/2010/03/17.html">distributed VCS post</a> to understand why we are using Git over something like <a href="http://subversion.tigris.org/"><abbr title="Subversion">SVN</abbr></a>.</p>
<h4>Setting up a Git server on <em class="ci-app">ci.app</em></h4>
<p>Git works in a de-centralised way but we need to have a central Git repository that we and other developers can push their changes to and other tools like Jenkins can pull updates from.</p>
<p>On <em class="ci-app">ci.app</em> run:</p>
<pre>
useradd git
su git
sudo mkdir -p /data/git/hello_world.git
sudo chown git -R /data/git/hello_world.git
cd /data/git/hello_world.git
git --bare init
curl http://utsl.gen.nz/git/post-update > /data/git/hello_world.git/hooks/post-update
exit
</pre>
<p>On <em class="localhost">localhost</em> you can now run:</p>
<pre>
git clone ssh://ci.app/data/git/hello_world.git ~/hello_world
cd hello_world
git remote add origin ssh://git@ci.app/data/git/hello_world.git
</pre>
<p>Now you have an empty directory on your local machine where you can develop from. Let&#8217;s add <code>app.js</code> we made earlier to this repository.</p>
<p>Add these contents to <code> ~/hello_world/app.js</code></p>
<pre>
var express = require('express')
  , app = express.createServer()

app.get('/', function(req, res){
  res.send([
      '&lt;h1&gt;Hello World&lt;/h1&gt;'
  ].join('\n'));
});

app.listen(3000);
console.log('Express app started on port 3000');
</pre>
<p>Now lets check it in.</p>
<pre>
git add --all
git commit -m 'Initial checkin' app.js
</pre>
<p>Let&#8217;s push it to our remote Git server</p>
<pre>
git push origin master
</pre>
<h4>Moving the app automatically</h4>
<p>We are going to use <a href="http://www.gnu.org/software/make/">make</a> as a tool to bundle commands. We will use Make to move the application from the Git repository to the <code>/data/apps/hello_world</code> directory.</p>
<p>On <em class="localhost">localhost</em>, add these contents to <code>~/hello_world/Makefile</code></p>
<pre>
install :
	sudo mkdir -p /data/apps/hello_world
	sudo cp ./app.js /data/apps/hello_world/
</pre>
<p>Check this file in and push changes:</p>
<pre>
git add --all
git commit -m 'adding build steps'
git push origin master
</pre>
<p>Now you could run this command and have the app put in the correct location for you:</p>
<pre>
make install
</pre>
<h3>Automating the build</h3>
<p>Jenkins is a very useful tool in the process of <a href="http://en.wikipedia.org/wiki/Continuous_integration">Continuous Integration</a>. At the most basic level Jenkins is a tool to allow you to schedule things to happen based on timings or events such as a code checkin.</p>
<h4>Installing Jenkins</h4>
<p>Let&#8217;s install Jenkins on <em class="ci-app">ci.app</em>.</p>
<pre>
apt-get install jenkins
</pre>
<p>Once installed you should be able to load Jenkins in your browser: at <a href="http://ci.app:8080/">http://ci.app:8080/</a>.</p>
<h4>Adding a new job to Jenkins</h4>
<p>Here you can add a &#8216;job&#8217; by:</p>
<ol>
<li>Selecting &#8216;<a href="http://ci.app:8080/view/All/newJob">New Job</a>&#8216;.</li>
<li>Call the Job name &#8220;Hello World&#8221;.</li>
<li>Select the option &#8216;Build a free-style software project&#8217;.</li>
<li>Save</li>
</ol>
<p>Once created you will be met with a page with a bunch of inputs. We will come back to that in a moment but first we need to add Git support to Jenkins. </p>
<h4>Adding Git support to Jenkins</h4>
<ol>
<li>Go to <a href="http://ci.app:8080/pluginManager/available">http://ci.app:8080/pluginManager/available</a>.</li>
<li>Click on the enable Git Plugin checkbox.</li>
<li>Click install at the bottom of the page.</li>
<li>Return back to your job configuration page (<a href="http://ci.app:8080/job/Hello%20World/configure">http://ci.app:8080/job/Hello World/configure</a>)</li>
<li>Select the Git option under the Source Code Management section.</li>
<li>Add this url into the url field: <code>ssh://git@localhost/data/git/hello_world.git</code></li>
<li>Select the Poll SCM checkbox under Build Triggers and enter: <code>* * * * *</code> (This will make Jenkins check every minute for changes to source files.)</li>
<li>Save the configuration</li>
<li>Click &#8216;build now&#8217; to check everything is working ok.</li>
</ol>
<p>As it stands, the Jenkins job is not being all that useful but we will discover it&#8217;s power later on.</p>
<h3>Deploying your app using Upstart</h3>
<p>Node.js scripts need to be run as daemons for hosting websites, which can make the deployment process a bit fiddly. We can use tools like <a href="http://upstart.ubuntu.com/">Upstart</a> to run and manage node.js scripts.</p>
<h4>Install Upstart</h4>
<pre>
apt-get install upstart
</pre>
<h4>Adding Upstart app configuration</h4>
<p>On <em class="localhost">localhost</em>, add these contents to <code>~/hello_world/hello_world.conf</code></p>
<pre>
#!upstart
description "node.js hello world app server"
author      "James Broad"

start on startup
stop on shutdown

script
    export HOME="/root"

    exec /usr/local/bin/node /data/apps/hello_world/app.js 2>&#038;1 >> /var/log/node.log
end script
</pre>
<p>We will be putting this file into <code>/etc/event.d/hello_world</code> on <em class="int-app">int.app</em> later on. Once in that location you can run <code>sudo start hello_world</code></p>
<h3>Continuously deploying your app</h3>
<p>Now that Jenkins is set up to keep an eye on our files, we can issue it some commands to deploy and run the app.js application.</p>
<p>Let&#8217;s return to <em class="localhost">localhost</em> and add a deployment step to Makefile. This will copy the files needed to install and run our application.<br />
Add these contents to <code>~/hello_world/Makefile</code></p>
<pre>
app_dir = /data/apps/hello_world
temp_install_dir = /tmp/hello_world
deployment_hostname = int.app

install :
	sudo mkdir -p $(app_dir)
	sudo cp ./app.js $(app_dir)/app.js
	sudo cp ./hello_world.conf /etc/event.d/hello_world

deploy :
	# Get rid of old temp installs
	ssh $(deployment_hostname) sudo rm -rf $(temp_install_dir)
	# Copy files over to remote machine
	rsync -r . $(deployment_hostname):$(temp_install_dir)
	# Install our app to the right location
	ssh $(deployment_hostname) cd $(temp_install_dir)\; make install
	ssh $(deployment_hostname) cd $(temp_install_dir)\; make start_app

start_app :
	sudo start  --no-wait -q hello_world
</pre>
<p>Check in and push your changes.</p>
<pre>
git add --all
git commit -m 'adding deployment steps'
git push origin master
</pre>
<h4>Handling environment permissions</h4>
<p>On <em class="int-app">int.app</em> you will NEED to set up your SSH Keys to allow passwordless ssh access and add paswordless sudo rights for the user jenkins so it can carry out tasks that require sudo such as service restarting.</p>
<h4>Passwordless SSH access</h4>
<p>To set up passwordless SSH access for Jenkins, log into <em class="ci-app">ci.app</em> as the user jenkins <code>ssh jenkins@ci.app</code>. Run and complete the prompts:</p>
<pre>
ssh-keygen
</pre>
<p>Copy the output of <code>~/.ssh/id_dsa.pub</code> or <code>~/.ssh/id_rsa.pub</code> (depending on what option you chose) to the file <code>~/.ssh/authorized_keys</code> on <em class="int-app">int.app</em>.</p>
<p>Now SSH to <em class="int-app">int.app</em> and add the jenkins user <code>adduser jenkins</code>, this will be needed for when Jenkins is installing stuff onto <em class="int-app">int.app</em>.</p>
<p>Now we need to log into <em class="ci-app">ci.app</em> as user jenkins to be able to accept the SSH Keys:</p>
<pre>
ssh jenkins@ci.app
ssh jenkins@int.app
exit
exit
</pre>
<h4>Passwordless sudo rights</h4>
<p>For enabling passwordless sudo rights to the jenkins user you will need to run: <code>sudo visudo</code> and append the file with the contents:</p>
<pre>
# Allow Jenkins to run certain commands as sudo without password
jenkins ALL = NOPASSWD: /bin/mkdir, /bin/rm, /bin/cp, /sbin/start, /sbin/stop
</pre>
<h4>Adding shell script stages to Jenkins</h4>
<p>Go to your hello world configuration panel (<a href="http://ci.app:8080/job/Hello%20World">http://ci.app:8080/job/Hello World</a>) and choose &#8216;add build step&#8217; under the Build section.</p>
<ol>
<li>Select &#8216;Execute shell&#8217; and add this line: <code>make deploy</code>.</li>
<li>Save the settings.</li>
<li>Run a build.</li>
</ol>
<p>If everything went according to plan you should be able to load <a href="http://int.app:3000">http://int.app:3000</a> and see the text &#8216;Hello World&#8217;.</p>
<h3>Verifying deployments</h3>
<p>Instead of us having to check the app is running every time a build happens, we can get Jenkins to do that for us by checking a url returns 200 response code.</p>
<p>Lets add a new Freestyle job in Jenkins and call it &#8220;Hello World Monitor&#8221;. Leave everything blank but click the checkbox for Monitor Site and add the url <code>http://int.app:3000/</code>.</p>
<p>We can now return back to our <a href="http://ci.app:8080/job/Hello%20World/configure">Hello World job</a> and check the Build other projects checkbox. Then add <code>Hello World Monitor</code> (it will auto-suggest). Save this configuration and run a build.</p>
<h3>Finally</h3>
<p>If you have made it this far, thanks for reading, hopefully everything went well?</p>
<p>If everything went well, you are in a good place to start adding more Continuous Integration elements such as unit tests, JSLinting and many other automated steps.</p>
<p>There are a number of things I didn&#8217;t go into much depth on such as the node.js app itself, there are plenty of articles out there about how to do this. A good resource worth checking out is <a href="http://howtonode.org/">http://howtonode.org</a>.</p>
<p>Feel free to get in touch if you need any help but be warned I have a busy day job so I may take time to respond.</p>
<p>Image courtesy of <a href="http://www.flickr.com/photos/kulor/4302501803/">Me</a></p>
<iframe src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fwww.carbonsilk.com%2Fnode%2Fdeploying-nodejs-apps%2F&amp;layout=standard&amp;show_faces=true&amp;width=450&amp;action=like&amp;colorscheme=light" scrolling="no" frameborder="0" allowTransparency="true" style="border:none; overflow:hidden; width:450px;height:30px;margin-top:5px;"></iframe>]]></content:encoded>
			<wfw:commentRss>http://www.carbonsilk.com/node/deploying-nodejs-apps/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		<feedburner:origLink>http://www.carbonsilk.com/node/deploying-nodejs-apps/</feedburner:origLink></item>
		<item>
		<title>Hiding the chat and invite friend panel in Gmail</title>
		<link>http://feedproxy.google.com/~r/carbonsilk/~3/fVab0BEdf0Q/</link>
		<comments>http://www.carbonsilk.com/productivity/hiding-the-chat-and-invite-friend-panel-in-gmail/#comments</comments>
		<pubDate>Fri, 12 Nov 2010 13:33:19 +0000</pubDate>
		<dc:creator>James Broad</dc:creator>
				<category><![CDATA[Productivity]]></category>
		<category><![CDATA[chrome]]></category>
		<category><![CDATA[custom css]]></category>
		<category><![CDATA[gmail]]></category>
		<category><![CDATA[google mail]]></category>

		<guid isPermaLink="false">http://www.carbonsilk.com/?p=235</guid>
		<description><![CDATA[After a quick scour around the internet and checking every option in the Gmail preferences it seemed like there was no way of hiding the chat (a feature I don’t use) and invite friend panels on the left bar of the web interface to Google Mail. My solution was to use a custom CSS rule [...]]]></description>
			<content:encoded><![CDATA[<p><img id="image_12_img" src="http://img.skitch.com/20101105-mws3xew583j3yeuquw8kwipyp5.gif" alt="Gmail chat panel"></p>
<p>After a quick scour around the internet and checking every option in the Gmail preferences it seemed like there was no way of hiding the chat (a feature I don’t use) and invite friend panels on the left bar of the web interface to Google Mail.</p>
<p>My solution was to use a custom CSS rule for Gmail which consists of the following CSS:</p>
<pre>.nH.pp.T0 .nH.s,
.nH.pp.T0 .nH.pY
{
    display:none;
}
</pre>
<h3>Minor Issues</h3>
<p><img src="http://img.skitch.com/20101105-b6y56cst65uc1e41e9hwacptcy.gif" alt="Border issue with empty panels"></p>
<p>Now this is not ideal CSS but it seems Gmail have no id’s or specific hooks to target the panels, so I went with the best specificity I could get to not affect other plugins you may have in the left rail (I also have a calendar panel). The downside to this CSS rule is I am left with some container borders as you can see in this snapshot.</p>
<h3>Alternative solution</h3>
<p>The alternative approach I could have taken would have been to add some custom JavaScript but I figured out CSS would be the fastest and most reliable way of hiding the panels. I may explore this as the anal side of me is not happy with the stray borders.</p>
<p>What would be nice is if Google allowed us to disable these items in the first place!</p>
<h3>Making custom CSS rules work in Chrome</h3>
<p><img style="width:100%" src="http://img.skitch.com/20101105-cds29hdkpriq297jraqnfqqt9x.gif" alt="Personalized Web Options"><br />
It seems Chrome (my browsing browser of choice) has no built in custom/user CSS functionality so I installed the <a href="https://chrome.google.com/extensions/detail/plcnnpdmhobdfbponjpedobekiogmbco">Personalized Web extension </a> which is nice as you can specify a regex pattern to match a url so I know I am only targeting Gmail using the pattern <code>^http[s]*://mail.google.com</code></p>
<iframe src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fwww.carbonsilk.com%2Fproductivity%2Fhiding-the-chat-and-invite-friend-panel-in-gmail%2F&amp;layout=standard&amp;show_faces=true&amp;width=450&amp;action=like&amp;colorscheme=light" scrolling="no" frameborder="0" allowTransparency="true" style="border:none; overflow:hidden; width:450px;height:30px;margin-top:5px;"></iframe>]]></content:encoded>
			<wfw:commentRss>http://www.carbonsilk.com/productivity/hiding-the-chat-and-invite-friend-panel-in-gmail/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.carbonsilk.com/productivity/hiding-the-chat-and-invite-friend-panel-in-gmail/</feedburner:origLink></item>
		<item>
		<title>Dom Dash – latest web application</title>
		<link>http://feedproxy.google.com/~r/carbonsilk/~3/TbV5_lPKflA/</link>
		<comments>http://www.carbonsilk.com/development/domdash-domain-portfolio/#comments</comments>
		<pubDate>Thu, 13 May 2010 05:17:52 +0000</pubDate>
		<dc:creator>James Broad</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[application]]></category>
		<category><![CDATA[codeigniter]]></category>
		<category><![CDATA[Design]]></category>
		<category><![CDATA[webapp]]></category>

		<guid isPermaLink="false">http://www.carbonsilk.com/?p=227</guid>
		<description><![CDATA[I have recently released domdash.com an application to help those that have a growing domain portfolio keep on top of their status. This was a personal itch that I needed to scratch with a domain acquisition almost every couple of months and a new project being released almost every quarter, things were getting a little [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://domdash.com" title="DomDash.com by James Broad"><img src="http://farm5.static.flickr.com/4054/4559902428_a6895c3ecb.jpg" width="500" height="500" alt="DomDash.com" /></a></p>
<p class="clear">I have recently released <a href="http://domdash.com">domdash.com</a> an application to help those that have a growing domain portfolio keep on top of their status. This was a personal itch that I needed to scratch with a domain acquisition almost every couple of months and a new project being released almost every quarter, things were getting a little hard to keep atop of.</p>
<p>One of my issues was that I have domains that sit on a mixture of hosts and domain name providers, so there was not one central tool to let me get information about my portfolio.</p>
<p>I paid particular attention to simplicity and usability when creating this application, constantly asking &#8220;does this feature add value&#8221;? With that mentality I dropped a couple of features which was hard discarding the time spent working on them but worth it for streamlining the end result. I intend on adding or refining features as I feel they fit the purpose of the application.</p>
<p>The most exciting aspect of this project was working with <a href="http://codeigniter.com/news/">CodeIgniter 2</a>, an <a href="http://en.wikipedia.org/wiki/Object-relational_mapping"><acronym title="Object-relational mapping">ORM</acronym></a> system and moving to a dedicated and affordable slice host <a href="http://www.linode.com/?r=d3905c2591b1dc6ca7a4734520f00b73f6946591">Linode</a> who are cheaper than the better known <a href="http://www.slicehost.com/">Slicehost</a> and seemed to have a pretty good reputation. So far Linode have been great, they have comprehensive <a href="http://library.linode.com/">documentation</a> on getting applications and services configured on your distribution and this was how easy it was to get up and running:</p>
<p><a href="http://twitter.com/kulor/status/12903252621">http://twitter.com/kulor/status/12903252621</a></p>
<blockquote><p>just set up an Ubuntu LAMP stack from scratch on my lunch break on linode.com (including signup)</p></blockquote>
<p>Anyway, I hope you enjoy this application, if you have feedback, feel free to click on the feedback link on <a href="http://domdash.com">domdash.com</a>.</p>
<iframe src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fwww.carbonsilk.com%2Fdevelopment%2Fdomdash-domain-portfolio%2F&amp;layout=standard&amp;show_faces=true&amp;width=450&amp;action=like&amp;colorscheme=light" scrolling="no" frameborder="0" allowTransparency="true" style="border:none; overflow:hidden; width:450px;height:30px;margin-top:5px;"></iframe>]]></content:encoded>
			<wfw:commentRss>http://www.carbonsilk.com/development/domdash-domain-portfolio/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.carbonsilk.com/development/domdash-domain-portfolio/</feedburner:origLink></item>
		<item>
		<title>Slow motion from 60FPS movies</title>
		<link>http://feedproxy.google.com/~r/carbonsilk/~3/HTIMX1KEnS4/</link>
		<comments>http://www.carbonsilk.com/video/60fps-to-slow-motion/#comments</comments>
		<pubDate>Sat, 20 Feb 2010 07:48:20 +0000</pubDate>
		<dc:creator>James Broad</dc:creator>
				<category><![CDATA[video]]></category>
		<category><![CDATA[conversion]]></category>
		<category><![CDATA[convert]]></category>
		<category><![CDATA[editing]]></category>
		<category><![CDATA[film]]></category>
		<category><![CDATA[media]]></category>
		<category><![CDATA[movie]]></category>

		<guid isPermaLink="false">http://www.carbonsilk.com/?p=212</guid>
		<description><![CDATA[If you are looking for a free solution to slow down 60 frames per second (FPS) AKA 60p footage to get a slow motion effect on your Mac, you can download and install the freeware video de-interlacer JSE Deinterlacer. This will allow you to export your video at a slower framerate like 24FPS through stretching the [...]]]></description>
			<content:encoded><![CDATA[<p><object width="560" height="340"><param name="movie" value="http://www.youtube.com/v/bLnUunB5dDo&#038;hl=en_US&#038;fs=1&#038;rel=0"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/bLnUunB5dDo&#038;hl=en_US&#038;fs=1&#038;rel=0" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="560" height="340"></embed></object></p>
<p>If you are looking for a free solution to slow down 60 frames per second (FPS) AKA 60p footage to get a slow motion effect on your Mac, you can download and install the freeware video de-interlacer <a href="http://www.apple.com/downloads/macosx/video/jesdeinterlacer.html">JSE Deinterlacer</a>. This will allow you to export your video at a slower framerate like 24FPS through stretching the film to be double length and use the additional frames shot to fill the time, kind of like stretching out  a coiled spring. Fast frame rates are now available from the Canon 7d and 550d cameras with signs that many more cameras follow suit by offering this feature, thus the reason to offer a no-cost option of how to handle the footage.</p>
<h3>Step one: Import</h3>
<p>Specify the film you wish to process, thats it, use the default values for everything else.</p>
<p><a href="http://www.carbonsilk.com/wp-content/uploads/2010/02/Import.jpg"><img class="alignnone size-full wp-image-214" title="Import" src="http://www.carbonsilk.com/wp-content/uploads/2010/02/Import.jpg" alt="" width="420" height="522" /></a></p>
<h3>Step Two: Project settings</h3>
<p>This is the main part we need to care about. Ensure you have <em>Deinterlace</em> selected from the options and <em>Both fields</em> and <em>Double movie duration</em> checked. <em>Normal height</em> and <em>Adaptive</em> will be selected by default, this is what we want.</p>
<p><a href="http://www.carbonsilk.com/wp-content/uploads/2010/02/Project.jpg"><img class="alignnone size-full wp-image-217" title="Project" src="http://www.carbonsilk.com/wp-content/uploads/2010/02/Project.jpg" alt="" width="420" height="522" /></a></p>
<h3>Step 3: Output</h3>
<p>We specify your desired output video location and set the settings for the movie that is exported. Select the <em>export</em> option and choose Quicktime Movie.</p>
<p><a href="http://www.carbonsilk.com/wp-content/uploads/2010/02/Output.jpg"><img class="alignnone size-full wp-image-216" title="Output" src="http://www.carbonsilk.com/wp-content/uploads/2010/02/Output.jpg" alt="" width="420" height="522" /></a></p>
<h3>Step 4: Movie Settings</h3>
<p>If you are explicitly looking for slowed speed sound select the <em>sound</em> checkbox and your audio channel will be exported, else just unselect this. Click <em>settings</em> to choose more specific output options.</p>
<p><a href="http://www.carbonsilk.com/wp-content/uploads/2010/02/Movie-Settings.jpg"><img class="alignnone size-full wp-image-215" title="Movie Settings" src="http://www.carbonsilk.com/wp-content/uploads/2010/02/Movie-Settings.jpg" alt="" width="365" height="448" /></a></p>
<h3>Step 5: Video Settings</h3>
<p>Choose MPEG-4 Video as your compression, choose a frame rate of 24 &#8211; 30 using keyframes every 24 frames. The other settings are just for how high you want quality to be.</p>
<p><a href="http://www.carbonsilk.com/wp-content/uploads/2010/02/Video-Settings.jpg"><img class="alignnone size-medium wp-image-218" title="Video Settings" src="http://www.carbonsilk.com/wp-content/uploads/2010/02/Video-Settings-300x226.jpg" alt="" width="300" height="226" /></a></p>
<h3>Step 6: Finishing up</h3>
<p>Now you can return back to the output screen and select <em>Ok</em>, this will start the conversion process off that could take some time depending on the size of your source video. Once you have converted your video, you can take it into your choice of video editing suites such as iMovie.</p>
<iframe src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fwww.carbonsilk.com%2Fvideo%2F60fps-to-slow-motion%2F&amp;layout=standard&amp;show_faces=true&amp;width=450&amp;action=like&amp;colorscheme=light" scrolling="no" frameborder="0" allowTransparency="true" style="border:none; overflow:hidden; width:450px;height:30px;margin-top:5px;"></iframe>]]></content:encoded>
			<wfw:commentRss>http://www.carbonsilk.com/video/60fps-to-slow-motion/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.carbonsilk.com/video/60fps-to-slow-motion/</feedburner:origLink></item>
		<item>
		<title>Convert a series of images to a movie</title>
		<link>http://feedproxy.google.com/~r/carbonsilk/~3/aHCu1pMGHXA/</link>
		<comments>http://www.carbonsilk.com/development/images-to-movie/#comments</comments>
		<pubDate>Sat, 17 Oct 2009 01:25:57 +0000</pubDate>
		<dc:creator>James Broad</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[ffmpeg]]></category>
		<category><![CDATA[images]]></category>
		<category><![CDATA[timelapse]]></category>
		<category><![CDATA[Unix]]></category>
		<category><![CDATA[video]]></category>

		<guid isPermaLink="false">http://www.carbonsilk.com/?p=203</guid>
		<description><![CDATA[I have talked in the past about how to get a fully working time lapse system on a Mac using a webcam and some command line scripting. That was great but could do with some tweaks to get a more elegant solution which I attempted to reach here. I wanted to get more use out [...]]]></description>
			<content:encoded><![CDATA[<p><object type="application/x-shockwave-flash" width="550" height="309" data="http://www.flickr.com/apps/video/stewart.swf?v=71377" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"><param name="flashvars" value="intl_lang=en-us&#038;photo_secret=163e39a9dd&#038;photo_id=4010869516"></param><param name="movie" value="http://www.flickr.com/apps/video/stewart.swf?v=71377"></param><param name="bgcolor" value="#000000"></param><param name="allowFullScreen" value="true"></param><embed type="application/x-shockwave-flash" src="http://www.flickr.com/apps/video/stewart.swf?v=71377" bgcolor="#000000" allowfullscreen="true" flashvars="intl_lang=en-us&#038;photo_secret=163e39a9dd&#038;photo_id=4010869516" height="309" width="550"></embed></object></p>
<p>I have talked in the past about how to get a <a href="http://www.carbonsilk.com/development/timelapse-video-mac/">fully working time lapse system on a Mac</a> using a webcam and some command line scripting. That was great but could do with some tweaks to get a more elegant solution which I attempted to reach here.</p>
<p>I wanted to get more use out of my digital SLR camera so I set my camera up on a tripod, connected it up to an intervalometer (my mac) and gained a bunch of files that needed to be processed and turned into a movie. I created the following script to turn my images into a movie.</p>
<p>This script will run on any unix like environment with a bash shell and uses <code>ffmpeg</code> so make sure you have it installed on your *nix machine.</p>
<ol>
<li>Download <a href="http://github.com/kulor/images2movie/blob/master/images2movie">images2movie</a></li>
<li>Change the permissions to allow the script to be executed <code>chmod a+x images2movie</code></li>
<li>Copy file to /usr/bin/ <code>sudo cp images2movie /usr/bin/</code></li>
<li>Run by <code>images2movie &lt;directory&gt; 30</code></li>
</ol>
<p>If it all goes well, you should see the following output:</p>
<pre>
Movie generated: timelapse.mov
</pre>
<p>Some more work could be done to resize images in advance to ensure that ffmpeg doesn&#8217;t choke on the image sizes but I will save that for another time.</p>
<iframe src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fwww.carbonsilk.com%2Fdevelopment%2Fimages-to-movie%2F&amp;layout=standard&amp;show_faces=true&amp;width=450&amp;action=like&amp;colorscheme=light" scrolling="no" frameborder="0" allowTransparency="true" style="border:none; overflow:hidden; width:450px;height:30px;margin-top:5px;"></iframe>]]></content:encoded>
			<wfw:commentRss>http://www.carbonsilk.com/development/images-to-movie/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.carbonsilk.com/development/images-to-movie/</feedburner:origLink></item>
		<item>
		<title>Amber – Mac Terminal theme</title>
		<link>http://feedproxy.google.com/~r/carbonsilk/~3/NOla-_6VYIk/</link>
		<comments>http://www.carbonsilk.com/development/amber-mac-terminal-theme/#comments</comments>
		<pubDate>Wed, 02 Sep 2009 00:46:50 +0000</pubDate>
		<dc:creator>James Broad</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[apple]]></category>
		<category><![CDATA[git]]></category>
		<category><![CDATA[github]]></category>
		<category><![CDATA[Mac]]></category>
		<category><![CDATA[OSX]]></category>
		<category><![CDATA[shell]]></category>
		<category><![CDATA[terminal]]></category>
		<category><![CDATA[theme]]></category>

		<guid isPermaLink="false">http://www.carbonsilk.com/?p=195</guid>
		<description><![CDATA[I created a terminal theme with a retro look of soft amber tones. I find this really nice to work with and have been using for a couple of months now. Download or fork it on Github. To use: download the amber.terminal file to your computer, open up Terminal.app, go to the preferences, settings tab, [...]]]></description>
			<content:encoded><![CDATA[<p><img class="alignnone size-full wp-image-196" title="amber theme screenshot" src="https://github.com/kulor/Amber-Theme/blob/dbde5f573913e5c2282c94ed405943357cc32061/amber.jpg?raw=true" alt="amber theme screenshot" width="529" height="367" /></p>
<p class="clear">I created a terminal theme with a retro look of soft amber tones. I find this really nice to work with and have been using for a couple of months now. Download or fork it on <a href="http://github.com/kulor/Amber-Theme/tree/master">Github</a>.</p>
<p>To use: download the <a href="http://github.com/kulor/Amber-Theme/blob/dbde5f573913e5c2282c94ed405943357cc32061/amber.terminal">amber.terminal</a> file to your computer, open up Terminal.app, go to the preferences, settings tab, then under the list of themes, click on the settings button and click import, now choose the amber.terminal file.</p>
<iframe src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fwww.carbonsilk.com%2Fdevelopment%2Famber-mac-terminal-theme%2F&amp;layout=standard&amp;show_faces=true&amp;width=450&amp;action=like&amp;colorscheme=light" scrolling="no" frameborder="0" allowTransparency="true" style="border:none; overflow:hidden; width:450px;height:30px;margin-top:5px;"></iframe>]]></content:encoded>
			<wfw:commentRss>http://www.carbonsilk.com/development/amber-mac-terminal-theme/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://www.carbonsilk.com/development/amber-mac-terminal-theme/</feedburner:origLink></item>
		<item>
		<title>Writing your first shell script</title>
		<link>http://feedproxy.google.com/~r/carbonsilk/~3/4bmSr4CIWl0/</link>
		<comments>http://www.carbonsilk.com/development/writing-your-first-shell-script/#comments</comments>
		<pubDate>Fri, 12 Jun 2009 13:32:26 +0000</pubDate>
		<dc:creator>James Broad</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[find]]></category>
		<category><![CDATA[loop]]></category>
		<category><![CDATA[script]]></category>
		<category><![CDATA[shell]]></category>
		<category><![CDATA[Unix]]></category>
		<category><![CDATA[vi]]></category>

		<guid isPermaLink="false">http://www.carbonsilk.com/?p=181</guid>
		<description><![CDATA[Shell scripts are a simple way of completing (repetitive) tasks on the command line, much like many programming languages will be used. You will see ~ something &#8212; ignore the &#8216;~&#8217; this is to signify that it is a command entered onto the command line itself. Writing the code ~ vi helloworld.sh #!/bin/bash # My [...]]]></description>
			<content:encoded><![CDATA[<div><a href="http://www.flickr.com/photos/hindesite/37052873/"><img src="http://farm1.static.flickr.com/33/37052873_2d8bfe13ba_d.jpg" alt="Shell"/></a></div>
<p class="clear">Shell scripts are a simple way of completing (repetitive) tasks on the command line, much like many programming languages will be used. You will see <code>~ something</code> &#8212; ignore the &#8216;~&#8217; this is to signify that it is a command entered onto the command line itself.</p>
<h3>Writing the code</h3>
<p><code>~ vi helloworld.sh</code></p>
<pre>
#!/bin/bash
# My first script
MESSAGE="Hello World!"
echo $MESSAGE
</pre>
<p>Here we have just entered a really simple example of using variables and returning the value.</p>
<h3>Setting the permissions</h3>
<p>We need to set permission to allow the script to be executed, this is needed to be done on all unix environments for something to be run</p>
<p><code>~ chmod +x helloworld.sh</code></p>
<h3>Running the script</h3>
<p><code>~ sh helloworld.sh</code></p>
<pre>Hello World!</pre>
<p>Now you should have the response &#8220;Hello World!&#8221; from running this script.</p>
<h3>Going more advanced</h3>
<p>Lets explore some of the basic options we have to play with in the shell by example.</p>
<h4>Loop test</h4>
<p><code>~ vi looptest.sh</code></p>
<pre>
#!/bin/bash
# My first loop
FILETYPES="xml html css js"
for TYPE in $FILETYPES
    do
        echo 'Looking for' $TYPE 'files'
        find . -name '*'$TYPE
    done
</pre>
<p>Now set the correct permissions and run the script</p>
<p><code>~ chmod +x looptest.sh</code><br />
<code>~ sh looptest.sh</code></p>
<pre>
Looking for xml files
./somefile.xml
Looking for html files
./somefile.html
Looking for css files
./somefile.css
Looking for js files
./somefile.js
</pre>
<h4>If conditional test</h4>
<p><code>~ vi iftest.sh</code></p>
<pre>
#!/bin/bash
# If the file does not exist, make it
FILE='test'
if [ ! -f $FILE ] ; then
    mkdir -p $FILE
fi
ls -las $FILE
</pre>
<p>Now set the correct permissions and run the script</p>
<p><code>~ chmod +x iftest.sh</code><br />
<code>~ sh iftest.sh</code></p>
<p>Hopefully this is enough to help you on your way to making more use of the powers of Unix&#8230;</p>
<h3>Further reading</h3>
<p><a href="http://www.gnu.org/software/bash/manual/html_node/index.html">Bash Manual</a><br />
<a href="http://blog.emson.co.uk/2009/06/18-useful-bash-scripts-for-web-developers/">Useful bash one liner scripts</a></p>
<iframe src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fwww.carbonsilk.com%2Fdevelopment%2Fwriting-your-first-shell-script%2F&amp;layout=standard&amp;show_faces=true&amp;width=450&amp;action=like&amp;colorscheme=light" scrolling="no" frameborder="0" allowTransparency="true" style="border:none; overflow:hidden; width:450px;height:30px;margin-top:5px;"></iframe>]]></content:encoded>
			<wfw:commentRss>http://www.carbonsilk.com/development/writing-your-first-shell-script/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://www.carbonsilk.com/development/writing-your-first-shell-script/</feedburner:origLink></item>
	</channel>
</rss><!-- Dynamic page generated in 0.258 seconds. --><!-- Cached page generated by WP-Super-Cache on 2013-05-21 09:16:31 --><!-- Compression = gzip -->
