<?xml version="1.0" encoding="UTF-8"?>
<posts type="array">
  <post>
    <body>&lt;p&gt;Quick post to let you know about my latest hack: basic support for &lt;a href=&quot;http://en.wikipedia.org/wiki/OpenCL&quot;&gt;OpenCL&lt;/a&gt; on &lt;a href=&quot;http://macruby.org&quot;&gt;MacRuby&lt;/a&gt; and Snow Leopard.&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;it is my first Ruby C extension ever	&lt;li&gt;it is my first OpenCL approach ever	&lt;li&gt;it is my first MacRuby hack (ever)&lt;/ul&gt;
&lt;p&gt;With this in mind, don&amp;#8217;t expect real world usage from this code, nor that it will get merged into upstream: it was just written for fun!&lt;/p&gt;
&lt;p&gt;The MacRuby branch with the changes is located &lt;a href=&quot;http://github.com/rubenfonseca/macruby&quot;&gt;here&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;Example&lt;/h4&gt;
&lt;p&gt;The hello world on OpenCL is probably &amp;#8220;calculate each element&amp;#8217;s square on a given array&amp;#8221;. The code below shows how this can be done in MacRuby:&lt;/p&gt;
&lt;script src=&quot;http://gist.github.com/284779.js?file=test_macruby_opencl.rb&quot;&gt;&lt;/script&gt;&lt;p&gt;This code runs the same computation on all available OpenCL devices on your hardware. The results on my hardware (2 GPUs, 1CPU) are:&lt;/p&gt;
&lt;script src=&quot;http://gist.github.com/284792.js?file=gistfile1.txt&quot;&gt;&lt;/script&gt;&lt;p&gt;It was fun, and maybe it can inspire someone :) The OpenCL &lt;span class=&quot;caps&quot;&gt;API&lt;/span&gt; is kinda complex and I&amp;#8217;m not sure if there&amp;#8217;s a good way of making it Rubyish enough. Suggestions are welcome! Have fun :)&lt;/p&gt;</body>
    <excerpt nil="true"></excerpt>
    <id type="integer">127</id>
    <permalink>opencl-in-macruby-hack-not-very-useful</permalink>
    <published-at type="datetime">2010-01-23T12:39:00-08:00</published-at>
    <title>OpenCL in MacRuby (hack, not very useful)</title>
  </post>
  <post>
    <body>&lt;p&gt;HTML5 is here! Urray!&lt;/p&gt;
