<?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>César&#039;s geek-side &#187; crodas</title>
	<atom:link href="http://crodas.org/author/admin/feed" rel="self" type="application/rss+xml" />
	<link>http://crodas.org</link>
	<description>bits comming in and out.</description>
	<lastBuildDate>Sun, 24 Oct 2010 08:32:55 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>HTML5 (and Flash) MP4 videos</title>
		<link>http://crodas.org/html5-and-flash-mp4-videos.php</link>
		<comments>http://crodas.org/html5-and-flash-mp4-videos.php#comments</comments>
		<pubDate>Sun, 24 Oct 2010 08:11:49 +0000</pubDate>
		<dc:creator>crodas</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://crodas.org/?p=126</guid>
		<description><![CDATA[Long time no write!, I&#8217;ve been very busy last year hacking on some cool projects (most of them are hosted on my Github account) and (tele) working for some cool clients (Opendrive, Meneame among others) and the best, I have a brand new job. Now I finally found some little time and of course, something [...]]]></description>
			<content:encoded><![CDATA[<p>Long time no write!, I&#8217;ve been very busy last year hacking on some cool projects (most of them are hosted on my <a href="http://github.com/crodas">Github</a> account) and (tele) working for some cool clients (<a href="http://opendrive.com/">Opendrive</a>, <a href="http://meneame.net/">Meneame</a> among others) and the best, I have a <a href="http://www.plumwillow.com/">brand new job</a>. Now I finally found some little time and of course, something interesting to write about in this blog.</p>
<p>Last week I was quite busy building an online video player for one customer, it was a nice challenge, and I thought it was pretty easy task. In this post I will describe what I&#8217;ve done to get it working from the perspective of the backend (from the frontend is not a big deal though, you only need some jquery player for HTML5 player with fallback to flash)</p>
<p>The first thing that I had to do was a super simple queue to process video conversions (FIFO),  I didn&#8217;t want to suck up all the CPU from the servers, right now it is converting 10 videos at a time. For this task I created a tiny webserver using NodeJS, which is pretty awesome btw to create child processes, and the best it&#8217;s a single process (no forks, no locks, no threads).  Because the queue has its interface through webserver I can create task and check their status with a simple <a href="http://en.wikipedia.org/wiki/Representational_State_Transfer">REST interface</a> (which is pretty neat).</p>
<p>The skeleton was built, now I had to Google about <a href="http://www.ffmpeg.org/">ffmpeg</a> and the right parameters to get a mp4 version of the current video, and this video should work for HTML5 (Chrome, and Safary I think) and Flash (JWPlayer &#8212; Firefox, IE, etc).</p>
<p>After hours of Googling and testing I ended up using these parameters:</p>
<blockquote><p><em>ffmpeg -i &lt;input&gt; -vcodec libx264 -vpre -vpre &#8220;&gt;-vpre &#8220;&gt;hq -vpre ipod640 -b 250k -bt 50k -acodec libfaac -ab 56k -ac 2 -s 480&#215;320 -g &lt;output&gt;</em></p></blockquote>
<p>That command was perfect for our use case, fast and with good quality.</p>
<p>Nonetheless I found some issues,  for instance the flash player wasn&#8217;t able to play the video until it was totally downloaded, which was pretty annoying for large videos and/or slow connections. For my surprise it was working perfectly fine on HTML5 (with last Chrome for OpenSuse), then watching Apache&#8217;s log I found out that Chrome was doing a couple of partial requests, the first one to get the meta-data of the video, and the other to get the video itself.</p>
<p>After tons of hours researching about how to move  meta-data to the beginning of the file, and ideally it should be done only with ffmpeg, but I couldn&#8217;t find it. (if you know how to do it, ping me pls)</p>
<p>Thank goodness I found a tiny program that does that pretty quickly, its name is <a href="http://gpac.sourceforge.net/doc_mp4box.php">MP4Box</a> which is part of <a href="http://gpac.sourceforge.net/">GPAC</a>.</p>
<blockquote><p><em>MP4Box -inter 0.5 &lt;output&gt;</em></p></blockquote>
<p>After these unexpected issues, everything is working as a charm <img src='http://crodas.org/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p>PD: Fixed some typos (it is 5am here)</p>]]></content:encoded>
			<wfw:commentRss>http://crodas.org/html5-and-flash-mp4-videos.php/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>ActiveMongo</title>
		<link>http://crodas.org/activemongo.php</link>
		<comments>http://crodas.org/activemongo.php#comments</comments>
		<pubDate>Sat, 27 Feb 2010 05:47:19 +0000</pubDate>
		<dc:creator>crodas</dc:creator>
				<category><![CDATA[Opensource]]></category>
		<category><![CDATA[ActiveMongo]]></category>
		<category><![CDATA[MongoDB]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://crodas.org/?p=99</guid>
		<description><![CDATA[After awhile without blogging, I was quite busy with work and some personal projects. Well, I created my first PECL Package (and therefore I have my @php.net mail) that I built in order to accomplish my personal goal that is already working on my sandbox (I&#8217;ll cover this later in this blog).
This time I will [...]]]></description>
			<content:encoded><![CDATA[<p>After awhile without blogging, I was quite busy with work and some personal projects. Well, I created my first <a title="PECL Package" href="http://pecl.php.net/package/TextCat" target="_blank">PECL Package</a> (and therefore I have my @php.net mail) that I built in order to accomplish <a href="http://crodas.org/weird-but-cool-pageranks-usage.php">my personal goal</a> that is already working on my sandbox (I&#8217;ll cover this later in this blog).</p>
<p>This time I will talk about <a href="http://www.mongodb.org/" target="_blank">MongoDB</a>, and my simple yet efficient <a href="http://github.com/crodas/ActiveMongo" target="_blank">ActiveRecord class </a>that I wrote in less than a week, in order to make even easier use <a href="http://www.mongodb.org/" target="_blank">MongoDB</a> from PHP.</p>
<p>If you already have any experience with MongoDB, you might be wondering <em>why did you create it? MongoDB is already very simple.</em> That&#8217;s right, but I want to make even easier and amicable, so I focused in these things:</p>
<ul>
<li>Keep it simple stupid.</li>
<li>Easy iteration.</li>
<li>Optimized Updates.</li>
<li>MongoDB is already good for queries, don&#8217;t wrap it</li>
</ul>
<p>Of course, you can do all this with just MongoDB, but it&#8217;s a bit tricky, especially the Optimized updates (just updating what had changed).</p>
<p>ActiveMongo usually would look like this,</p>
<pre>&lt;?php

ActiveMongo::connect("testing_db", "localhost");

class Users extends ActiveMongo
{
    /* Define our User's document properties, */
    /* just to make our code readable, not really needed */
    public $username;
    public $password;
    public $country;
    public $address;
}

$user = new User;
$user-&gt;username = "crodas";
$user-&gt;password = "password";
$user-&gt;country  = "Paraguay";
$user-&gt;address[0] = array('address1' =&gt; 'foobar', 'city' =&gt; 'Asuncion', 'zip' =&gt; 'xxxx');
/* Insert */
$user-&gt;save();
$user-&gt;password = "another_password";
/* Update, only the password would be updated. */
$user-&gt;save();
?&gt;</pre>
<p>Until here, there is nothing new, except that for Updates, instead of put the whole object back, ActiveMongo will perform a diff between the current result and the object&#8217;s property, and it will generate a special document using $unset, $set that is going to be sent to Mongo. Again, this operation is very simple, but it might be hard to detect, look at the next example:</p>
<pre>&lt;?php
/* .... */
$user-&gt;address[0] ['address1'] = 'Bar';
unset($user-&gt;address[0]['zip']);
$user-&gt;address[1] = array('address1' =&gt; 'another address', 'city' =&gt; 'Asuncion');
$user-&gt;save();
?&gt;</pre>
<p>In this case, ActiveMongo Instead of send the whole User object, just the following object will be sent to Mongo:</p>
<pre>{
'$set' : [
     {'address.0.address1' : 'Bar'},
     {'address.1': {'address1' : 'another address', 'city' : 'Asuncion'}}
    ],
'$unset' : [{'address.0.zip' : 1}]
}</pre>
<p>That is quite hard to generate by hand for every <span style="text-decoration: line-through;">table</span> collection, and put the entire document back is a waster of resource (network, IO and so forth).</p>
<p>Another important feature (at least for me <img src='http://crodas.org/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> , are the data validation. I implemented it in a simple way (at least I think). Suppose that in the User collection, we want to store the password encoded with SHA1, and the username can&#8217;t be changed, this can be done as follow:</p>
<pre>&lt;?php
class User Extends ActiveMongo
{
    public $username;
    public $password;
    public $country;
    public $address;

    function username_filter($value, $past_value)
    {
        if ($past_value != null &amp;&amp; $value != $past_value) {
           throw new FilterException("Can't change username");
        }
        if (!preg_match("s/[a-z][a-z0-9\-]+/", $value)) {
           throw new FilterException("Invalid username");
        }
    }

    function password_filter(&amp;$value)
    {
        if (strlen($value) &lt; 5) {
            return false; /* same as throw something */
        }
        $value = sha1($value);
    }
}
?&gt;</pre>
<p>Nice, isn&#8217;t it?. Of course, we can&#8217;t check if a current field exists or not, we can only validate that if exists. If you need to ensure that every document has some properties you can use the pre_save hook that receive as first parameter the operation (&#8216;create&#8217; or &#8216;update&#8217;) and document that will be saved in the second parameter.</p>
<pre>class User Extends ActiveMongo
{
    /* ... previous code .../
    function pre_save($op, $document)
    {
        $to_check = array('username', 'password');

        switch($op) {
        case 'create':
            foreach ($check as $field) {
               if (!isset($document[$field])) {
                   throw new FilterException("Missing field {$field}");
               }
            }
            break;
        case 'update':
            foreach ((array)$document['$unset'] as $field) {
                if (isset($document['$unset'][$field])) {
                    throw new FilterException("The field {$field} cant be unset");
                }
            }
            break;
        }
    }
}</pre>
<p>If the folk request (and if it is useful) this checking could be automated somehow (e.j: implementing a method checkFields() that return an array of required fields), meanwhile I&#8217;ll find this way pretty useful and amicable, also this hook could be used to check if the current user has permissions to perform an insert or creation (useful for CRM, currently ActiveMongo support only three possible hooks, pre_save, on_save (after the save()) and on_iterate (when it moves to the next record).</p>
<p>The most important part is how you query your database, for our luck, MongoDB has a very flexible query method, think on it as a compiled SQL, with no join <img src='http://crodas.org/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> ),  because <a href="http://www.mongodb.org/display/DOCS/Advanced+Queries" target="_blank">MongoDB is already kickass in queries</a>, there is no need to abstract it.</p>
<pre>class User Extends ActiveMongo
{
    /* ... previous code .../
    /* SELECT * FROM user WHERE karma &gt; 15 ORDER BY karma DESC */
    function my_query($karma)
    {
         /* get MongoDB collection object */
         $col = $this-&gt;_getCollection();
         /* Let's build our request */
         $query = $col-&gt;find( array('karma' =&gt; array('$gt' =&gt; 15)) );
         $query-&gt;sort(array('karma' =&gt; -1));
         /* now give the query to ActiveMongo */
         $this-&gt;setCursor($query);

         return $this; /* to use directly with foreach */
    }
}

/* How to use it. */
$users = new User;
foreach ($users-&gt;my_query(15) as $user) {
    $user-&gt;user_type = 'super_user';
    $user-&gt;save();
}

/* ActiveMongo on its own provides a very simple query API */
/* no limit, no sorting */
$user = new User;
$user-&gt;username = 'crodas';
$user-&gt;find(); /* read the parameters from object property */</pre>
<p>Currently ActivoMongo is still under development, but as far as I have tested seems pretty stable, most of development are to add new functionality, for instance I&#8217;m looking for an easy way to add references to other document, or set of documents, keeping in mind efficiency, talking as less as possible to the database.</p>
<p>Every release will be hosted at <a href="http://www.phpclasses.org/">PHPClasses</a>, and in the <a href="http://github.com/crodas/ActiveMongo" target="_blank">git repository</a> I&#8217;ll mirror my under-development version.</p>
<p>Comments, patches, fork/merge request are more than welcome <img src='http://crodas.org/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>]]></content:encoded>
			<wfw:commentRss>http://crodas.org/activemongo.php/feed</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Thinking in Documents (and dropping ACID)</title>
		<link>http://crodas.org/thinking-in-documents-and-dropping-acid.php</link>
		<comments>http://crodas.org/thinking-in-documents-and-dropping-acid.php#comments</comments>
		<pubDate>Sat, 28 Nov 2009 21:51:49 +0000</pubDate>
		<dc:creator>crodas</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Brazil]]></category>
		<category><![CDATA[CouchDB]]></category>
		<category><![CDATA[MongoDB]]></category>
		<category><![CDATA[phpconf2009]]></category>

		<guid isPermaLink="false">http://crodas.org/?p=69</guid>
		<description><![CDATA[]]></description>
			<content:encoded><![CDATA[<div id="__ss_2603989" style="width: 425px; text-align: left;"><object style="margin:0px" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="425" height="355" 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://static.slidesharecdn.com/swf/ssplayer2.swf?doc=phpconf-091128153336-phpapp01&amp;rel=0&amp;stripped_title=thinking-in-documents-dropping-acid-2603989" /><param name="allowfullscreen" value="true" /><embed style="margin:0px" type="application/x-shockwave-flash" width="425" height="355" src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=phpconf-091128153336-phpapp01&amp;rel=0&amp;stripped_title=thinking-in-documents-dropping-acid-2603989" allowscriptaccess="always" allowfullscreen="true"></embed></object></div>]]></content:encoded>
			<wfw:commentRss>http://crodas.org/thinking-in-documents-and-dropping-acid.php/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Distributing PHP processing with Gearman</title>
		<link>http://crodas.org/distributing-php-processing-with-gearman.php</link>
		<comments>http://crodas.org/distributing-php-processing-with-gearman.php#comments</comments>
		<pubDate>Tue, 24 Nov 2009 03:32:05 +0000</pubDate>
		<dc:creator>crodas</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[gearman]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[phpclasses]]></category>

		<guid isPermaLink="false">http://crodas.org/?p=58</guid>
		<description><![CDATA[The weekend I wrote an article about Gearman published on the PHPClasses site.
Special thanks to my friend Manuel Lemos]]></description>
			<content:encoded><![CDATA[<p>The weekend I wrote an article about <a href="http://gearman.org/">Gearman</a> published on the<a href="http://phpclasses.org/"> PHPClasses site</a>.</p>
<div id="attachment_63" class="wp-caption aligncenter" style="width: 610px"><a href="http://www.phpclasses.org/blog/post/108-Distributing-PHP-processing-with-Gearman.html"><img class="size-large wp-image-63" title="My post at PHPClasses" src="http://crodas.org/wp-content/uploads/2009/11/phpclasses-1024x640.png" alt="My post at PHPClasses" width="600" height="431" /></a><p class="wp-caption-text">My post at PHPClasses</p></div>
<p>Special thanks to my friend <a href="http://manuellemos.net/">Manuel Lemos</a></p>]]></content:encoded>
			<wfw:commentRss>http://crodas.org/distributing-php-processing-with-gearman.php/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Latinoware 2009</title>
		<link>http://crodas.org/latinoware-2009.php</link>
		<comments>http://crodas.org/latinoware-2009.php#comments</comments>
		<pubDate>Fri, 23 Oct 2009 16:37:02 +0000</pubDate>
		<dc:creator>crodas</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[latinoware]]></category>
		<category><![CDATA[speech]]></category>

		<guid isPermaLink="false">http://crodas.org/?p=34</guid>
		<description><![CDATA[Non-Framework MVC sites with PHP
View more documents from crodas.
]]></description>
			<content:encoded><![CDATA[<div id="__ss_2329857" style="width: 425px; text-align: left;"><a style="font:14px Helvetica,Arial,Sans-serif;display:block;margin:12px 0 3px 0;text-decoration:underline;" title="Non-Framework MVC sites with PHP" href="http://www.slideshare.net/crodas/nonframework-mvc-sites-with-php">Non-Framework MVC sites with PHP</a><object style="margin:0px" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="425" height="355" 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://static.slidesharecdn.com/swf/ssplayer2.swf?doc=slides-091023112819-phpapp01&amp;stripped_title=nonframework-mvc-sites-with-php" /><param name="allowfullscreen" value="true" /><embed style="margin:0px" type="application/x-shockwave-flash" width="425" height="355" src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=slides-091023112819-phpapp01&amp;stripped_title=nonframework-mvc-sites-with-php" allowscriptaccess="always" allowfullscreen="true"></embed></object></p>
<div style="font-size: 11px; font-family: tahoma,arial; height: 26px; padding-top: 2px;">View more <a style="text-decoration:underline;" href="http://www.slideshare.net/">documents</a> from <a style="text-decoration:underline;" href="http://www.slideshare.net/crodas">crodas</a>.</div>
</div>]]></content:encoded>
			<wfw:commentRss>http://crodas.org/latinoware-2009.php/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Weird but cool Pagerank&#8217;s usage</title>
		<link>http://crodas.org/weird-but-cool-pageranks-usage.php</link>
		<comments>http://crodas.org/weird-but-cool-pageranks-usage.php#comments</comments>
		<pubDate>Tue, 06 Oct 2009 17:42:33 +0000</pubDate>
		<dc:creator>crodas</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[algorithms]]></category>
		<category><![CDATA[pagerank]]></category>
		<category><![CDATA[weirdness]]></category>

		<guid isPermaLink="false">http://crodas.org/?p=3</guid>
		<description><![CDATA[Yesterday, talking with a good friend, he told me he needed a good algorithm to detect keywords (relevant words) from a document. The first algorithm  that came out from my head was a simple word frequency counter, discarding common words by building a list of stop-words with a previous learning. This algorithm is pretty [...]]]></description>
			<content:encoded><![CDATA[<p>Yesterday, talking with a good friend, he told me he needed a good algorithm to detect keywords (relevant words) from a document. The first algorithm  that came out from my head was a simple word frequency counter, discarding common words by building a list of stop-words with a previous learning. This algorithm is pretty obvious and I&#8217;m  sure it is very used out there.</p>
<p>Then Googling for some papers (I have a bunch on my laptop but I do not recall where I stored it)   I found a paper that opened my mind (<a href="http://www.cse.unt.edu/~rada/papers/mihalcea.emnlp04.pdf">TextRank: Bringing order into Texts</a>). It suggests to build a graph of words, then apply the <a href="http://en.wikipedia.org/wiki/PageRank">PageRank Algorithm</a> to the graph in order to know relevant words. I haven&#8217;t read it deeply yet, but I&#8217;ve got that idea with a brief reading, and it makes sense, I&#8217;m wondering why I never thought about it.</p>
<p>I&#8217;m planning to code it, just as a proof-of-concepts during this week.  Basically I will use some old code that I&#8217;ve coded (but never finished) awhile ago, I remember I build it very modular using classes, so adapt that code for these needs will be pretty straightforward.  And in the graph of words (and sets of  1, 2, 3 words probably), the previous word will reference the next word (If you have no idea about what I said here, just take a look <a href="http://en.wikipedia.org/wiki/File:PageRanks-Example.svg">here</a>).</p>
<p>I will post the results here.</p>]]></content:encoded>
			<wfw:commentRss>http://crodas.org/weird-but-cool-pageranks-usage.php/feed</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
	</channel>
</rss>

