<?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>official.fm developer blog</title>
	<atom:link href="http://devblog.official.fm/feed/" rel="self" type="application/rss+xml" />
	<link>http://devblog.official.fm</link>
	<description>official.fm developer blog</description>
	<lastBuildDate>Mon, 19 Mar 2012 20:37:36 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1.3</generator>
		<item>
		<title>alac.js: ALAC in Coffeescript</title>
		<link>http://devblog.official.fm/uncategorized/alac-in-coffeescript/</link>
		<comments>http://devblog.official.fm/uncategorized/alac-in-coffeescript/#comments</comments>
		<pubDate>Wed, 21 Dec 2011 21:17:28 +0000</pubDate>
		<dc:creator>Amos Wenger</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://devblog.official.fm/?p=157</guid>
		<description><![CDATA[Our labs team has released ALAC in Coffeescript. ALAC is Apple&#8217;s proprietary lossless audio format. It&#8217;s mainly used for audio production, not for consumer listening. Apple released their source code not long ago and we did a port from C to Javascript, using bleeding edge browse APIs to actually render the waveforms. This codec was [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://ofmlabs.org/">Our labs team</a> has released <a href="http://codecs.ofmlabs.org">ALAC in Coffeescript</a>.</p>
<p>ALAC is Apple&#8217;s proprietary lossless audio format. It&#8217;s mainly used for audio production, not for consumer listening. Apple released their source code not long ago and we did a port from C to Javascript, using bleeding edge browse APIs to actually render the waveforms.</p>
<p>This codec was never going to become a standard. It was never to going to be playable in any browser without a fairly rare plugin. But using Javascript in a browser supporting these new audio APIs, everybody can now play this codec without installing anything.</p>
<p><a href="https://github.com/ofmlabs/alac.js">Open source, on Github</a>.</p>
<p>Links:</p>
<ul>
<li><a href="http://badassjs.com/post/14463682242/introducing-alac-js-an-apple-lossless-audio-decoder-in">Devon&#8217;s blog on JS advances </a> has the details.</li>
<li>Conversation in French <a href="http://korben.info/codecs-javascript-mp3-alac.html">on Korben&#8217;s blog</a>.</li>
<li>The <a href="http://news.ycombinator.com/item?id=3371171">Hacker News thread</a> about it.</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://devblog.official.fm/uncategorized/alac-in-coffeescript/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>updated Desktop Track Manager</title>
		<link>http://devblog.official.fm/news/updated-desktop-track-manager/</link>
		<comments>http://devblog.official.fm/news/updated-desktop-track-manager/#comments</comments>
		<pubDate>Fri, 16 Dec 2011 15:47:26 +0000</pubDate>
		<dc:creator>Amos Wenger</dc:creator>
				<category><![CDATA[news]]></category>

		<guid isPermaLink="false">http://devblog.official.fm/?p=150</guid>
		<description><![CDATA[We have posted a new version of our Desktop Track Manager. This is a client-side app that helps with common tasks for artists. It&#8217;s especially useful for uploading multiple files at a time. The biggest improvement is good performance for people with a lot of files, but also there were a bunch of pinpoint fixes. [...]]]></description>
			<content:encoded><![CDATA[<p>We have posted a new version of our Desktop Track Manager. This is a client-side app that helps with common tasks for artists. It&#8217;s especially useful for uploading multiple files at a time.</p>
<p>The biggest improvement is good performance for people with a lot of files, but also there were a bunch of pinpoint fixes.</p>
<p>Here is the change log:</p>
<table border="0" cellspacing="0" cellpadding="0" width="471">
<tbody>
<tr height="15">
<td colspan="3" width="471" height="15"><strong>TrackManager-0.3.9.2</strong></td>
</tr>
<tr height="15">
<td height="15"></td>
<td>BUG</td>
<td width="341">Wrong characters (capital and misspelling)</td>
</tr>
<tr height="15">
<td height="15"></td>
<td>BUG</td>
<td width="341">Long description crashes</td>
</tr>
<tr height="15">
<td height="15"></td>
<td>BUG</td>
<td width="341">Components jump on the right sidebar when changing track selection</td>
</tr>
<tr height="15">
<td height="15"></td>
<td>BUG</td>
<td width="341">Loading icon is jumping around when updating multiple tracks</td>
</tr>
<tr height="30">
<td height="30"></td>
<td>BUG</td>
<td width="341">When a track is updated selection is lost in the track list</td>
</tr>
<tr height="15">
<td height="15"></td>
<td>BUG</td>
<td width="341">No track is selected after TM launch</td>
</tr>
<tr height="15">
<td height="15"></td>
<td>BUG</td>
<td width="341">Selection is lost when sorting tracks</td>
</tr>
<tr height="15">
<td height="15"></td>
<td>FEATURE</td>
<td width="341">Added message when verification code is not accepted</td>
</tr>
<tr height="15">
<td height="15"></td>
<td>FEATURE</td>
<td width="341">Added Password visible in the right sidebar for private tracks</td>
</tr>
<tr height="15">
<td height="15"></td>
<td>FEATURE</td>
<td width="341">Added display of common fields for multi track edition</td>
</tr>
<tr height="15">
<td height="15"></td>
<td>FEATURE</td>
<td width="341">Open dialog for browsing audio file when clicking on the dropbox</td>
</tr>
<tr height="15">
<td height="15"></td>
<td>FEATURE</td>
<td width="341">Drag and drop image in the edit track dialog and the right sidebar for single and multiple track selection</td>
</tr>
<tr height="30">
<td height="30"></td>
<td>OPT</td>
<td width="341">CPU Optimizations (TM slows down with accounts that have more than 100 tracks)</td>
</tr>
</tbody>
</table>
<p>To pick up the new version, go to <a title="http://bit.ly/vl2q39" href="http://bit.ly/vl2q39">http://bit.ly/vl2q39</a>.</p>
<p>The core contributors on this project were Emilie de Fouchécour and Thibault Béné.</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://devblog.official.fm/news/updated-desktop-track-manager/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Top Tests</title>
		<link>http://devblog.official.fm/open-source-contributions/top-tests/</link>
		<comments>http://devblog.official.fm/open-source-contributions/top-tests/#comments</comments>
		<pubDate>Mon, 12 Dec 2011 20:27:31 +0000</pubDate>
		<dc:creator>Amos Wenger</dc:creator>
				<category><![CDATA[open source contributions]]></category>

		<guid isPermaLink="false">http://devblog.official.fm/?p=144</guid>
		<description><![CDATA[If your unit tests are slow, it&#8217;s hard to debug the problem.  We have released a tool to help  Rails developers speed up tests. This tool is called &#8220;Top Tests.&#8221; To help you figure out where the problems are, Top Tests shows you a list of the ten slowest tests. Run times are shown, and [...]]]></description>
			<content:encoded><![CDATA[<p>If your unit tests are slow, it&#8217;s hard to debug the problem.  We have released a tool to help  Rails developers speed up tests. This tool is called &#8220;Top Tests.&#8221;</p>
<p>To help you figure out where the problems are, Top Tests shows you a list of the ten slowest tests. Run times are shown, and the list is sorted from the worst on down. It&#8217;s like a profiler that tells you about runtime performance, except that it tells you about performance of your tests instead of your app.</p>
<p>To enable you to include test performance in your unit tests, Top Tests allows you to fail the build if any test takes too long. The timeout is a configurable parameter.</p>
<p>Our tool is open source under a BSD license. Code and detailed documentation is on Github at <a title="https://github.com/officialfm/top_tests" href="https://github.com/officialfm/top_tests">https://github.com/officialfm/top_tests</a>.</p>
<p>We use lots of open source from other people and are happy to get to give back. We hope this is useful.</p>
<p>The core contributor on this project was Alexis Bernard.</p>
]]></content:encoded>
			<wfw:commentRss>http://devblog.official.fm/open-source-contributions/top-tests/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>front end developer wanted</title>
		<link>http://devblog.official.fm/uncategorized/front-end-developer-wanted/</link>
		<comments>http://devblog.official.fm/uncategorized/front-end-developer-wanted/#comments</comments>
		<pubDate>Tue, 08 Nov 2011 00:47:38 +0000</pubDate>
		<dc:creator>ben</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[helpwanted]]></category>

		<guid isPermaLink="false">http://devblog.official.fm/?p=132</guid>
		<description><![CDATA[We&#8217;re looking for a developer with skills in the browser stack &#8211; HTML, CSS, Javascript. You must be up to date: HTML5, CSS3, current ideas about JS. The person who is the right fit for this job is probably mid-career. This wouldn&#8217;t be your first job after university. This is a full time job in [...]]]></description>
			<content:encoded><![CDATA[<p>We&#8217;re looking for a developer with skills in the browser stack &#8211; HTML, CSS, Javascript.  You must be up to date: HTML5, CSS3, current ideas about JS.</p>
<p>The person who is the right fit for this job is probably mid-career. This wouldn&#8217;t be your first job after university.</p>
<p>This is a full time job in our Geneva office. You&#8217;ll need to speak French and some English. You&#8217;ll need to be able to work legally in Switzerland (most EU people are).</p>
<p>Be a person with energy and passion, somebody who&#8217;s really happy when they make something fantastic. </p>
<p>Email jobs@official.fm. Tell us about yourself. What have you made? Got source?</p>
]]></content:encoded>
			<wfw:commentRss>http://devblog.official.fm/uncategorized/front-end-developer-wanted/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Advanced API now available in Ruby and PHP bindings</title>
		<link>http://devblog.official.fm/ruby/advanced-api-now-available-in-ruby-and-php-bindings/</link>
		<comments>http://devblog.official.fm/ruby/advanced-api-now-available-in-ruby-and-php-bindings/#comments</comments>
		<pubDate>Thu, 04 Aug 2011 15:37:07 +0000</pubDate>
		<dc:creator>Amos Wenger</dc:creator>
				<category><![CDATA[Advanced API]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://devblog.official.fm/?p=128</guid>
		<description><![CDATA[It&#8217;s with great pleasure that I announce you the release of officialfm-php v0.1.0 and officialfm-ruby v0.1.1, both of which support all endpoints of the Official.fm Advanced API. By navigating the developer docs, you can see that the Advanced API uses OAuth 1.0a to allow users to log in with their own credentials in a secure [...]]]></description>
			<content:encoded><![CDATA[<p>It&#8217;s with great pleasure that I announce you the release of <a href="https://github.com/officialfm/officialfm-php">officialfm-php</a> v0.1.0 and <a href="https://github.com/officialfm/officialfm-ruby">officialfm-ruby</a> v0.1.1, both of which support all endpoints of the Official.fm Advanced API.</p>
<p>By navigating the <a href="http://official.fm/developers/advanced">developer docs</a>, you can see that the Advanced API uses <a href="http://oauth.net/">OAuth</a> 1.0a to allow users to log in with their own credentials in a secure way, without ever needing to ask for their password.</p>
<p>This means that you can now create web applications that can fully manipulate a user&#8217;s profile, such as changing his name, bio, uploading a new avatar, but also uploading new tracks, modifying existing ones, and assembling playlists fully through the API. These new endpoints open up a world of possibilities for Official.fm web applications. One could create multi-track editors fully in the browser, that could even run on mobile devices!</p>
<p>However, the OAuth sign-in flow is not exactly trivial. First, a request token must be obtained by prodiving your application key and consumer secret. Then, you have to redirect the user to an authorize request URL on official.fm. Then, once the user has authorized your application, he wll be redirected to a callback page in your application, then providing you with the token which will be used to sign all further communication.</p>
<p>Fortunately, there exists Ruby and PHP libraries to help with OAuth. In Ruby, we recommend using omniauth, which integrates nicely into Rails. We provide an example of <a href="https://github.com/officialfm/sign-in-with-officialfm-ruby">sign-in with Official.fm in Ruby using Rails 3 and omniaut</a> on GitHub. As for PHP, it seems that the stock oauth module handles request_token incorrectly, using a GET request instead of a POST request, so it doesn&#8217;t work correctly. We recommend instead using the <a href="http://code.google.com/p/oauth-php/">oauth-php library</a>, which has the added bonus of not using any native code. As for Ruby, we provide <a href="https://github.com/officialfm/officialfm-php">an example PHP application</a> for OAuth sign-in on GitHub.</p>
<p>If you create an application using the Advanced API, mention us on Twitter and we might feature it on this blog!</p>
]]></content:encoded>
			<wfw:commentRss>http://devblog.official.fm/ruby/advanced-api-now-available-in-ruby-and-php-bindings/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Unleashing the full power of the Official.fm Javascript APIs</title>
		<link>http://devblog.official.fm/javascript/officialfm-javascript-apis/</link>
		<comments>http://devblog.official.fm/javascript/officialfm-javascript-apis/#comments</comments>
		<pubDate>Wed, 15 Jun 2011 10:51:32 +0000</pubDate>
		<dc:creator>Amos Wenger</dc:creator>
				<category><![CDATA[JavaScript]]></category>

		<guid isPermaLink="false">http://devblog.official.fm/?p=73</guid>
		<description><![CDATA[In the previous posts, we have reviewed the Ruby bindings and the PHP bindings for our Simple API. As a reminder, the Simple API allows you to retrieve users, tracks, and playlists information. Using the &#8216;embed&#8217; parameter, HTML embed codes are generated, allowing to easily include Official.fm players in dynamically generated webpages. However, things tend [...]]]></description>
			<content:encoded><![CDATA[<p>In the previous posts, we have reviewed the Ruby bindings and the PHP bindings for our Simple API. As a reminder, the Simple API allows you to retrieve users, tracks, and playlists information. Using the &#8216;embed&#8217; parameter, HTML embed codes are generated, allowing to easily include Official.fm players in dynamically generated webpages. However, things tend to move more and more to the client side, and this means Javascript. Our Javascript binding allows you to do exactly that: access the Simple API from the browser, using asynchronous HTTP requests. But that&#8217;s not all there is to it.</p>
<p><a href="http://freshcove.rs/"><img src="http://devblog.official.fm/wp-content/uploads/2011/06/freshcovers-1024x696.png" alt="" title="freshcovers" width="1024" height="696" class="aligncenter size-large wp-image-99" /></a></p>
<p>It&#8217;s with great pleasure that we finally release our Javascript Player API. Creating players, manipulating them (play/pause/stop/next), responding to events (when reaching the end of a playlist, when paused by the user, etc.) has never been easier with <a href="https://github.com/officialfm/officialfm-javascript/raw/master/player_api.js">this single javascript file</a>. It is always up to date at <a href="https://github.com/officialfm/officialfm-javascript/raw/master/player_api.js">our GitHub repo</a>. Don&#8217;t host your own version but rather, use GitHub as a CDN, so that your web applications will never break even when we update the player.</p>
<p>Enough talk, time to get some action. Let&#8217;s get started with the Player API, since it&#8217;s the most exciting part of this release. In this example, I&#8217;ll just create a player for one of my favorite playlists lately, Sunset Melodies. First, we need an HTML page with an empty div, ready to host our player.</p>
<p><script src="https://gist.github.com/1008849.js?file=gistfile1.phtml"></script></p>
<p>So there we have it, a nice skeleton page. Now we want to had a small bit of Javascript to actually create the player when the page is loaded.</p>
<p><script src="https://gist.github.com/1008850.js?file=gistfile1.phtml"></script></p>
<p>In all our Javascript APIs, we use the global namespace OfficialFM. The most interesting method of the player API is, of course, create(). It takes a option hash allowing you to fine tune the player creation. Three fields are mandatory though: container_id, type, and id. Type is either &#8216;track&#8217; or &#8216;playlist&#8217;, id is simply the Official.fm identifier of the track or playlist, and container_id, the id of the HTML element in which to put the player.</p>
<p>However, this simple example doesn&#8217;t do justice to the Player API. What we have ignored so far is that create() returns a Player object, with all sorts of interesting methods, such as play, pause, next, previous, get_current_track_info, etc. It gets better: you can react to player events such as onPlay, onPause, onProgress (called every few ms), onTracklistEnd, etc. For example, if you wanted to trigger the next player in a list, you would simply have to add these two fields to the options hash:</p>
<p><script src="https://gist.github.com/1019959.js?file=gistfile1.js"></script></p>
<p>(To see it in practice, <a href="http://jsfiddle.net/RddWP/4/">read this jsfiddle</a>, featuring three tracks I really like.)</p>
<p>However, to obtain a list of track IDs, it would be even cooler to use the Official.fm Simple API, right? Well good news: there is a Javascript bindings for it. However, unlike the pure Player API, it depends on jQuery, so it&#8217;s a bit more heavyweight. Nevertheless, it makes it easy to build really nice applications. And to show my point, I have built a pretty HTML5/CSS3/Javascript application to show the latest tracks in a nice carousel: <a href="http://freshcove.rs/">freshcove.rs</a>. As usual, we&#8217;ve made the <a href="https://github.com/officialfm/freshcovers">source</a> available on Github, feel free to fork and improve!</p>
]]></content:encoded>
			<wfw:commentRss>http://devblog.official.fm/javascript/officialfm-javascript-apis/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Building Official.fm-powered applications in PHP</title>
		<link>http://devblog.official.fm/php/building-officialfm-apps-in-php/</link>
		<comments>http://devblog.official.fm/php/building-officialfm-apps-in-php/#comments</comments>
		<pubDate>Tue, 14 Jun 2011 09:32:46 +0000</pubDate>
		<dc:creator>Amos Wenger</dc:creator>
				<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://devblog.official.fm/?p=60</guid>
		<description><![CDATA[Last time, we reviewed the Ruby bindings for Official.fm&#8217;s simple API. However, as we mentioned, we want to empower you, and that means giving you the choice of the language you want. Second of a whole series of language bindings, today we take a look at the PHP bindings which have just been released in [...]]]></description>
			<content:encoded><![CDATA[<p>Last time, we reviewed the Ruby bindings for Official.fm&#8217;s simple API. However, as we mentioned, we want to empower you, and that means giving you the choice of the language you want. Second of a whole series of language bindings, today we take a look at the <a href="https://github.com/officialfm/officialfm-php">PHP bindings</a> which have just been released in version 0.0.1</p>
<p>As you have probably noticed, the Official.fm simple API responds with either XML or JSON. For the PHP bindings, we&#8217;ve opted for JSON responses, so the binding needs json_decode, present from PHP 5.2.0 and onwards. It also uses json_last_error if present, so if you have PHP >= 5.3.0 you get better error reports.</p>
<p>For maximum reliability, it also uses Sean Huber&#8217;s excellent curl binding for PHP, that you can grab here: <a href="https://github.com/shuber/curl">https://github.com/shuber/curl</a>. PHP&#8217;s new JSON module makes our API very straight-forward to use. Like the <a href="https://github.com/officialfm/officialfm-ruby">Ruby bindings</a>, it is fully object-oriented. Here&#8217;s a really small example to get started with:</p>
<p><script src="https://gist.github.com/1006173.js?file=gistfile1.pl"></script></p>
<p>First, we include the officialfm.php. Since it depends on curl.php make sure that you have it in the same directory. Next, we instanciate the OfficialFM class, passing our API key. Next, we the profile of the user &#8220;nddrylliog&#8221; and print its full name. By the way, in production, replace this demo key by <a href="http://official.fm/developers/manage#register">your own application key</a>! It&#8217;s free, and it helps us respond to your needs in the best possible way.</p>
<p>To have a complete list of possible requests and their responses, have a look at our recently revamped <a href="http://official.fm/developers/simple/responses">developer docs</a>. Note that, as in the Ruby binding, when you&#8217;re requesting information about a single element, the bindings will return a single object instead of an array, unlike the REST API.</p>
<p>Apart from that slight difference, you&#8217;ll find in the PHP API everything from the REST API, including the ability to generate embed codes for track players and playlist players. Here&#8217;s a small example to display the first three playlist for the search term &#8220;sunrise&#8221;:</p>
<p><script src="https://gist.github.com/1006217.js?file=sunrise.php"></script></p>
<p>Optional parameters, such as the maximum number of results and whether embed codes should be included in the response, are passed via an array as the last parameter to query functions. embed is an alias for api_embed_codes and limit is an alias for api_max_responses, like in the <a href="https;//github.com/officialfm/officialfm-ruby">Ruby bindings</a>.</p>
<p>Now let&#8217;s build something concrete with those PHP bindings. This time we&#8217;ll build something really trivial, a static Google map of an user subscribers/subscriptions and contacts. The <a href="http://code.google.com/apis/maps/documentation/staticmaps/">Google Static Maps API V2</a> is insanely simple to use, basically we just have to construct the URL of the map&#8217;s generated image. The map can&#8217;t be scrolled, zoomed etc. like full-featured JS maps can, and we&#8217;re limited as to the number of markers because of maximum URL length that Google servers support, but we&#8217;ll focus on using the PHP bindings to retrieve Official.fm user information.</p>
<p><a href="http://devblog.official.fm/wp-content/uploads/2011/06/staticmap.png"><img src="http://devblog.official.fm/wp-content/uploads/2011/06/staticmap-300x300.png" alt="" title="staticmap" width="300" height="300" class="aligncenter size-medium wp-image-84" /></a></p>
<p>The core logic is really simple: creating an OfficialFM instance with our API key, doing three requests (subscribers, subscriptions, contacts), and iterating through them to construct our Google Maps URL. You can browse the <a href="https://github.com/officialfm/usermaps/blob/master/index.php5">full project&#8217;s source on Github</a>, as usual, and see the result <a href="http://usermaps.orchestra.io/">deployed on orchestra.io</a>.</p>
<p>Next time, we&#8217;ll have an entirely Javascript-focused article, presenting a Simple API bindings and a new API which we are extremely proud of, and which will undoubtedly inspire many cool hacks. In other news, <a href="http://wiki.musichackday.org/index.php?title=Berlin_2011_Hacks">Music Hack Day Berlin</a> was a blast! If you weren&#8217;t there, it&#8217;s official, you have been missing out. We&#8217;ll be kicking ass at <a href="http://bcn.musichackday.org/2011/">Music Hack Day Barcelona</a> as well, and although the registration is sold out, you should watch the hacks presentations, and follow <a href="https://twitter.com/bcnmusichackday">@bcnmusichackday</a> on Twitter!</p>
]]></content:encoded>
			<wfw:commentRss>http://devblog.official.fm/php/building-officialfm-apps-in-php/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Official.fm + Twitter + Ruby = ofmtweet</title>
		<link>http://devblog.official.fm/ruby/officialfm-ruby-gem-ofmtweet/</link>
		<comments>http://devblog.official.fm/ruby/officialfm-ruby-gem-ofmtweet/#comments</comments>
		<pubDate>Tue, 24 May 2011 15:21:12 +0000</pubDate>
		<dc:creator>Amos Wenger</dc:creator>
				<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://devblog.official.fm/?p=37</guid>
		<description><![CDATA[It&#8217;s been a while since our Ruby gem was first released. Today we&#8217;re going to take a closer look at it by studying a practical example: ofmtweet. It&#8217;s a simple application that displays the last few tweeted tracks along with official.fm players. Besides being a great way to keep up with what&#8217;s being listened to [...]]]></description>
			<content:encoded><![CDATA[<p>It&#8217;s been a while since <a href="https://github.com/officialfm/officialfm-ruby">our Ruby gem</a> was first released. Today we&#8217;re going to take a closer look at it by studying a practical example: <a href="http://ofmtweet.heroku.com/">ofmtweet</a>. It&#8217;s a simple application that displays the last few tweeted tracks along with official.fm players. Besides being a great way to keep up with what&#8217;s being listened to on the Twitterverse, it&#8217;s actually a good example to get to know our Ruby bindings better!</p>
<p><img src="http://i.imgur.com/I9Ja3.png"/></p>
<p>Since it&#8217;s a small application, we are going to use the <a href="http://www.sinatrarb.com/">Sinatra</a> web framework, with the <a href="http://datamapper.org/">DataMapper</a> ORM, <a href="http://www.germane-software.com/software/rexml/">REXML</a> to manipulate XML blocks, and of course the <a href="https://github.com/jnunemaker/twitter">Twitter</a> and <a href="https://github.com/officialfm/officialfm-ruby">Official.fm</a> gems. We&#8217;re going to need a database to cache our results, since the combined requests to Twitter + Official.fm APIs make loading from scratch very costly. An in-memory <a href="http://www.sqlite.org/">SQLite</a> instance will be more than enough.</p>
<h3>Getting started</h3>
<p>Here&#8217;s our Gemfile, run <tt>bundle install</tt> and you&#8217;re all set!</p>
<p><script src="https://gist.github.com/982573.js"> </script></p>
<p>Your first step as an Official.fm application developer is to register your application in the <a href="http://official.fm/developers/manage">developers zone</a>. Don&#8217;t forget to give your application a meaningful name and description, along with a pretty logo — you don&#8217;t want to be unprepared when we pick your application to be featured on this blog!</p>
<p>Once you have your Application key, use it to complete this skeleton Sinatra app we&#8217;re going to flesh out:</p>
<p><script src="https://gist.github.com/982587.js"> </script></p>
<p>To make sure we&#8217;re on the right path, run <tt>ruby app.rb</tt> and visit <a href="http://localhost:4567/">http://localhost:4567/</a> (or whatever port Sinatra is running on) to see the result.</p>
<h3>Fetching tweets</h3>
<p>This is not a Twitter API tutorial, but thankfully, the twitter gem is really easy to use. Good job, <a href="https://github.com/jnunemaker/twitter">@jnunemaker</a>! We&#8217;re going to be searching for tweets containing the string <tt>official.fm/tracks/</tt>. Since searching with the Twitter API is serious business, we need to create a Search object, specify that we want recent results (well duh), and say how many results we want. This is roughly what we&#8217;re looking at:</p>
<p><script src="https://gist.github.com/982598.js?file=gistfile1.rb"></script></p>
<p>For a more complete example, see <a href="https://gist.github.com/982656">this gist</a> which displays a pretty ugly list of tweets, but hey, it works.</p>
<h3>Creating players</h3>
<p>It&#8217;s easy to create an Official.FM player once we know the ID of the track we want to play. We use <a href="http://www.ruby-doc.org/core/classes/Regexp.html">regular expressions</a> to validate the track URLs and extract the track ID. We also ignore retweets, since they&#8217;re annoying, and we check for the presence of <tt>official.fm/tracks/</tt>, because the Twitter API searches in expanded short-urls, thus we&#8217;re going to end up with bit.ly, fb.me, jmp.</p>
<p><script src="https://gist.github.com/982845.js"> </script></p>
<p>So what&#8217;s going on here? First, we create an <tt>OfficialFM::Client</tt> with our Application key. Then we retrieve information about a track, by ID, including embed codes, and we use the small embed codes in our list of tweets. The result is pretty neat, although at this point it&#8217;s obvious it needs a designer&#8217;s touch. See <a href="https://gist.github.com/982958">this gist</a> for an example of players in the timeline.</p>
<p>The best way to see what&#8217;s happening behind the scenes it to play with our API Console. Here&#8217;s an <a href="https://apigee.com/officialfm/embed/console/apigee-console-snapshots-1304226000000_b8327d35-d23e-4c44-9346-f0167f449854/rendersnapshotview">example request</a> made by our application. We could display a lot more infos such as the downloads count, creation date, genres, and a download link for some tracks.</p>
<h3>Improving performance</h3>
<p>If you&#8217;ve gotten this far, you might&#8217;ve noticed the application is running slow as fuck. Now the reason we have a database in the first place is because we want to cache those results. Instead of just caching the Twitter API results, we&#8217;re going to go one step further and cache the XHTML nodes we use to display the tweets in our application. This severely improves load times when the data is still fresh (<600s old, for the example). Since this is not a DataMapper tutorial, let me refer you to the <a href="https://github.com/officialfm/ofmtweet">ofmtweet repository</a>, which contains the full database logic presented in this paragraph.</p>
<p>Another suboptimal detail in our implementation (besides the fact that Twitter&#8217;s public keyless API seems to take pleasure in waiting 3 secs before answering) is that one request per track is done in order to create a player. Not only is it wasteful and slow, it&#8217;s also unnecessary! Our upcoming JavaScript player API allows you to create Official.fm players on-the-fly, allowing a full dynamic experience. I&#8217;ve been dreaming of a minimalist HTML5+CSS3+JS unofficial front-end to Official.fm for ages now. Can you pull it off? I&#8217;d love to feature such an app on this blog.</p>
<p>See you next time for another language binding announcement!</p>
]]></content:encoded>
			<wfw:commentRss>http://devblog.official.fm/ruby/officialfm-ruby-gem-ofmtweet/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>official.fm for developers — bring it on!</title>
		<link>http://devblog.official.fm/news/5/</link>
		<comments>http://devblog.official.fm/news/5/#comments</comments>
		<pubDate>Fri, 29 Apr 2011 10:51:20 +0000</pubDate>
		<dc:creator>Amos Wenger</dc:creator>
				<category><![CDATA[Advanced API]]></category>
		<category><![CDATA[news]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Player API]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Simple API]]></category>

		<guid isPermaLink="false">http://cluster006.ovh.net/~official/?p=5</guid>
		<description><![CDATA[It&#8217;s official: developers are first-class citizens here, starting now. Let&#8217;s cut to the chase: this blog is here to keep you posted about everything API going on at official.fm. It will be updated regularly with news, examples, stats, and spotlights on projects we find particularly inspiring. Our goal is to empower you, no matter which [...]]]></description>
			<content:encoded><![CDATA[<p>It&#8217;s official: developers are first-class citizens here, starting now.</p>
<p>Let&#8217;s cut to the chase: this blog is here to keep you posted about everything API going on at <a href="http://official.fm/">official.fm</a>. It will be updated regularly with news, examples, stats, and spotlights on projects we find particularly inspiring.</p>
<p>Our goal is to empower you, no matter which language or platform you choose.  Our job is to make your experience as smooth as possible, and to interface between you and our core development team so that your voice is heard. We love open source and we use open technologies everywhere in our products. Thus, all the API bindings are released under the <a href="http://en.wikipedia.org/wiki/BSD_licenses#3-clause_license_.28.22New_BSD_License.22_or_.22Modified_BSD_License.22.29">New BSD License</a>.</p>
<p>Here&#8217;s the current state of affairs.<br/></p>
<h3>The Simple API</h3>
<p>The <a href="http://official.fm/developers/simple_api">Simple API</a> has been around for some time, allowing you to search for tracks, playlists and retrieve user information. Until recently it was simply a RESTful service, but we&#8217;re creating bindings so that it&#8217;s dead easy to use from major programming languages.</p>
<p>To use the Simple API, <a href="http://official.fm/developers/manage">register your application</a> and simply use your API key as shown in the various bindings examples.</p>
<h4>Ruby</h4>
<pre escaped="true" lang="bash" line="1">gem install officialfm</pre>
<p>The officialfm gem was <a href="https://github.com/officialfm/officialfm-ruby">the first to be released</a>. It&#8217;s currently in version 0.0.2, but there&#8217;s no reason the interface should change. It fully supports the Simple API, has unit tests and a complete rdoc. For a complete example application using it, see <a href="https://github.com/officialfm/ofmtweet">ofmtweet</a>, a Sinatra web application that combines Twitter and the official.fm API to show the latest tracks that have been tweeted.</p>
<h4>PHP</h4>
<p>The PHP bindings, to be released very soon, are similar to the Ruby bindings. They also cover the Simple API and allow easy access to information about users, tracks and playlists.<br/></p>
<h3>Feedback</h3>
<p>We&#8217;re still learning about your applications and how to make our API the most convenient possible. We&#8217;d love to hear your ideas for improvement and your bug reports! All our APIs and bindings have <a href="https://github.com/officialfm">GitHub projects</a> than you can report issues against. We&#8217;ll get back to you as soon as possible.</p>
<p>To stay tuned about API and binding updates, make sure to <a href="http://twitter.com/ofmdev">follow us on twitter</a>. It&#8217;s also a good way to ask us short questions, as opposed to GitHub or our <a href="http://help.official.fm/">helpdesk</a>, more suited for long-winded bug reports.<br/></p>
<h3>What&#8217;s next?</h3>
<h4>Player Javascript API</h4>
<p>In addition to a full Simple API access, the Player Javascript API will allow you to create Flash or HTML official.fm players on-the-fly, from track or playlist IDs.</p>
<h4>Advanced API</h4>
<p>The Simple API was a first experiment with opening up our data to third-parties. But it was limited to read-only access. Our next step, the Advanced API, will allow write access, such as editing user details, voting, uploading tracks, and much more.</p>
<p>By the way, I&#8217;m Amos Wenger, Community Development Engineer at <a href="http://official.fm/">official.fm</a> and my job is to be 100% dedicated to the developer community around our API.</p>
<p>Glad to have you on board !</p>
]]></content:encoded>
			<wfw:commentRss>http://devblog.official.fm/news/5/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