&lt;p&gt;I was tired of hearing about one of the new innovation in HTML5: the &lt;a href=&quot;http://dev.w3.org/html5/websockets/&quot;&gt;WebSocket &lt;span class=&quot;caps&quot;&gt;API&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;After reading the excelent blog post about &lt;a href=&quot;http://www.igvita.com/2009/12/22/ruby-websockets-tcp-for-the-browser/&quot;&gt;WebSockets and Ruby&lt;/a&gt; by Ilya Grigorik I got inspired by &lt;a href=&quot;http://rfw.posterous.com/musictweets-a-rediswebsocket-powered-experime&quot;&gt;this experiment&lt;/a&gt; which is a simple example of a &lt;em&gt;twitter-to-browser&lt;/em&gt; usage of websockets.&lt;/p&gt;
&lt;p&gt;Since the excelent &lt;a href=&quot;http://github.com/igrigorik/em-websocket&quot;&gt;em-websocket&lt;/a&gt; was available on github, I decided to write my own &amp;#8220;from twitter to the browser&amp;#8221; real time updates, with no polling.&lt;/p&gt;
&lt;p&gt;You can check the final result on &lt;a href=&quot;http://github.com/rubenfonseca/twitter-amqp-websocket-example&quot;&gt;my github repo&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;General overview&lt;/h3&gt;
&lt;p&gt;Twitter Stream &lt;span class=&quot;caps&quot;&gt;API&lt;/span&gt; &amp;#8594; Filter &amp;#8594; RabbitMQ &amp;#8594; &lt;span class=&quot;caps&quot;&gt;AMQP&lt;/span&gt; &amp;#8594; Eventmachine &amp;#8594; WebSocket &amp;#8594; HTML5 Brwser&lt;/p&gt;
&lt;p&gt;Too much buzzwords? Lets look at some code.&lt;/p&gt;
&lt;h3&gt;Filter&lt;/h3&gt;
&lt;p&gt;The filter is responsible for eating the &lt;a href=&quot;http://apiwiki.twitter.com/Streaming-API-Documentation&quot;&gt;Twitter Stream &lt;span class=&quot;caps&quot;&gt;API&lt;/span&gt;&lt;/a&gt; and puting the tweets on a queue (RabbitMQ in my case) using &lt;span class=&quot;caps&quot;&gt;AMQP&lt;/span&gt;:&lt;/p&gt;
&lt;script src=&quot;http://gist.github.com/264450.js?file=gistfile1.rb&quot;&gt;&lt;/script&gt;&lt;p&gt;Pretty easy right? Notice I am using a fanout exchange, which will allow me to broadcast the same message to all queues (clients) latter on.&lt;/p&gt;
&lt;h3&gt;Server&lt;/h3&gt;
&lt;p&gt;Now we just need to build a server that accepts websocket connections, and for each client deliver each message that arrives on the fanout exchange. The code will make this clear:&lt;/p&gt;
&lt;script src=&quot;http://gist.github.com/264453.js?file=gistfile1.rb&quot;&gt;&lt;/script&gt;&lt;p&gt;So simple, yet so awesome!&lt;/p&gt;
&lt;h3&gt;Client&lt;/h3&gt;
&lt;p&gt;The client just have to connect the websocket, and for each &lt;span class=&quot;caps&quot;&gt;JSON&lt;/span&gt; piece that arrives on the socket, present them on the screen:&lt;/p&gt;
&lt;script src=&quot;http://gist.github.com/264454.js?file=gistfile1.js&quot;&gt;&lt;/script&gt;&lt;p&gt;It seems we&amp;#8217;ve ended writing almost more JS than Ruby :P Note that I&amp;#8217;ve only tested this on Webkit nightly and latest Google Chrome beta for Mac.&lt;/p&gt;
&lt;p&gt;Overall it was a great and easy experience building this simple system, but it allowed me to realize how simple we can build scalable push systems with the WebSocket &lt;span class=&quot;caps&quot;&gt;API&lt;/span&gt;!&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;update&lt;/strong&gt;: seems like &lt;a href=&quot;http://twitter.com/igrigorik/status/7107086085&quot;&gt;Ilya Grigorik liked it&lt;/a&gt; :)&lt;/p&gt;</body>
    <excerpt nil="true"></excerpt>
    <id type="integer">126</id>
    <permalink>twitter-amqp-websocket-example-no-polling</permalink>
    <published-at type="datetime">2009-12-28T10:18:00-08:00</published-at>
    <title>Twitter AMQP WebSocket Example (no polling)</title>
  </post>
  <post>
    <body>&lt;p&gt;Are you tired of calling your friends and family at prices from the last century? Do you feel frustrated every time you have to top-up the credit of your mobile phone, just because you are obliged to? Do you hate the obvious portuguese &lt;em&gt;cartel&lt;/em&gt; around mobile operators?&lt;/p&gt;
