<?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>Caffeine Lab &#187; hacking</title>
	<atom:link href="http://erwan.jp/category/hacking/feed/" rel="self" type="application/rss+xml" />
	<link>http://erwan.jp</link>
	<description>Really tasty technologies</description>
	<lastBuildDate>Wed, 07 Jul 2010 10:58:18 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
<cloud domain='erwan.jp' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
		<item>
		<title>Asynchronous HTTP Client in Play Framework</title>
		<link>http://erwan.jp/2010/06/29/asynchronous-http-client-in-play-framework/</link>
		<comments>http://erwan.jp/2010/06/29/asynchronous-http-client-in-play-framework/#comments</comments>
		<pubDate>Tue, 29 Jun 2010 13:45:52 +0000</pubDate>
		<dc:creator>erwan</dc:creator>
				<category><![CDATA[hacking]]></category>
		<category><![CDATA[api]]></category>
		<category><![CDATA[play framework]]></category>

		<guid isPermaLink="false">http://erwan.jp/?p=490</guid>
		<description><![CDATA[I just finished migrating Play&#8217;s http client to Ning&#8217;s own asynchronous library. What does it mean? A lot. When you want to retrieve data from a different server, your web application behaves like a web client. Rather than serving a resource to a client, it requests one from a different server. For example, that&#8217;s what [...]]]></description>
			<content:encoded><![CDATA[<p>I just finished migrating Play&#8217;s http client to <a href="http://github.com/ning/async-http-client">Ning&#8217;s own asynchronous library</a>. What does it mean? A lot.</p>
<p>When you want to retrieve data from a different server, your web application behaves like a web client. Rather than serving a resource to a client, it requests one from a different server. For example, that&#8217;s what you would do if you want to interact with the Twitter API or if you want to build a web based feed reader.</p>
<h3>HTTP Client Calls in Play 1.0</h3>
<p>Play has a pretty cool http client library &#8211; pretty cool in the sense that it&#8217;s very simple to use compared to what you usually get in Java. I can get the content of a resource by calling:</p>
<p>[java]<br />
String body = WS.url(&#8220;http://erwan.jp/&#8221;).get().getString();<br />
[/java]</p>
<p>In the same fashion, I can do a post and retrieve the JSON result:</p>
<p>[java]<br />
JsonElement response = WS.url(&#8220;http://api.server.tld/new&#8221;).body(&#8220;content&#8221;).post().getJson();<br />
[/java]</p>
<p>As a comparison, <a href="http://hc.apache.org/httpclient-3.x/tutorial.html">see how it works</a> with Apache HttpClient.</p>
<p>However there&#8217;s a big flaw in this API: it can only be used synchronously. That means that your Java thread will be blocked until the response from the server is received. Depending on the server it could take several seconds, so it is a real issue. If you need to do 5 calls then work on the result, you will have to wait for the previous call to be done before you can launch the second. In Play you can use jobs to have your calls executed in a separate thread, but it&#8217;s a burder to have to create jobs for that and kind of defeats the purpose of using play.libs.WS.</p>
<h3>Play 1.1: Introducing Asynchronous Calls</h3>
<p>Since a commit I did last week, additional methods are available on the request object. Now you can do:</p>
<p>[java]<br />
Future&lt;HttpResponse&gt; response = WS.url(&#8220;http://erwan.jp/&#8221;).getAsync();<br />
[/java]</p>
<p>Now your call is done in a thread &#8211; you can manipulate your <a href="http://java.sun.com/javase/6/docs/api/java/util/concurrent/Future.html#method_summary">Future</a> object to test if the result is available, to cancel the call or to block the thread until the result is ready. Let&#8217;s say you need to do 3 API calls, and then use the results together. With the synchronous library you have to serialize the calls, but now you can do the calls in parallel:</p>
<p>[java]<br />
// Launch all three calls in parallel<br />
Future&lt;HttpResponse&gt; future1 = WS.url(&#8220;http://server/api/one&#8221;).getAsync();<br />
Future&lt;HttpResponse&gt; future2 = WS.url(&#8220;http://server/api/two&#8221;).getAsync();<br />
Future&lt;HttpResponse&gt; future3 = WS.url(&#8220;http://server/api/three&#8221;).getAsync();<br />
// Now that the calls are launched in separate threads, wait for the results<br />
Document xml1 = future1.get().getXml();<br />
Document xml2 = future2.get().getXml();<br />
Document xml3 = future3.get().getXml();<br />
[/java]</p>
<p>Launch the calls in parallel means a much quicker response, so that&#8217;s an improvement in the case we have several calls to do. But we are still blocking one of Play&#8217;s threads until the three calls are done.</p>
<h3>Avoid blocking Play&#8217;s threads</h3>
<p>Before we go on, it&#8217;s important to understand Play&#8217;s threads pool. It&#8217;s configurable but usually there is one IO thread and 2 execution threads. When the IO thread gets a request it passes it to one of the execution thread, the execution thread calculates it and passes it back to the IO thread that will queue it to serve it to the client who originated the request.</p>
<p>That means that the execution of the action on the controller will block one thread. So if you do a synchronous web service call from your action, you&#8217;ll block a precious thread for all the time you wait for the remote server to respond to your server. When all threads are blocked waiting for a result, other requests get queued. Your site&#8217;s response is slow, and your users are unhappy.</p>
<p>So here is how you can free the thread while you wait for the remote server to respond. The following code is an action, within a controller:</p>
<p>[java]<br />
﻿private static Future<HttpResponse> response;<br />
public static void mirrorFeed() throws Exception {<br />
    if (request.isNew) {<br />
        response = WS.url(&#8220;http://planet.playframework.org/feed&#8221;).getAsync();<br />
        waitFor(response);<br />
    } else {<br />
        renderXml(response.get().getXml());<br />
    }<br />
}<br />
[/java]</p>
<p>This can be tricky to understand at a first glance, so here is the process.</p>
<ul>
<li>Your action gets called a first time: request.isNew is true. An asynchronous HTTP call is made to the playframework.org server.</li>
<li>The &#8220;waitFor(Future<?>)&#8221; (static method on the Controller class) tells Play to wait until the response is received.
<li>When the answer is ready, Play will call the action again. This time, request.isNew is false. We know that the Future is ready so we can do a get() to retrieve the HttpResponse instance. Here we&#8217;re just serving it to the user, but you see how we could parse the feed to use just some information in our response.</li>
</ul>
<p>So here you go: the use of an asynchronous call prevents to block an execution thread, and the performance of your application will not be affected by the response time of the remote server.</p>
<h3>When you should still use a job</h3>
<p>While the waitFor trick prevents you from blocking a Play thread, your user still has to wait for the web service call to be back before he gets his response. In other words, your application may feel slow to the user.</p>
<p>When the information you need is general enough, for example when it comes from a public feed, it can still be a better approach to keep the information up-to-date using a job. At the time the user will fetch the information it will not be the most recent, but the page will be served to the user much quicker.</p>
<p>This is what I am doing for the Twitter box on <a href="http://planet.playframework.org">Planet Play</a>: I don&#8217;t pull it for each visitor at request time (that would be insane), but I have a Job refreshing the information every 5 minutes. Any page rendered will never get anything older than 5 minutes.</p>
<p>[java]<br />
@Every(&#8220;5mn&#8221;)<br />
public class TwitterJob extends Job {<br />
	public void doJob() {<br />
		try {<br />
			TwitterSearch.refresh(&#8220;playframework&#8221;);<br />
		} catch (UnsupportedEncodingException e) {<br />
			Logger.error(&#8220;Error refreshing Twitter search&#8221;);<br />
		}<br />
	}<br />
}<br />
[/java]</p>
<p>The information is then stored in cache and retrieved to render the front page.</p>
]]></content:encoded>
			<wfw:commentRss>http://erwan.jp/2010/06/29/asynchronous-http-client-in-play-framework/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>What I&#8217;ve been up to: Zenexity, Play</title>
		<link>http://erwan.jp/2009/11/30/what-ive-been-up-to-zenexity-play/</link>
		<comments>http://erwan.jp/2009/11/30/what-ive-been-up-to-zenexity-play/#comments</comments>
		<pubDate>Mon, 30 Nov 2009 11:01:20 +0000</pubDate>
		<dc:creator>erwan</dc:creator>
				<category><![CDATA[hacking]]></category>
		<category><![CDATA[life]]></category>
		<category><![CDATA[tech]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[play framework]]></category>

		<guid isPermaLink="false">http://erwan.jp/?p=469</guid>
		<description><![CDATA[Busy as I was, I realized I didn&#8217;t blog about my recent employment change. I left Yoono 2 months ago to join a company called Zenexity (site in French). It&#8217;s really cool because after Flock and Yoono that were very similar (consumer oriented/social mashup/Mozilla technologies), I get to work on really different stuff: more server-side, [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify;">Busy as I was, I realized I didn&#8217;t blog about my recent employment change. I left <a href="http://yoono.com/">Yoono</a> 2 months ago to join a company called <a href="http://www.zenexity.fr">Zenexity</a> (site in French). It&#8217;s really cool because after <a href="http://www.flock.com">Flock</a> and Yoono that were very similar (consumer oriented/social mashup/Mozilla technologies), I get to work on really different stuff: more server-side, and more business oriented. But still with a strong R&amp;D component, and it&#8217;s something that really motivated me to get on board with Zenexity: they&#8217;re independent because they earn their own money (e.g. don&#8217;t live on VC money) but still spend a lot of effort in R&amp;D projects. Projects for customers also are really state-of-the-art of the web.</p>
<p style="text-align: justify;">Specifically, they (I mean &#8220;we&#8221;) have an Open Source project called the <a href="http://www.playframework.org">Play! Framework</a>. It&#8217;s an MVC framework similar to <a href="http://www.djangoproject.com/">Django</a> or <a href="http://rubyonrails.org/">Ruby on Rails</a>, in Java. Within the Java world, I think it&#8217;s pretty disruptive. It contrasts from bloated stacks, and manages to provide simplicity and productivity to Java web development. Also, it <em>speaks the language of the web</em> by making it easy to create RESTful web apps, pretty URLs and web services.</p>
<p style="text-align: justify;">Here is a screencast I did last month for the 1.0 release.</p>
<p style="text-align: justify;"><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="400" height="300" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="allowfullscreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="src" value="http://vimeo.com/moogaloop.swf?clip_id=7087610&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=0&amp;show_portrait=0&amp;color=BCE569&amp;fullscreen=1" /><embed type="application/x-shockwave-flash" width="400" height="300" src="http://vimeo.com/moogaloop.swf?clip_id=7087610&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=0&amp;show_portrait=0&amp;color=BCE569&amp;fullscreen=1" allowscriptaccess="always" allowfullscreen="true"></embed></object></p>
<p><a href="http://vimeo.com/7087610">A web app  in 10 minutes using Play!</a> from <a href="http://vimeo.com/user2463720">zenexity</a> on <a href="http://vimeo.com">Vimeo</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://erwan.jp/2009/11/30/what-ive-been-up-to-zenexity-play/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Simple Tips to Build Scalable Websites</title>
		<link>http://erwan.jp/2009/07/01/scalable-websites/</link>
		<comments>http://erwan.jp/2009/07/01/scalable-websites/#comments</comments>
		<pubDate>Wed, 01 Jul 2009 15:13:17 +0000</pubDate>
		<dc:creator>erwan</dc:creator>
				<category><![CDATA[hacking]]></category>
		<category><![CDATA[tech]]></category>
		<category><![CDATA[amazon ec2]]></category>
		<category><![CDATA[cloud computing]]></category>
		<category><![CDATA[google app engine]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[scalability]]></category>
		<category><![CDATA[virtualization]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://erwan.jp/?p=418</guid>
		<description><![CDATA[A few days ago I&#8217;ve been invited to a launch party for a web product in Paris. While the product was nice and polished, it seems like the developers didn&#8217;t understand anything about scalability. They didn&#8217;t even understand my question when I asked them if the product could scale. It&#8217;s probably not a big deal [...]]]></description>
			<content:encoded><![CDATA[<p>A few days ago I&#8217;ve been invited to a launch party for a web product in Paris. While the product was nice and polished, it seems like the developers didn&#8217;t understand anything about scalability. They didn&#8217;t even understand my question when I asked them if the product could scale.</p>
<p>It&#8217;s probably not a big deal for them: they were presenting a CMS, so most of the time it will be installed for a limited user base. I guess most people will be happy to use it on a single server, so it&#8217;s probably OK for them not to be able to scale. However I noticed that while scalability is now a fairly solved problem, there are not that many articles explaining how to prepare to scalability on the web. So here I go. I will not try to replace a <a href="http://www.amazon.com/Building-Scalable-Web-Sites-applications/dp/0596102356/ref=sr_1_2?ie=UTF8&amp;s=books&amp;qid=1246458871&amp;sr=8-2">good book</a>, but just to give the very basics.</p>
<h3>What is scalability?</h3>
<p>It&#8217;s important to get that out of the way. Scalability is not performance: it&#8217;s not about making good use of CPU and bandwidth, and it&#8217;s not about having the page being loaded quickly in the user&#8217;s browser. It&#8217;s about being able to balance the load between several servers. So when the load increases (more users creating accounts, more visitors, more page views) you can add additional servers to balance the load. You don&#8217;t just throw in a server, you need to design your software to work on a cluster of servers.</p>
<p>An other point is that you will rarely create a cluster of machines from scratch: when you launch a new website you will have few users so few machines (one or two), and as your load increase you will increase the number of servers. You will have to scale different parts of your system one after the other.</p>
<h3>#1: the web front-end</h3>
<p>Most of the time you start with a front-end (PHP, Python, Ruby, Java&#8230;) and a data layer (MySQL, PostgreSQL, CouchDB&#8230;). As your load increase, the front-end will be the first to break. Of course server-side caching will help, but at some point you will need several front-end servers.</p>
<p>The key for that is to ensure you don&#8217;t store any data on the front-end. The problem sometimes arise with sessions: a lot of PHP libraries store session information locally on the server, and that prevents from balancing the load. The idea is that in a session a user may hit a server for a given page, then an other for the next page. If the session is only accessible to the first server, you&#8217;re screwed. You want it to be somewhere else. That can be in the data layer or in a special sessions server. If you write a Facebook app you don&#8217;t need to care, because Facebook takes care of the session.</p>
<p>Now can have as many front-ends as we want, but we have a unique database server.</p>
<h3>#2: the read operations on the database</h3>
<p>Most applications will have many more reads than writes. For example in a blogging software, each visitor will trigger a read on the database (OK, not <em>each</em> visitor if there is a good cache), but writes only occur when the author writes a new post or someone leave a comment.</p>
<p>That&#8217;s good, because it&#8217;s much easier to scale reads than writes. Just make sure that in your code you have different settings for reads and writes. They can point to the same database at launch time, but when the time comes you can separate those. Writes will go to your &#8220;main&#8221; database, and reads will go to a copy. There are other approaches, but for example MySQL offers <a href="http://dev.mysql.com/doc/refman/5.0/en/replication.html">replications</a> features. Once set up, the slaves will stay in sync with the master. You can have as many slaves as you need.</p>
<p>OK &#8211; several front-ends, several read-only databases, but still one master database for writes. If your applications has few reads it may be fine with a beefy database server, (and some major websites just have one master database), but if you have a lot of writes (highly social applications like Facebook or Twitter) you may want to continue the scaling process.</p>
<h3>#3: the write database</h3>
<p>Now we want to have several databases where we can write to. Obviously, we have to be careful not to introduce inconsistencies in the process. So having an old version of a blog post on a server and the new version on an other one is not great; what if some users see an old version of your post and others see the most recent one ?</p>
<p>There are various strategies to divide data in a safe and consistent way, including:</p>
<ul>
<li>Depending on the userid (or blogid, or whatever makes sense in your application), put the data on one server on an other. For example, all users with an even id go to server1 and all users with an odd id go to server2. Hint: make sure your algorithm lets you add more servers later, which is not the case with my example where you will be stuck at 2 servers <img src='http://erwan.jp/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </li>
<li>Put some tables on a server, some others on an other. It doesn&#8217;t help you when a table is growing too much, but it can be combined with the previous point.</li>
</ul>
<h3>Conclusion</h3>
<p>Here you go, the basics for building a scalable website. That&#8217;s not all you have to do, if your website continues growing you will face more problems such as having to scale your network. I&#8217;m not talking about outgoing bandwidth but communication between your servers (front-end and data layers). But if your code is efficient, those simple recommendation will get you to a server that can handle a fairly big load. I really recommend <a href="http://www.amazon.com/Building-Scalable-Web-Sites-applications/dp/0596102356/ref=sr_1_2?ie=UTF8&amp;s=books&amp;qid=1246458871&amp;sr=8-2">Building Scalable Websites</a>, from O&#8217;Reilly if you want to know more.</p>
<h3>FAQ</h3>
<p><strong><em>Q: Language X doesn&#8217;t scale, but language Y does!</em></strong></p>
<p>A: Bullshit. It&#8217;s not the language that scales, it&#8217;s your code. Some languages may not perform as good as others, so you will have to add boxes more often but the way you scale is still the same.</p>
<p><strong><em>Q: What about cloud computing? Virtualization? All these fancy buzzwords?</em></strong></p>
<p>Virtualization means you run on virtual machines rather than on physical ones. The benefit is that you can easily add or remove machines. For example, using <a href="http://aws.amazon.com/ec2/">Amazon EC2</a> you can add as many machines as you want in a few minutes, and then remove them in no more time. With a classical hosting company, you need to make a phone call, ask for the machines and you get them in maybe one week. They&#8217;ll charge you for the set-up too, and if you no longer want it you still have to pay for a full term. So cloud computing offers are generally more flexible.</p>
<p><em><strong>Q: Does Google App Engine make it easier to scale?</strong></em></p>
<p>In short, yes. By not letting you access the machines, Google App Engine constrain you into writing scalable code. You also don&#8217;t have to request new machines when you need them or release when you no longer need them; you just pay what you use depending on the load of your application.</p>
<p>I am a big fan on Google App Engine but be careful, since it&#8217;s programmed in a particular way it&#8217;s not easy to move your project out of it. You may feel locked in after you project started.</p>
]]></content:encoded>
			<wfw:commentRss>http://erwan.jp/2009/07/01/scalable-websites/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Thoughts on Google App Engine</title>
		<link>http://erwan.jp/2009/05/26/google-app-engine/</link>
		<comments>http://erwan.jp/2009/05/26/google-app-engine/#comments</comments>
		<pubDate>Tue, 26 May 2009 15:33:58 +0000</pubDate>
		<dc:creator>erwan</dc:creator>
				<category><![CDATA[hacking]]></category>
		<category><![CDATA[tech]]></category>
		<category><![CDATA[amazons3]]></category>
		<category><![CDATA[appengine]]></category>
		<category><![CDATA[google]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://erwan.jp/?p=405</guid>
		<description><![CDATA[I&#8217;ve been playing with Google App Engine recently. It&#8217;s actually pretty cool, to the point that I&#8217;m almost ashamed to have ignored it when it was released. I kind of felt like it would be too restrictive with just Python, just their own database and so on. But so far, I like it: It&#8217;s only [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been playing with <a href="http://appengine.google.com/">Google App Engine</a> recently. It&#8217;s actually pretty cool, to the point that I&#8217;m almost ashamed to have ignored it when it was released. I kind of felt like it would be too restrictive with just Python, just their own database and so on.</p>
<p>But so far, I like it:</p>
<ul>
<li>It&#8217;s only Python (or Java), but you can do pretty much anything you would do in a non-App Engine Python project. You can load pure pythonic third party libraries by just including them in your project.</li>
<li>The free quotas are really big. It&#8217;s enough for a  hobby project, and if it becomes successful enough to hit the ceiling you should be able to figure out a way to monetize it to pay your Google bill.</li>
<li>You can use your own domain name even with a free account</li>
<li>There is no SQL, but Google&#8217;s BigTable seems to be good enough. Heck, that&#8217;s what they use for most of their products!</li>
</ul>
<p>And you get all the App Engine specific goodness: easy authentication with Google Accounts, free hosting with huge quotas, and most importantly <strong>easy scalability</strong> on Google&#8217;s infrastructure&#8230; Having to call your hosting company to add new servers is a pain in the ass (and in the wallet), having to create and delete instances on <a href="http://aws.amazon.com/s3/">Amazon S3</a> is a much better, but not having to think about it at all is just pure joy.</p>
]]></content:encoded>
			<wfw:commentRss>http://erwan.jp/2009/05/26/google-app-engine/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Thank you, AMO!</title>
		<link>http://erwan.jp/2009/04/15/thank-you-amo/</link>
		<comments>http://erwan.jp/2009/04/15/thank-you-amo/#comments</comments>
		<pubDate>Wed, 15 Apr 2009 09:58:03 +0000</pubDate>
		<dc:creator>erwan</dc:creator>
				<category><![CDATA[browsers]]></category>
		<category><![CDATA[hacking]]></category>
		<category><![CDATA[addon]]></category>
		<category><![CDATA[amo]]></category>
		<category><![CDATA[extension]]></category>
		<category><![CDATA[firefox]]></category>
		<category><![CDATA[moji]]></category>
		<category><![CDATA[vgspy]]></category>
		<category><![CDATA[video games]]></category>

		<guid isPermaLink="false">http://erwan.jp/?p=393</guid>
		<description><![CDATA[The website addons.mozilla.org recently changed the rule for sandboxed addons: you no longer need to register and login to install one. That was a big issue because the review process is a bit heavy, and a lot of add-ons were stuck in that Limbo of Firefox. The difference for my recent sandboxed Video Games Spy [...]]]></description>
			<content:encoded><![CDATA[<p>The website addons.mozilla.org recently changed the rule for sandboxed addons: you no longer need to register and login to install one. That was a big issue because the review process is a bit heavy, and a lot of add-ons were stuck in that Limbo of Firefox.</p>
<p>The difference for my recent sandboxed <a title="AMO" href="https://addons.mozilla.org/en-US/firefox/addon/8027">Video Games Spy</a> (a sidebar to get aggregated info about games) is huge. It went from 0-ish to more than 50 downloads a day! It&#8217;s still not a lot, especially compared the thousand a day <a href="https://addons.mozilla.org/en-US/firefox/addon/145">Moji</a> is still getting, but it shows there is <em>some</em> interest for the add-on.</p>
<div id="attachment_161" class="wp-caption aligncenter" style="width: 291px"><a href="https://addons.mozilla.org/en-US/firefox/addon/8027"><img class="size-full wp-image-161" title="Video Games Spy" src="http://erwan.jp/wp-content/uploads/2008/07/vgspy1.png" alt="Video Games Spy" width="281" height="532" /></a><p class="wp-caption-text">Super Mario Galaxy!</p></div>
]]></content:encoded>
			<wfw:commentRss>http://erwan.jp/2009/04/15/thank-you-amo/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Should Firefox toolbars get &#8220;Text besides icons&#8221;?</title>
		<link>http://erwan.jp/2008/12/01/should-firefox-toolbars-get-text-besides-icons/</link>
		<comments>http://erwan.jp/2008/12/01/should-firefox-toolbars-get-text-besides-icons/#comments</comments>
		<pubDate>Tue, 02 Dec 2008 00:18:55 +0000</pubDate>
		<dc:creator>erwan</dc:creator>
				<category><![CDATA[browsers]]></category>
		<category><![CDATA[hacking]]></category>
		<category><![CDATA[tech]]></category>

		<guid isPermaLink="false">http://erwan.jp/?p=289</guid>
		<description><![CDATA[This is a feature that I really love in Gnome (Linux), and that I wish Firefox had it too. That would make it even more integrated into the Gnome desktop. It is about the options for text and icons on toolbars. Currently, Firefox proposes three options: Icons only (the default) Icons and text Text only [...]]]></description>
			<content:encoded><![CDATA[<p>This is a feature that I really love in Gnome (Linux), and that I wish Firefox had it too. That would make it even more integrated into the Gnome desktop.</p>
<p>It is about the options for text and icons on toolbars. Currently, Firefox proposes three options:</p>
<ul>
<li>Icons only (the default)</li>
<li>Icons and text</li>
<li>Text only</li>
</ul>
<h3>Gnome and Toolbars</h3>
<p>Gnome, on the other hand, has one more option: text <em>besides</em> icons, while the icons and text option of Firefox is called text <em>below</em> icons. My preference goes to text besides icons. Let&#8217;s see how each option looks on Epiphany, Gnome&#8217;s own web browser:</p>
<div id="attachment_292" class="wp-caption aligncenter" style="width: 510px"><a href="http://erwan.jp/wp-content/uploads/2008/12/toolbars.png"><img class="size-full wp-image-292" title="toolbars" src="http://erwan.jp/wp-content/uploads/2008/12/toolbars.png" alt="" width="500" height="322" /></a><p class="wp-caption-text">Gnome&#39;s different toolbar options on Epiphany</p></div>
<p>From top to bottom: text below icons, text besides icons, icons only and text only. As you can see, in the &#8220;text besides icons&#8221; option, not all icons have a label: only the most important ones. It&#8217;s not unlike IE6, so IE6 was not completely garbage. Yes it has a shitty rendering engine, no tabs and no popup blocker, but it has text besides icons <img src='http://erwan.jp/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> .</p>
<p>The advantages of &#8220;text besides icons&#8221; are multiple, not limited to teaching the meaning of the buttons but also:</p>
<ul>
<li>Create a hierarchy between important buttons and secondary buttons (for example, &#8220;back&#8221; is more important than &#8220;forward&#8221;</li>
<li>Give more real estate to important buttons, making them easier to click</li>
</ul>
<p>Those two goals have been solved for Mac and Windows for the back and forward buttons only; however on Linux back and forward are still given the same importance.</p>
<p>I believe the patch would be simple enough, it is just one entry to add to the options list and and few CSS rules to apply in this case (see below).</p>
<h3>The Cherry on the Cake</h3>
<p>If Firefox get that feature, the cherry on the cake would be to have an additional option for Linux users: &#8220;System Default&#8221;. Using this option, Firefox will just use whatever the user (or the distribution) set from the preferences. It would be tempting to get rid of the option altogether and set everyone to the system default, but I guess that wouldn&#8217;t please KDE users who don&#8217;t have access to this preference.</p>
<p>That requires (1) to read the gconf option for toolbars and (2) to listen for the change in order to refresh the UI as soon as the user changes the system preference.</p>
<p>It seems like the Mozilla codebase already have some code related to gconf, in <a href="http://mxr.mozilla.org/firefox/source/browser/components/shell/src/nsGNOMEShellService.cpp">nsGNOMEShellService.cpp</a> to set Firefox as the default browser.</p>
<h3>Get it Today</h3>
<p>You can easily get the text besides icons on your Firefox, by adding the following lines to your <a href="http://www.mozilla.org/unix/customizing.html">userChrome.css</a>:</p>
<pre>/* Text besides icons */
toolbar:not([mode=full]) #back-button,
toolbar:not([mode=full]) #home-button {
   -moz-box-orient: horizontal !important;
}

#back-button .toolbarbutton-text,
#home-button .toolbarbutton-text {
   display: block !important;
}</pre>
<p>You will have to set your toolbars to &#8220;icons only&#8221;.</p>
<div id="attachment_294" class="wp-caption aligncenter" style="width: 310px"><a href="http://erwan.jp/wp-content/uploads/2008/12/text-besides-icons.png"><img class="size-medium wp-image-294" title="Text Besides Icons in Firefox" src="http://erwan.jp/wp-content/uploads/2008/12/text-besides-icons-300x206.png" alt="Text Besides Icons in Firefox" width="300" height="206" /></a><p class="wp-caption-text">Text Besides Icons in Firefox</p></div>
]]></content:encoded>
			<wfw:commentRss>http://erwan.jp/2008/12/01/should-firefox-toolbars-get-text-besides-icons/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>France2 News for XBMC and Plex</title>
		<link>http://erwan.jp/2008/10/26/france2-news-for-xbmc-and-plex/</link>
		<comments>http://erwan.jp/2008/10/26/france2-news-for-xbmc-and-plex/#comments</comments>
		<pubDate>Sun, 26 Oct 2008 07:06:08 +0000</pubDate>
		<dc:creator>erwan</dc:creator>
				<category><![CDATA[hacking]]></category>

		<guid isPermaLink="false">http://erwan.jp/?p=265</guid>
		<description><![CDATA[I just released a plugin for the media center softwares XBMC and Plex to watch the France2 news from your couch. Details in French here. Je viens de publier un plugin pour les media center XBMC et Plex permettant de regarder le journal de France2 depuis le canapé. Détails ici.]]></description>
			<content:encoded><![CDATA[<p>I just released a plugin for the media center softwares <a href="http://xbmc.org">XBMC</a> and <a href="http://plexapp.com">Plex</a> to watch the <a href="http://france2.fr/">France2</a> news from your couch. <a href="http://erwan.jp/xbmcfrance2">Details in </a><a href="http://erwan.jp/xbmcfrance2">French here</a>.</p>
<p>Je viens de publier un plugin pour les media center  <a href="http://xbmc.org">XBMC</a> et <a href="http://plexapp.com">Plex</a> permettant de regarder le journal de <a href="http://france2.fr/">France2</a> depuis le canapé. <a href="http://erwan.jp/xbmcfrance2">Détails ici</a>.</p>
<p><a href="http://erwan.jp/wp-content/uploads/2008/10/xbmcfrance2.jpg"><img class="aligncenter size-medium wp-image-253" title="xbmcfrance2" src="http://erwan.jp/wp-content/uploads/2008/10/xbmcfrance2-300x168.jpg" alt="" width="300" height="168" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://erwan.jp/2008/10/26/france2-news-for-xbmc-and-plex/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Getting more media sites in Flock&#8217;s mediabar, with Media RSS</title>
		<link>http://erwan.jp/2008/07/17/flock-media-rss/</link>
		<comments>http://erwan.jp/2008/07/17/flock-media-rss/#comments</comments>
		<pubDate>Thu, 17 Jul 2008 22:15:39 +0000</pubDate>
		<dc:creator>erwan</dc:creator>
				<category><![CDATA[flock]]></category>
		<category><![CDATA[hacking]]></category>
		<category><![CDATA[browsers]]></category>
		<category><![CDATA[feed]]></category>
		<category><![CDATA[mrss]]></category>
		<category><![CDATA[rss]]></category>

		<guid isPermaLink="false">http://erwan.jp/?p=158</guid>
		<description><![CDATA[Flock 2.0 is on its way to the final release, and many of you have noticed that besides all the Firefox 3 goodness, the experience is pretty much the same as in Flock 1.2. Well, it&#8217;s pretty much the same, not exactly the same. One discreet feature is the recognition of Media RSS feeds for [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.flock.com/beta/download/">Flock 2.0</a> is on its way to the final release, and many of you have noticed that besides all the Firefox 3 goodness, the experience is pretty much the same as in Flock 1.2. Well, it&#8217;s <em>pretty much</em> the same, not <em>exactly</em> the same. One discreet feature is the recognition of <a href="http://search.yahoo.com/mrss">Media RSS</a> feeds for the mediabar.</p>
<div id="attachment_184" class="wp-caption aligncenter" style="width: 310px"><a href="http://erwan.jp/wp-content/uploads/2008/07/lemonde.png"><img class="size-medium wp-image-184" title="Media RSS on lemonde.fr" src="http://erwan.jp/wp-content/uploads/2008/07/lemonde-300x118.png" alt="" width="300" height="118" /></a><p class="wp-caption-text">Media RSS on the French website lemonde.fr</p></div>
<p>While Flock has been doing a lot of service-specific integration, it has never been the intent for the long term. We do service-specific because we have no choice, but we are eager to support open standards (and promote them) as they get available. Our blog editor had support for <a href="http://www.xmlrpc.com/metaWeblogApi">MetaWeblog</a> and <a href="http://www.atomenabled.org/developers/protocol/">ATOM Publishing Protocol</a> from the beginning, and now it&#8217;s the turn of the mediabar to get some open standard love.</p>
<h3>Media Discovery</h3>
<p>What does it mean for you, the user? Well, it means that besides the 7 supported services, you can consume content from any website that advertise an RSS feed. You can try it, in <a href="http://www.flock.com/beta/download/">Flock 2.0beta2</a>. Here is a selection of websites:</p>
<ul>
<li><a href="http://icanhascheezburger.com/">I can has cheezburger</a></li>
<li><a href="http://smugmug.com/">Smugmug</a></li>
<li><a href="http://www.lemonde.fr/">Le Monde</a> (if you can read French)</li>
<li>And many more! There are so many sites I can&#8217;t keep track of all of them.</li>
</ul>
<h3>Custom Search</h3>
<p>So when you visit a page with a media rss feed, you can see it in the mediabar and subscribe to it. It gives a experience similar to Flock&#8217;s news reader, but with an experience more tailored to media content (images and videos). But there is more. It&#8217;s really an advanced feature, but if a website provides a media rss feed for a given search result, you can use that to add search in the mediabar.</p>
<p><strong>Example</strong>: <a href="http://www.hulu.com">Hulu</a><br />
Hulu is a website with TV content from the major networks (FOX, NBS, PBS&#8230;) with limited advertisement. You can get search for it in Flock&#8217;s mediabar, again that&#8217;s for Flock 2.0beta2:</p>
<ol>
<li>Open the URL &#8220;about:config&#8221;</li>
<li>Search for &#8220;rssSearch&#8221;</li>
<li>Change the value of flock.photo.rssSearch to:<br />
<code>[{"hulu":{"id":"hulu","title":"Hulu Videos","url":"http://www.hulu.com/feed/search/%s","icon":"http://www.hulu.com/images/hulu.ico"}}]</code></li>
<li>Open the mediabar</li>
</ol>
<p>Voilà! You can now search for your favorite TV shows in the mediabar.</p>
<div id="attachment_159" class="wp-caption alignnone" style="width: 510px"><a href="http://erwan.jp/wp-content/uploads/2008/07/homer.png"><img class="size-full wp-image-159" title="Homer Simpsons on Hulu.com" src="http://erwan.jp/wp-content/uploads/2008/07/homer.png" alt="" width="500" height="199" /></a><p class="wp-caption-text">Search for &quot;Homer&quot; on Hulu.com</p></div>
<h3>Get support for your site</h3>
<p>If you have a feed with images or videos on your website/blog, you can get it in Flock&#8217;s mediabar pretty easily.</p>
<p>The easiest way is to pipe your feed through <a href="http://www.feedburner.com">Feedburner</a>, making sure you enable their <a href="http://blogs.feedburner.com/feedburner/archives/000812.html">SmartCast</a> feature. Feedburner will nicely add the required markup to your feed (and they have a lot of other features too).</p>
<p>If you&#8217;re tech savvy and you&#8217;d rather do it your way, there is <a href="http://developer.flock.com/wiki/Media_RSS">some documentation</a> that I wrote for that.</p>
]]></content:encoded>
			<wfw:commentRss>http://erwan.jp/2008/07/17/flock-media-rss/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Week-End Hacking</title>
		<link>http://erwan.jp/2008/07/06/week-end-hacking/</link>
		<comments>http://erwan.jp/2008/07/06/week-end-hacking/#comments</comments>
		<pubDate>Mon, 07 Jul 2008 07:07:20 +0000</pubDate>
		<dc:creator>erwan</dc:creator>
				<category><![CDATA[flock]]></category>
		<category><![CDATA[hacking]]></category>

		<guid isPermaLink="false">http://erwan.jp/?p=155</guid>
		<description><![CDATA[I&#8217;ve spent a day hacking on a new extension. It&#8217;s for gamers (like me!) who like to check reviews about new games before they buy. I&#8217;ve put Amazon customer reviews score, the mandatory Metacritic score. More to come &#8211; let me know what you think should be there. Also, when you visit Metacritic, IGN or [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve spent a day hacking on a new extension. It&#8217;s for gamers (like me!) who like to check reviews about new games before they buy. I&#8217;ve put Amazon customer reviews score, the mandatory Metacritic score. More to come &#8211; let me know what you think should be there.</p>
<p>Also, when you visit Metacritic, IGN or Gamespot, games get detected, so all you need when you&#8217;re viewing a page about a game is to click on the famicom icon, and the info will open on the left. Pretty cool, eh?</p>
<p>It&#8217;s in <a href="https://addons.mozilla.org/en-US/firefox/addon/8027">AMO sandbox</a> now, so if you don&#8217;t have an AMO account with Sandbox access you can also <a href="http://erwan.jp/vgspy/">download it here</a>. And if you like it, don&#8217;t forget to write a review on AMO, so it can get out of the sandbox!</p>
<div id="attachment_157" class="wp-caption aligncenter" style="width: 304px"><a href="http://erwan.jp/wp-content/uploads/2008/07/vgspy-flock.png"><img class="size-medium wp-image-157" title="VGSpy" src="http://erwan.jp/wp-content/uploads/2008/07/vgspy-flock-294x300.png" alt="Video Games Spy" width="294" height="300" /></a><p class="wp-caption-text">&quot;Boom Blox&quot; in VGSpy</p></div>
]]></content:encoded>
			<wfw:commentRss>http://erwan.jp/2008/07/06/week-end-hacking/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