&lt;p&gt;Well, fell no more! Enter the VoIP world!&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://www.betamax.com&quot;&gt;Betamax&lt;/a&gt; created &lt;a href=&quot;http://backsla.sh/betamax&quot;&gt;lots of&lt;/a&gt; providers specialized in VoIP. Although almost all of them offer free calls to Portuguese landline numbers, I never realized how competitive they were on the mobile side.&lt;/p&gt;
&lt;p&gt;So I dig a little, and found some pretty competitive Betamax VoIP providers:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;12voip.com &amp;#8211; 4.5 cent/min&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
	&lt;li&gt;voipraider.com &amp;#8211; 5.0 cent/min&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
	&lt;li&gt;webcalldirect.com &amp;#8211; 6.0 cent/min&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The best thing about these providers is&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;No required monthly payment&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
	&lt;li&gt;You can use your own phone number as Caller ID (so people still answer your calls).&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
	&lt;li&gt;They all support the &lt;span class=&quot;caps&quot;&gt;SIP&lt;/span&gt; protocol (great for non-windows users like me)&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
	&lt;li&gt;Same price for all the mobile operators (so you can jump the wall garden)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I hope that this information helps you lowering your phone bill. Spread the word, and maybe your mobile operator starts lowering the prices too!&lt;/p&gt;</body>
    <excerpt nil="true"></excerpt>
    <id type="integer">125</id>
    <permalink>cheap-calls-to-any-portuguese-mobile-network</permalink>
    <published-at type="datetime">2009-07-17T13:18:00-07:00</published-at>
    <title>Cheap calls to any Portuguese mobile network</title>
  </post>
  <post>
    <body>&lt;p&gt;I am a client of the &lt;a href=&quot;http://www.optimustag.pt&quot;&gt;optimus tag&lt;/a&gt; service (for English users, it&amp;#8217;s a phone plan that includes free calls for any other phone using the same network plan).&lt;/p&gt;
&lt;p&gt;Recently, I discovered they have a &lt;a href=&quot;http://www.optimustag.pt/Servicos/Webphone.jsp&quot;&gt;softphone like system&lt;/a&gt; called Webphone (Windows only), that allows you to place and receive calls, &lt;span class=&quot;caps&quot;&gt;SMS&lt;/span&gt;, &lt;span class=&quot;caps&quot;&gt;MMS&lt;/span&gt;, and other stuff, right from your computer.&lt;/p&gt;
&lt;p&gt;My first thought was &amp;#8220;this must use some kind of &lt;span class=&quot;caps&quot;&gt;SIP&lt;/span&gt; service&amp;#8221;. Since the &lt;span class=&quot;caps&quot;&gt;SIP&lt;/span&gt; settings are not posted anywhere on the internet, and I don&amp;#8217;t want to use Windows to use their client, I decided to dig deeper and try to find the &lt;span class=&quot;caps&quot;&gt;SIP&lt;/span&gt; configurations so it can work on any regular softphone.&lt;/p&gt;
&lt;p&gt;Although it was easier than I thought (&lt;a href=&quot;http://www.wireshark.org&quot;&gt;Wireshark&lt;/a&gt;, I love you), there is one serious limitation that I couldn&amp;#8217;t solve without hacking some open source code. Anyway here&amp;#8217;s the main settings:&lt;/p&gt;
&lt;h3&gt;Optimus Tag &lt;span class=&quot;caps&quot;&gt;SIP&lt;/span&gt; settings (to use with a &lt;span class=&quot;caps&quot;&gt;SIP&lt;/span&gt; softphone)&lt;/h3&gt;
&lt;ul&gt;
	&lt;li&gt;&lt;strong&gt;server address&lt;/strong&gt;: sip.optimus.pt&lt;/li&gt;
	&lt;li&gt;&lt;strong&gt;username&lt;/strong&gt;: 351 &lt;em&gt;your number&lt;/em&gt;@sip.optimus.pt&lt;/li&gt;
	&lt;li&gt;&lt;strong&gt;password&lt;/strong&gt;: your webphone password&lt;/li&gt;
	&lt;li&gt;&lt;strong&gt;&lt;span class=&quot;caps&quot;&gt;SIP&lt;/span&gt; proxy&lt;/strong&gt;: asbg.sip.optimus.pt&lt;/li&gt;
	&lt;li&gt;&lt;strong&gt;User Agent&lt;/strong&gt;: Optimus-SoftPhone/7.0.1.4124&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Now, the last item is the worst part. If you don&amp;#8217;t specify a &lt;strong&gt;User-Agent&lt;/strong&gt; that starts with &lt;code&gt;Optimus-SoftPhone&lt;/code&gt;, you&amp;#8217;ll receive a &amp;#8220;403 Forbidden User Agent&amp;#8221; message. I tried to find a &lt;span class=&quot;caps&quot;&gt;SIP&lt;/span&gt; softphone that allowed me to change the UserAgent but didn&amp;#8217;t found one (I didn&amp;#8217;t try hard).&lt;/p&gt;
&lt;p&gt;So I decided to take the &lt;a href=&quot;http://www.twinklephone.com&quot;&gt;Twinkle&lt;/a&gt; open source &lt;span class=&quot;caps&quot;&gt;SIP&lt;/span&gt; client, changed the hard coded User Agent, and got surprised when it worked flawlessly from the first time! I tried placing and receiving calls and it worked perfectly :)&lt;/p&gt;
&lt;p&gt;If you&amp;#8217;re interested on the trivial patch (I used Twinkle version 1.4.2) you can find it &lt;a href=&quot;http://gist.github.com/116644&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;If you know a &lt;span class=&quot;caps&quot;&gt;SIP&lt;/span&gt; client for OS X or Linux that allows me to change the User Agent, don&amp;#8217;t hesitate to comment bellow!&lt;/p&gt;</body>
    <excerpt nil="true"></excerpt>
    <id type="integer">124</id>
    <permalink>optimus-webphone-sip-settings</permalink>
    <published-at type="datetime">2009-05-23T07:41:00-07:00</published-at>
    <title>Optimus Webphone SIP settings</title>
  </post>
  <post>
    <body>&lt;p&gt;quick post to let you know my latest two mini-projects on &lt;a href=&quot;http://www.github.com&quot;&gt;github&lt;/a&gt;:&lt;/p&gt;
&lt;h3&gt;Ruby library to whit.me service &lt;span class=&quot;caps&quot;&gt;API&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;http://whit.me&quot;&gt;whit.me&lt;/a&gt; is a wonderful service to shorten URLs. They have a &lt;a href=&quot;http://www.whit.me/api/docs&quot;&gt;public &lt;span class=&quot;caps&quot;&gt;API&lt;/span&gt;&lt;/a&gt;, and I wrote this library that allows you to use the service in the middle of any Ruby script.&lt;/p&gt;
&lt;p&gt;The project is available &lt;a href=&quot;http://github.com/rubenfonseca/whitme/tree/master&quot;&gt;here&lt;/a&gt;. It is compatible with Ruby 1.9 and JRuby, and contains a full RSpec test suite.&lt;/p&gt;
&lt;h3&gt;newzbin &lt;span class=&quot;caps&quot;&gt;XMPP&lt;/span&gt; search agent&lt;/h3&gt;
&lt;p&gt;After spending some time learning &lt;a href=&quot;http://xmpp.org&quot;&gt;&lt;span class=&quot;caps&quot;&gt;XMPP&lt;/span&gt;&lt;/a&gt;, I decided to try it and build something useful. So I hacked a simple search agent for the &lt;a href=&quot;http://newzbin.com&quot;&gt;newzbin&lt;/a&gt; website to be used by me and my friends. It is poorly written, but it works.&lt;/p&gt;
&lt;p&gt;Maybe you can learn something from the simple example. In case you&amp;#8217;re  interested, the code is available &lt;a href=&quot;http://github.com/rubenfonseca/newzbin_xmpp/tree/master&quot;&gt;again on github&lt;/a&gt;. It uses the XMPP4R gem and CouchDB (overkill, I know).&lt;/p&gt;
&lt;p&gt;Feel free to comment on any of the code and send me suggestions on how to  improve it.&lt;/p&gt;</body>
    <excerpt nil="true"></excerpt>
    <id type="integer">123</id>
    <permalink>two-more-contributions-to-the-open-source-world</permalink>
    <published-at type="datetime">2009-05-22T14:22:00-07:00</published-at>
    <title>Two more contributions to the open source world</title>
  </post>
</posts>
