<?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>Muziboo Development Blog &#187; Uncategorized</title>
	<atom:link href="http://devblog.muziboo.com/category/uncategorized/feed/" rel="self" type="application/rss+xml" />
	<link>http://devblog.muziboo.com</link>
	<description>Muziboo development stories. Mostly set in ruby land</description>
	<lastBuildDate>Fri, 01 Apr 2011 04:52:32 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Cucumber and i18n with interpolation</title>
		<link>http://devblog.muziboo.com/2011/04/01/cucumber-and-i18n-with-interpolatio/</link>
		<comments>http://devblog.muziboo.com/2011/04/01/cucumber-and-i18n-with-interpolatio/#comments</comments>
		<pubDate>Fri, 01 Apr 2011 04:51:10 +0000</pubDate>
		<dc:creator>prateek</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://devblog.muziboo.com/?p=127</guid>
		<description><![CDATA[
			
				
			
		
If you are using cucumber to test a multilingual app, you should check out this post for a step definition that you can use to test multilingual strings. However, most likely you would be using variables in your translation strings. Assuming you have pickle installed (if you don&#8217;t you should), you can use the step [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fdevblog.muziboo.com%2F2011%2F04%2F01%2Fcucumber-and-i18n-with-interpolatio%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fdevblog.muziboo.com%2F2011%2F04%2F01%2Fcucumber-and-i18n-with-interpolatio%2F&amp;source=muziboo&amp;style=normal&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p>If you are using cucumber to test a multilingual app, you should check out <a href="http://amielmartin.tumblr.com/post/235855133/using-i18n-in-cucumber" onclick="javascript:pageTracker._trackPageview('/outbound/article/amielmartin.tumblr.com');">this post</a> for a step definition that you can use to test multilingual strings. However, most likely you would be using variables in your translation strings. Assuming you have <a href="https://github.com/ianwhite/pickle" onclick="javascript:pageTracker._trackPageview('/outbound/article/github.com');">pickle</a> installed (if you don&#8217;t you should), you can use the step and step definition below to test strings with variable interpolation</p>
<p><script src="https://gist.github.com/897732.js?file=gistfile1.rb"></script></p>
<p>Just like pickle, you can add any number of variables.</p>
]]></content:encoded>
			<wfw:commentRss>http://devblog.muziboo.com/2011/04/01/cucumber-and-i18n-with-interpolatio/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Rails + MySQL scaling on a budget</title>
		<link>http://devblog.muziboo.com/2011/03/09/rails-mysql-scaling-on-a-budget/</link>
		<comments>http://devblog.muziboo.com/2011/03/09/rails-mysql-scaling-on-a-budget/#comments</comments>
		<pubDate>Wed, 09 Mar 2011 13:30:36 +0000</pubDate>
		<dc:creator>prateek</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://devblog.muziboo.com/?p=112</guid>
		<description><![CDATA[
			
				
			
		
aka .. can&#8217;t throw hardware at it
Just when I decided to focus fulltime on my new startup SupportBee, our first product Muziboo decided to grow (no complaints though). We went from about 10k visits a day to about 30k visits a day in a month&#8217;s time. Muziboo was my first web programming experience and in [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fdevblog.muziboo.com%2F2011%2F03%2F09%2Frails-mysql-scaling-on-a-budget%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fdevblog.muziboo.com%2F2011%2F03%2F09%2Frails-mysql-scaling-on-a-budget%2F&amp;source=muziboo&amp;style=normal&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p>aka .. can&#8217;t throw hardware at it</p>
<p>Just when I decided to focus fulltime on my new startup <a href="http://supportbee.com" onclick="javascript:pageTracker._trackPageview('/outbound/article/supportbee.com');">SupportBee</a>, our first product <a href="http://www.muziboo.com" >Muziboo</a> decided to grow (no complaints though). We went from about 10k visits a day to about 30k visits a day in a month&#8217;s time. Muziboo was my first web programming experience and in the sprit of a <a href="http://gettingreal.37signals.com/" onclick="javascript:pageTracker._trackPageview('/outbound/article/gettingreal.37signals.com');">real</a> startup, I always postponed worrying about scaling. However, the cracks showed through this time. Here is what we observed</p>
<ul>
<li>Slow page load</li>
<li>High CPU load and disk I/O</li>
<li>MySQL consuming very high CPU consistently</li>
</ul>
<p>Below is a log of what we did to make the site faster</p>
<p><strong>Better Server Monitoring and Logging</strong></p>
<p>You can&#8217;t fix what you can&#8217;t measure. We researched a bit and installed <a href="http://munin-monitoring.org/" onclick="javascript:pageTracker._trackPageview('/outbound/article/munin-monitoring.org');">munin</a>. Apart from the standard plugins (disk, cpu, network) we setup plugins for beanstalk, rails and nginx. This gave us some pretty charts to understand how the system was behaving. Here is an example of what munin charts looks like</p>
<p><img title="Hosted by imgur.com" src="http://i.imgur.com/Ln3aP.png" alt="" /></p>
<p>Not only can you see the current state of the system, you can also see data for past weeks/months/years. If you are not excited by installing munin, you can look at hosted solution like <a href="http://www.serverdensity.com" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.serverdensity.com');">Server Density</a></p>
<p><strong>MySQL slow query log for missing indexes</strong></p>
<p>Rails does not (cannot) add indexes to your database. Rails does not (cannot) add indexes to your database <em>automatically</em>. You will have to figure out what indexes to add based on your queries. This is not a problem for small tables (hundreds or thousands of rows) but its a problem with bigger tables. Fortunately, its easy to find out queries that are not using the index. Apart from listing slow queries, MySQL can list all the queries that don&#8217;t use the index in slow query log. You can enable it by having this directive in your mysql configuration file</p>
<pre>log-queries-not-using-indexes</pre>
<p>We enabled this option and found out that we had a bunch of index less queries. As we added these indexes, mysql&#8217;s cpu usage started going down bringing the system to a much better shape. You can use mysql&#8217;s explain statement to understand your queries better and add indexes. Its a good idea to have explain&#8217;s output in your rails&#8217; log during development. I found this snippet that does it for you</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">unless</span> RAILS_ENV == <span style="color:#996600;">'production'</span>
      <span style="color:#9966CC; font-weight:bold;">module</span> ActiveRecord
        <span style="color:#9966CC; font-weight:bold;">module</span> ConnectionAdapters
          <span style="color:#9966CC; font-weight:bold;">class</span> MysqlAdapter <span style="color:#006600; font-weight:bold;">&amp;</span>lt; AbstractAdapter             <span style="color:#9966CC; font-weight:bold;">def</span> select_with_explain<span style="color:#006600; font-weight:bold;">&#40;</span>sql, name = <span style="color:#0000FF; font-weight:bold;">nil</span><span style="color:#006600; font-weight:bold;">&#41;</span>               explanation = execute_with_disable_logging<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'EXPLAIN '</span> <span style="color:#006600; font-weight:bold;">+</span> sql<span style="color:#006600; font-weight:bold;">&#41;</span>               e = explanation.<span style="color:#9900CC;">all_hashes</span>.<span style="color:#9900CC;">first</span>               exp = e.<span style="color:#9900CC;">collect</span><span style="color:#006600; font-weight:bold;">&#123;</span><span style="color:#006600; font-weight:bold;">|</span>k,v<span style="color:#006600; font-weight:bold;">|</span> <span style="color:#996600;">&quot; | #{k}: #{v} &quot;</span><span style="color:#006600; font-weight:bold;">&#125;</span>.<span style="color:#9900CC;">join</span>               log<span style="color:#006600; font-weight:bold;">&#40;</span>exp, <span style="color:#996600;">'Explain'</span><span style="color:#006600; font-weight:bold;">&#41;</span>               select_without_explain<span style="color:#006600; font-weight:bold;">&#40;</span>sql, name<span style="color:#006600; font-weight:bold;">&#41;</span>             <span style="color:#9966CC; font-weight:bold;">end</span>             <span style="color:#9966CC; font-weight:bold;">def</span> execute_with_disable_logging<span style="color:#006600; font-weight:bold;">&#40;</span>sql, name = <span style="color:#0000FF; font-weight:bold;">nil</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#008000; font-style:italic;">#:nodoc:               #Run a query without logging               @connection.query(sql)             rescue ActiveRecord::StatementInvalid =&amp;gt; exception</span>
              <span style="color:#9966CC; font-weight:bold;">if</span> exception.<span style="color:#9900CC;">message</span>.<span style="color:#CC0066; font-weight:bold;">split</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;:&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">first</span> =~ <span style="color:#006600; font-weight:bold;">/</span>Packets out of order<span style="color:#006600; font-weight:bold;">/</span>
                <span style="color:#CC0066; font-weight:bold;">raise</span> <span style="color:#6666ff; font-weight:bold;">ActiveRecord::StatementInvalid</span>, <span style="color:#996600;">&quot;'Packets out of order' error was received from the database. Please update your mysql bindings (gem install mysql) and read http://dev.mysql.com/doc/mysql/en/password-hashing.html for more information.  If you're on Windows, use the Instant Rails installer to get the updated mysql bindings.&quot;</span>
              <span style="color:#9966CC; font-weight:bold;">else</span>
                <span style="color:#CC0066; font-weight:bold;">raise</span>
              <span style="color:#9966CC; font-weight:bold;">end</span>
            <span style="color:#9966CC; font-weight:bold;">end</span>
            alias_method_chain <span style="color:#ff3333; font-weight:bold;">:select</span>, <span style="color:#ff3333; font-weight:bold;">:explain</span>
          <span style="color:#9966CC; font-weight:bold;">end</span>
        <span style="color:#9966CC; font-weight:bold;">end</span>
      <span style="color:#9966CC; font-weight:bold;">end</span>
    <span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>Put it in your config/initializers directory as mysql_explain.rb and restart your server. Now you should see output from explain in your logs before your sql queries. One point to note is that throwing memcache is not a substitute for having faster queries.</p>
<p><strong>Beware of MySQL&#8217;s ORDER BY rand()</strong></p>
<p>Even after adding indexes, one of our queries was not using them. On investigating further I found out that MySQL&#8217;s order by rand() is evil. I won&#8217;t go into the specifics now but you can read up more on <a href="http://stackoverflow.com/questions/1244555/how-can-i-optimize-mysqls-order-by-rand-function" onclick="javascript:pageTracker._trackPageview('/outbound/article/stackoverflow.com');">stackoverflow</a>. In short, order by rand() will always do a full table scan. Avoid it.</p>
<p><strong>MySQLDump haz all the locks</strong></p>
<div><a href="http://dev.mysql.com/doc/refman/5.1/en/mysqldump.html" onclick="javascript:pageTracker._trackPageview('/outbound/article/dev.mysql.com');">mysqldump</a> is a popular choice for backing up databases. However it locks up all your tables during the backup. What this means is that your rails&#8217; instances cannot access the database during that time and most likely cannot serve any requests. We moved to <a href="http://www.percona.com/docs/wiki/percona-xtrabackup:start" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.percona.com');">Percona&#8217;s xtrabackup </a>to fix this. However this only works for tables that are innodb (in our case, every table).</div>
<p><strong>Moving from mongrel to passenger</strong></p>
<p>Muziboo was started when the world was just moving over from fastcgi to mongrel. Hence we were using a bunch of  mongrels monitored by monit. However, every time you want to add more mongrels, you have to change your monit configuration file to start and monitor more mongrels. Also there is no easy way to reduce the number of mongrels when under less load. Hence we decided to move over to passenger. In passenger, you just have to change the number of max instances in the nginx configuration files and more app instances will be started under load. When the load is lesser, these instances are shut down. All this is automatically done for you.</p>
<p><strong>Taming I/O during rsync</strong></p>
<p>We use rsync to backup uploaded files uploaded by Muziboo&#8217;s user. We have about 1 TB of data and even though the backup is incremental, there is still considerable I/O to check which files have to be moved. To make sure that rsync does not overwhelm everything else, we used the following options</p>
<pre>nice -20 ionice -c2 -n7 /usr/bin/rsync -avz -e ssh --times --size-only --stats ......</pre>
<p>Nice and IONice help you keep the CPU and disk usage low. You can also use it for other cron/background jobs that you run.</p>
<p>With these changes in place, we have been able to accomodate all the growth on a single server (Quadcore + 12 GB RAM). I think with more growth we may have slowers mysql writes and at that point we may need to move to a separate db server.</p>
<p>Read some interesting comments on this post on <a href="http://news.ycombinator.com/item?id=2304747" onclick="javascript:pageTracker._trackPageview('/outbound/article/news.ycombinator.com');">Hacker News</a></p>
]]></content:encoded>
			<wfw:commentRss>http://devblog.muziboo.com/2011/03/09/rails-mysql-scaling-on-a-budget/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Hosting your git repo on your own server</title>
		<link>http://devblog.muziboo.com/2011/02/13/hosting-your-own-git-repo-on-your-server/</link>
		<comments>http://devblog.muziboo.com/2011/02/13/hosting-your-own-git-repo-on-your-server/#comments</comments>
		<pubDate>Sun, 13 Feb 2011 11:05:32 +0000</pubDate>
		<dc:creator>prateek</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://devblog.muziboo.com/?p=108</guid>
		<description><![CDATA[
			
				
			
		
Hosting a git repo yourself is a very simple exercise. If you don&#8217;t need (or don&#8217;t want to pay for) features offered by github, you can setup your server to host your git repo. All you need is a server with ssh access. Here are the steps that you need to follow
Login to your server

ssh [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fdevblog.muziboo.com%2F2011%2F02%2F13%2Fhosting-your-own-git-repo-on-your-server%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fdevblog.muziboo.com%2F2011%2F02%2F13%2Fhosting-your-own-git-repo-on-your-server%2F&amp;source=muziboo&amp;style=normal&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p>Hosting a git repo yourself is a very simple exercise. If you don&#8217;t need (or don&#8217;t want to pay for) features offered by github, you can setup your server to host your git repo. All you need is a server with ssh access. Here are the steps that you need to follow</p>
<p>Login to your server</p>
<p><code lang="bash"><br />
ssh tom@example.com<br />
tom@example.com$ mkdir my_repo.git<br />
tom@example.com$ cd my_repo.git<br />
tom@example.com$ git init<br />
</code></p>
<p>On you local machine, where you have your code</p>
<p><code lang="bash"><br />
$ cd my_code # cd to your code<br />
$ git init<br />
$ git add .  # Adds everything. Use .gitignore to ignore some files<br />
$ git remote add origin tom@example.com:my_repo.git<br />
$ git push origin master<br />
</code></p>
<p>Now you can clone tom@example.com:my_repo.git on any number of machines. To not share password, put your public keys on tom@example.com</p>
<p>This approach gives you a basic git setup with ssh access (no http access). These steps should work on shared hosting too (as long as you have git available)</p>
]]></content:encoded>
			<wfw:commentRss>http://devblog.muziboo.com/2011/02/13/hosting-your-own-git-repo-on-your-server/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Flexmock Error: undefined method `destroyed?&#8217;</title>
		<link>http://devblog.muziboo.com/2010/09/22/flexmock-error-undefined-method-destroyed/</link>
		<comments>http://devblog.muziboo.com/2010/09/22/flexmock-error-undefined-method-destroyed/#comments</comments>
		<pubDate>Wed, 22 Sep 2010 03:54:14 +0000</pubDate>
		<dc:creator>prateek</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://devblog.muziboo.com/?p=101</guid>
		<description><![CDATA[
			
				
			
		
If you are using flexmock for testing your rails code and you are mocking an active record model using flexmock(:model, Model), you may get an error like
 undefined method `destroyed?'
The problem is that flexmock defines a lot of methods/attributes like id and new_instance? etc but does not define a destroyed? method that rails now expects. [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fdevblog.muziboo.com%2F2010%2F09%2F22%2Fflexmock-error-undefined-method-destroyed%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fdevblog.muziboo.com%2F2010%2F09%2F22%2Fflexmock-error-undefined-method-destroyed%2F&amp;source=muziboo&amp;style=normal&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p>If you are using flexmock for testing your rails code and you are mocking an active record model using flexmock(:model, Model), you may get an error like</p>
<p><code style="font-family: Monaco, Consolas, 'DejaVu Sans Mono', monospace; font-size: 11px; color: #444444;"> undefined method `destroyed?'</code></p>
<p>The problem is that flexmock defines a lot of methods/attributes like id and new_instance? etc but does not define a destroyed? method that rails now expects. Fortunately, this is easy to fix. Create a file &#8216;config/initializers/flexmock_extensions.rb&#8217; and put this in</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">class</span> FlexMock
  <span style="color:#9966CC; font-weight:bold;">class</span> MockContainerHelper
    <span style="color:#9966CC; font-weight:bold;">def</span> add_model_methods<span style="color:#006600; font-weight:bold;">&#40;</span>mock, model_class, id<span style="color:#006600; font-weight:bold;">&#41;</span>
      container = mock.<span style="color:#9900CC;">flexmock_container</span>
&nbsp;
      mock_errors = container.<span style="color:#9900CC;">flexmock</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;errors&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
      mock_errors.<span style="color:#9900CC;">should_receive</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:count</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">and_return</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006666;">0</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">by_default</span>
      mock_errors.<span style="color:#9900CC;">should_receive</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:full_messages</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">and_return</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">by_default</span>
&nbsp;
      mock.<span style="color:#9900CC;">should_receive</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:id</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">and_return</span><span style="color:#006600; font-weight:bold;">&#40;</span>id<span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">by_default</span>
      mock.<span style="color:#9900CC;">should_receive</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:to_params</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">and_return</span><span style="color:#006600; font-weight:bold;">&#40;</span>id.<span style="color:#9900CC;">to_s</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">by_default</span>
      mock.<span style="color:#9900CC;">should_receive</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:new_record</span>?<span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">and_return</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF; font-weight:bold;">false</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">by_default</span>
      mock.<span style="color:#9900CC;">should_receive</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:class</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">and_return</span><span style="color:#006600; font-weight:bold;">&#40;</span>model_class<span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">by_default</span>
      mock.<span style="color:#9900CC;">should_receive</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:errors</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">and_return</span><span style="color:#006600; font-weight:bold;">&#40;</span>mock_errors<span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">by_default</span>
      mock.<span style="color:#9900CC;">should_receive</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:destroyed</span>?<span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">and_return</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF; font-weight:bold;">false</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">by_default</span>
&nbsp;
      <span style="color:#008000; font-style:italic;"># HACK: Ruby 1.9 needs the following lambda so that model_class</span>
      <span style="color:#008000; font-style:italic;"># is correctly bound below.</span>
      <span style="color:#CC0066; font-weight:bold;">lambda</span> <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#006600; font-weight:bold;">&#125;</span>
      mock.<span style="color:#9900CC;">should_receive</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:is_a</span>?<span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">with</span><span style="color:#006600; font-weight:bold;">&#40;</span>any<span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">and_return</span> <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#006600; font-weight:bold;">|</span>other<span style="color:#006600; font-weight:bold;">|</span>
        other == model_class
      <span style="color:#006600; font-weight:bold;">&#125;</span>.<span style="color:#9900CC;">by_default</span>
      mock.<span style="color:#9900CC;">should_receive</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:instance_of</span>?<span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">with</span><span style="color:#006600; font-weight:bold;">&#40;</span>any<span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">and_return</span> <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#006600; font-weight:bold;">|</span>other<span style="color:#006600; font-weight:bold;">|</span>
        other == model_class
      <span style="color:#006600; font-weight:bold;">&#125;</span>.<span style="color:#9900CC;">by_default</span>
      mock.<span style="color:#9900CC;">should_receive</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:kind_of</span>?<span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">with</span><span style="color:#006600; font-weight:bold;">&#40;</span>any<span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">and_return</span> <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#006600; font-weight:bold;">|</span>other<span style="color:#006600; font-weight:bold;">|</span>
        model_class.<span style="color:#9900CC;">ancestors</span>.<span style="color:#9966CC; font-weight:bold;">include</span>?<span style="color:#006600; font-weight:bold;">&#40;</span>other<span style="color:#006600; font-weight:bold;">&#41;</span>
      <span style="color:#006600; font-weight:bold;">&#125;</span>.<span style="color:#9900CC;">by_default</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>Basically, we are defining the method destroyed? and returning false everytime. Now your tests should work</p>
]]></content:encoded>
			<wfw:commentRss>http://devblog.muziboo.com/2010/09/22/flexmock-error-undefined-method-destroyed/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Updated Blackbook gem</title>
		<link>http://devblog.muziboo.com/2010/04/06/updated-blackbook-gem/</link>
		<comments>http://devblog.muziboo.com/2010/04/06/updated-blackbook-gem/#comments</comments>
		<pubDate>Tue, 06 Apr 2010 15:28:45 +0000</pubDate>
		<dc:creator>prateek</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[blackbook]]></category>
		<category><![CDATA[gem]]></category>

		<guid isPermaLink="false">http://devblog.muziboo.com/?p=90</guid>
		<description><![CDATA[
			
				
			
		
I just pushed some changes to my fork of the blackbook address book importer gem. Here is a list of changes

The gem now works with the latest version of mechanize and nokogiri
Myspace and Gmail importer working perfectly. Myspace had changed its url scheme and also address book rendering stuff so the gem was broken for [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fdevblog.muziboo.com%2F2010%2F04%2F06%2Fupdated-blackbook-gem%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fdevblog.muziboo.com%2F2010%2F04%2F06%2Fupdated-blackbook-gem%2F&amp;source=muziboo&amp;style=normal&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p>I just pushed some changes to my fork of the <a href="http://github.com/prateekdayal/blackbook" onclick="javascript:pageTracker._trackPageview('/outbound/article/github.com');">blackbook address book importer gem</a>. Here is a list of changes</p>
<ul>
<li>The gem now works with the latest version of mechanize and nokogiri</li>
<li>Myspace and Gmail importer working perfectly. Myspace had changed its url scheme and also address book rendering stuff so the gem was broken for a while</li>
</ul>
<p>Sadly the yahoo address book importer is not working as yahoo as added a captcha before csv download. I will try to use an alternative view and fix the issue sometime soon.  I have not tried aol and hotmail import.</p>
<p>If you need any help, please leave a comment here.</p>
]]></content:encoded>
			<wfw:commentRss>http://devblog.muziboo.com/2010/04/06/updated-blackbook-gem/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Externalinterface not working in Firefox but working in IE for invisible swf</title>
		<link>http://devblog.muziboo.com/2009/11/26/externalinterface-not-working-in-firefox-but-working-in-ie-for-invisible-swf/</link>
		<comments>http://devblog.muziboo.com/2009/11/26/externalinterface-not-working-in-firefox-but-working-in-ie-for-invisible-swf/#comments</comments>
		<pubDate>Thu, 26 Nov 2009 05:20:35 +0000</pubDate>
		<dc:creator>prateek</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[error]]></category>

		<guid isPermaLink="false">http://devblog.muziboo.com/?p=87</guid>
		<description><![CDATA[
			
				
			
		
Yes &#8230; as unrealistic as it may sound, yesterday, I ran into an issue where something worked in Internet explorer but not in Firefox. I was trying to call an actionscript functions on a swf file from javascript. This is a fairly standard thing and is well documented on the web. I followed all the [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fdevblog.muziboo.com%2F2009%2F11%2F26%2Fexternalinterface-not-working-in-firefox-but-working-in-ie-for-invisible-swf%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fdevblog.muziboo.com%2F2009%2F11%2F26%2Fexternalinterface-not-working-in-firefox-but-working-in-ie-for-invisible-swf%2F&amp;source=muziboo&amp;style=normal&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p>Yes &#8230; as unrealistic as it may sound, yesterday, I ran into an issue where something worked in Internet explorer but not in Firefox. I was trying to call an actionscript functions on a swf file from javascript. This is a fairly standard thing and is <a href="http://www.adobe.com/devnet/flash/articles/external_interface_06.html" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.adobe.com');">well documented</a> on the web. I followed all the steps (registering a callback and embedding the swf using <a href="http://code.google.com/p/swfobject/" onclick="javascript:pageTracker._trackPageview('/outbound/article/code.google.com');">swfobject</a> library) and it worked perfectly in IE. I could call my actionscript functions using javascript in IE but in firefox it would occasionally fail and I would see the following two messages in firebug</p>
<p><em><strong>uncaught exception: [Exception... "Failure" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location: "JS frame :: http://localhost:9001/javascripts/swfobject.js?1259133537 :: anonymous :: line 4" data: no]</strong></em></p>
<p><em><strong>$(&#8217;movieName&#8217;).asFunc() undefined method </strong></em></p>
<p>where <em>movieName</em> is the id of the swf file and <em>asFunc</em> is the function defined in actionscript using ExternalInterface.addCallback. After a lot of googling, I ran into <a href="http://www.kirupa.com/forum/showpost.php?p=2310986&amp;postcount=2" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.kirupa.com');">this thread</a> which explained the basic problem. Since my swf file was hidden in the footer of the page, the callbacks worked after I had once scrolled down and seen the footer. Yes as crazy as it sounds, that was really the problem.  Firefox wants you to see the swf once before you make the function call.  To make sure that the 1&#215;1 sized swf file was always visible no matter where you are in the page, I added the following css rule</p>
<p>#movieName {<br />
position: fixed;<br />
top: 0;<br />
left: 0;<br />
}</p>
<p>This rule makes sure that no matter how much you scroll up or scroll down, the swf file is always at the same place (in this case, just at the starting of the page, relative to the browser window). You can read more about fixed positioning <a href="http://www.w3schools.com/Css/css_positioning.asp" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.w3schools.com');">here</a>. I am sure there must be a better explanation/solution for this problem but I have tried my approach and it atleast works. If you find a better solution, please post as a comment and I will update the post.</p>
]]></content:encoded>
			<wfw:commentRss>http://devblog.muziboo.com/2009/11/26/externalinterface-not-working-in-firefox-but-working-in-ie-for-invisible-swf/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Resizing existing images uploaded using file_column</title>
		<link>http://devblog.muziboo.com/2009/11/14/resizing-existing-images-uploaded-using-file_column/</link>
		<comments>http://devblog.muziboo.com/2009/11/14/resizing-existing-images-uploaded-using-file_column/#comments</comments>
		<pubDate>Sat, 14 Nov 2009 06:48:56 +0000</pubDate>
		<dc:creator>prateek</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://devblog.muziboo.com/?p=83</guid>
		<description><![CDATA[
			
				
			
		
File column is a great plugin by Sebastian Kanthak for uploading images (and other files) in a rails&#8217; site. The plugin has rmagick integration and can create thumbnails automatically for you. We use it for Muziboo and have been pretty happy with it (yes despite the rmagick dependency). We recently had to update the thumbnail [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fdevblog.muziboo.com%2F2009%2F11%2F14%2Fresizing-existing-images-uploaded-using-file_column%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fdevblog.muziboo.com%2F2009%2F11%2F14%2Fresizing-existing-images-uploaded-using-file_column%2F&amp;source=muziboo&amp;style=normal&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p><a href="http://www.kanthak.net/opensource/file_column/" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.kanthak.net');">File column</a> is a great plugin by Sebastian Kanthak for uploading images (and other files) in a rails&#8217; site. The plugin has rmagick integration and can create thumbnails automatically for you. We use it for <a href="http://www.muziboo.com" >Muziboo</a> and have been pretty happy with it (yes despite the rmagick dependency). We recently had to update the thumbnail dimensions for a few of our models. Its fairly simple to change the thumbnail sizes in the model and all new uploads are resized to new dimensions. However, the existing images are not automatically changed for you . Thankfully, on digging deeper into the code I found that there is pretty simple way to accomplish that. Lets say you have a user model (with a file_column field photo) and you want to update the thumbnails for all existing images. You just need to simply run the following commands</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">User.<span style="color:#9900CC;">find</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:all</span>,:conditions <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;photo IS NOT NULL&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">each</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>u<span style="color:#006600; font-weight:bold;">|</span>
  u.<span style="color:#9900CC;">photo</span> = <span style="color:#CC00FF; font-weight:bold;">File</span>.<span style="color:#CC0066; font-weight:bold;">open</span><span style="color:#006600; font-weight:bold;">&#40;</span>u.<span style="color:#9900CC;">photo</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  u.<span style="color:#9900CC;">save</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>Ofcourse if you have a lot of users, you may wanna fetch them in batches. Also image resizing is a pretty CPU intensive operation so you may wanna watch out for that. Once the operation is over, you will have updated thumbnails for all your previously uploaded images.</p>
]]></content:encoded>
			<wfw:commentRss>http://devblog.muziboo.com/2009/11/14/resizing-existing-images-uploaded-using-file_column/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Authentication error while fetching gmail contacts using blackbook</title>
		<link>http://devblog.muziboo.com/2009/09/17/authentication-error-while-fetching-gmail-contacts-using-blackbook/</link>
		<comments>http://devblog.muziboo.com/2009/09/17/authentication-error-while-fetching-gmail-contacts-using-blackbook/#comments</comments>
		<pubDate>Thu, 17 Sep 2009 08:56:34 +0000</pubDate>
		<dc:creator>prateek</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://devblog.muziboo.com/?p=67</guid>
		<description><![CDATA[
			
				
			
		
Blackbook gem can be used to fetch contacts from gmail, yahoo and hotmail address books. However I recently found out that it would throw up a &#8216;Must be authenticated to access contacts&#8217; error everytime I tried to import gmail contacts. On digging deeper, I found out that google has changed the contents of its cookie and blackbook uses this cookie [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fdevblog.muziboo.com%2F2009%2F09%2F17%2Fauthentication-error-while-fetching-gmail-contacts-using-blackbook%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fdevblog.muziboo.com%2F2009%2F09%2F17%2Fauthentication-error-while-fetching-gmail-contacts-using-blackbook%2F&amp;source=muziboo&amp;style=normal&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p><a href="http://github.com/purzelrakete/blackbook" onclick="javascript:pageTracker._trackPageview('/outbound/article/github.com');">Blackbook</a> gem can be used to fetch contacts from gmail, yahoo and hotmail address books. However I recently found out that it would throw up a &#8216;Must be authenticated to access contacts&#8217; error everytime I tried to import gmail contacts. On digging deeper, I found out that google has changed the contents of its cookie and blackbook uses this cookie to make sure that the user is authenticated. To fix the issue, you just need to make a one line change in the function <em>scrape_contacts</em> in the file <em>lib/blackbook/importer/gmail.rb. </em></p>
<p>Change</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">unless</span> agent.<span style="color:#9900CC;">cookies</span>.<span style="color:#9900CC;">find</span><span style="color:#006600; font-weight:bold;">&#123;</span><span style="color:#006600; font-weight:bold;">|</span>c<span style="color:#006600; font-weight:bold;">|</span> c.<span style="color:#9900CC;">name</span> == <span style="color:#996600;">'GAUSR'</span>  <span style="color:#006600; font-weight:bold;">&amp;</span>amp;<span style="color:#006600; font-weight:bold;">&amp;</span>amp;
  c.<span style="color:#9900CC;">value</span> == <span style="color:#996600;">&quot;mail:#{options[:username]}&quot;</span><span style="color:#006600; font-weight:bold;">&#125;</span>
<span style="color:#CC0066; font-weight:bold;">raise</span><span style="color:#006600; font-weight:bold;">&#40;</span> <span style="color:#6666ff; font-weight:bold;">Blackbook::BadCredentialsError</span>, <span style="color:#996600;">&quot;Must be authenticated to access contacts.&quot;</span> <span style="color:#006600; font-weight:bold;">&#41;</span></pre></div></div>

<p>to</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">unless</span> agent.<span style="color:#9900CC;">cookies</span>.<span style="color:#9900CC;">find</span><span style="color:#006600; font-weight:bold;">&#123;</span><span style="color:#006600; font-weight:bold;">|</span>c<span style="color:#006600; font-weight:bold;">|</span> c.<span style="color:#9900CC;">name</span> == <span style="color:#996600;">'GAUSR'</span> <span style="color:#006600; font-weight:bold;">&amp;</span>amp;<span style="color:#006600; font-weight:bold;">&amp;</span>amp;
  <span style="color:#006600; font-weight:bold;">&#40;</span>c.<span style="color:#9900CC;">value</span> =~ <span style="color:#006600; font-weight:bold;">/</span>mail.<span style="color:#006600; font-weight:bold;">*</span>:<span style="color:#008000; font-style:italic;">#{options[:username]}/)!=nil}</span>
<span style="color:#CC0066; font-weight:bold;">raise</span><span style="color:#006600; font-weight:bold;">&#40;</span> <span style="color:#6666ff; font-weight:bold;">Blackbook::BadCredentialsError</span>, <span style="color:#996600;">&quot;Must be authenticated to access contacts.&quot;</span> <span style="color:#006600; font-weight:bold;">&#41;</span></pre></div></div>

<p>If you want to install the updated gem instead of making the change, you can find it in <a href="http://github.com/prateekdayal/blackbook" onclick="javascript:pageTracker._trackPageview('/outbound/article/github.com');">my blackbook fork</a>. My fork also includes the <a href="http://devblog.muziboo.com/2009/07/02/myspace-email-address-book-import-in-ruby/" >myspace address book import</a></p>
]]></content:encoded>
			<wfw:commentRss>http://devblog.muziboo.com/2009/09/17/authentication-error-while-fetching-gmail-contacts-using-blackbook/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Use RedCloth to nofollow all user generated links</title>
		<link>http://devblog.muziboo.com/2009/05/04/use-redcloth-to-nofollow-all-user-generated-links-2/</link>
		<comments>http://devblog.muziboo.com/2009/05/04/use-redcloth-to-nofollow-all-user-generated-links-2/#comments</comments>
		<pubDate>Mon, 04 May 2009 07:52:24 +0000</pubDate>
		<dc:creator>prateek</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://devblog.muziboo.com/2009/05/04/use-redcloth-to-nofollow-all-user-generated-links-2/</guid>
		<description><![CDATA[
			
				
			
		
Nofollow attribute in link tag makes sure that search engine bots don&#8217;t use the link for crawling the destination site. This is a measure to combat link spam and to make sure that you don&#8217;t pass link juice if you don&#8217;t want to. This is especially important for user generated content sites as they have [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fdevblog.muziboo.com%2F2009%2F05%2F04%2Fuse-redcloth-to-nofollow-all-user-generated-links-2%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fdevblog.muziboo.com%2F2009%2F05%2F04%2Fuse-redcloth-to-nofollow-all-user-generated-links-2%2F&amp;source=muziboo&amp;style=normal&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p><a href="http://en.wikipedia.org/wiki/Nofollow" onclick="javascript:pageTracker._trackPageview('/outbound/article/en.wikipedia.org');">Nofollow</a> attribute in <a href="http://www.w3schools.com/TAGS/tag_a.asp" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.w3schools.com');">link tag</a> makes sure that search engine bots don&#8217;t use the link for crawling the destination site. This is a measure to combat link spam and to make sure that you don&#8217;t pass link juice if you don&#8217;t want to. This is especially important for user generated content sites as they have no control over what links the users will put.</p>
<p>At <a href="http://www.muziboo.com" >Muziboo</a>, we use <a href="http://github.com/jgarber/redcloth/tree/master" onclick="javascript:pageTracker._trackPageview('/outbound/article/github.com');">RedCloth</a> to format the text that users input. We also use it to filter out any css styling the users put in and some html tags like embed, img etc. Let me show you how we nofollow all links automatically. Create a file called redcloth extension.rb and put it in config/initializers directory. Now put this in the file (please replace a_tag below with a. I had to stop wp from making that line a link)</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
</pre></td><td class="code"><pre class="language" style="font-family:monospace;">module RedCloth::Formatters::HTML
  include RedCloth::Formatters::Base
&nbsp;
    def link(opts)
     &quot;&lt;a href=\&quot;#{escape_attribute opts[:href]}\&quot;#{pba(opts)} rel=\&quot;nofollow\&quot;&gt;#{opts[:name]}&lt;/a&gt;&quot;
&nbsp;
    end
&nbsp;
    private
&nbsp;
    # HTML cleansing stuff
    ALLOWED_TAGS = {
      'a' =&amp;gt; ['href', 'title'],
      'br' =&amp;gt; [],
      'i' =&amp;gt; nil,
      'u' =&amp;gt; nil,
      'b' =&amp;gt; nil,
      'pre' =&amp;gt; nil,
      'kbd' =&amp;gt; nil,
      'code' =&amp;gt; ['lang'],
      'cite' =&amp;gt; nil,
      'strong' =&amp;gt; nil,
      'em' =&amp;gt; nil,
      'ins' =&amp;gt; nil,
      'sup' =&amp;gt; nil,
      'sub' =&amp;gt; nil,
      'del' =&amp;gt; nil,
      'table' =&amp;gt; nil,
      'tr' =&amp;gt; nil,
      'td' =&amp;gt; ['colspan', 'rowspan'],
      'th' =&amp;gt; nil,
      'ol' =&amp;gt; ['start'],
      'ul' =&amp;gt; nil,
      'li' =&amp;gt; nil,
      'p' =&amp;gt; nil,
  }
&nbsp;
    def clean_html( text, tags = ALLOWED_TAGS )
        text.gsub!( /&lt;!--\[CDATA\[/, '' )
        text.gsub!( /&lt;(\/*)(\w+)([^--&gt;]*)&amp;gt;/ ) do
            raw = $~
            tag = raw[2].downcase
            if tags.has_key? tag
                pcs = [tag]
                pcs &amp;lt;&amp;lt; &quot;rel=\&quot;nofollow\&quot;&quot; if (tag == 'a' and raw[1]=='')
                tags[tag].each do |prop|
                    ['&quot;', &quot;'&quot;, ''].each do |q|
                        q2 = ( q != '' ? q : '\s' )
                        if raw[3] =~ /#{prop}\s*=\s*#{q}([^#{q2}]+)#{q}/i
                            attrv = $1
                            next if prop == 'src' and attrv =~ %r{^(?!http)\w+:}
                            pcs &amp;lt;&amp;lt; &quot;#{prop}=\&quot;#{$1.gsub('&quot;', '\\&quot;')}\&quot;&quot; unless $1.nil?
                            break
                        end
                    end
                end if tags[tag]
                &quot;&amp;lt;#{raw[1]}#{pcs.join &quot; &quot;}&amp;gt;&quot;
            else
                &quot; &quot;
            end
        end
    end
&nbsp;
end</pre></td></tr></table></div>

<p>To filter the input, simply call RedCloth.new(input_text,[:sanitize_html,:filter_styles]).</p>
<p>These instructions are for Rails 2.3.2. For older rails&#8217; put the redcloth_extensions.rb file in lib folder and require it in your environment.rb</p>
<div class="zemanta-pixie"><img class="zemanta-pixie-img" src="http://img.zemanta.com/pixy.gif?x-id=16637c17-848f-89da-a77c-9b7c010f1329" alt="" /></div>
]]></content:encoded>
			<wfw:commentRss>http://devblog.muziboo.com/2009/05/04/use-redcloth-to-nofollow-all-user-generated-links-2/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Javascript and CSS debugging on internet explorer</title>
		<link>http://devblog.muziboo.com/2009/04/22/javascript-and-css-debugging-on-internet-explorer-2/</link>
		<comments>http://devblog.muziboo.com/2009/04/22/javascript-and-css-debugging-on-internet-explorer-2/#comments</comments>
		<pubDate>Wed, 22 Apr 2009 06:14:26 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[dns hosting]]></category>

		<guid isPermaLink="false">http://devblog.muziboo.com/2009/04/22/javascr/</guid>
		<description><![CDATA[
			
				
			
		
It comes as no surprise that when it comes to Javascript, browsers such as Firefox and Safari are more forgiving than Internet Explorer. Also tools like Firebug make javascript debugging very simple. However firebug (just like firefox) does not seem to mind issues like an extra comma or a missing semilcolon and this makes everything [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fdevblog.muziboo.com%2F2009%2F04%2F22%2Fjavascript-and-css-debugging-on-internet-explorer-2%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fdevblog.muziboo.com%2F2009%2F04%2F22%2Fjavascript-and-css-debugging-on-internet-explorer-2%2F&amp;source=muziboo&amp;style=normal&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p>It comes as no surprise that when it comes to Javascript, browsers such as Firefox and Safari are more forgiving than Internet Explorer. Also tools like <a href="https://addons.mozilla.org/firefox/addon/1843" onclick="javascript:pageTracker._trackPageview('/outbound/article/addons.mozilla.org');">Firebug</a> make javascript debugging very simple. However firebug (just like firefox) does not seem to mind issues like an extra comma or a missing semilcolon and this makes everything break on ie. I recently ran into one such bugs and had a big javascript file that had an error <em>somewhere</em> and resulted in <a href="http://www.google.co.in/search?q=expected+string+identifier+error+internet+explorer&amp;ie=utf-8&amp;oe=utf-8&amp;aq=t&amp;rls=com.ubuntu:en-US:unofficial&amp;client=firefox-a" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.google.co.in');">exptected string, identifier error</a> on ie. While looking for javascript debugging tool for ie, I found a few tools</p>
<p><a href="http://www.microsoft.com/downloads/details.aspx?familyid=e59c3964-672d-4511-bb3e-2d5e1db91038&amp;displaylang=en" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.microsoft.com');">Internet Explorer Developer Toolbar</a></p>
<p><a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=2f465be0-94fd-4569-b3c4-dffdf19ccd99&amp;displaylang=en" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.microsoft.com');">Microsoft Script Debugger</a></p>
<p>You can find some more information about these tools at <a href="http://blogs.msdn.com/ie/archive/2004/10/26/247912.aspx" onclick="javascript:pageTracker._trackPageview('/outbound/article/blogs.msdn.com');">this</a> msdn blogpost. However, the tool that eventually helped me fix the error and which is much more generic and useful is <a href="http://www.jslint.com/" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.jslint.com');">JSLint</a>. Written by <a href="//scribefire/content/editor/www.crockford.com" onclick="javascript:pageTracker._trackPageview('/outbound/article/scribefire');">Douglas Crockford</a>, this tells you not only about the errors in your javascript file but also bad coding practices that can be seen in your code. I fixed all errors listed on JSLint for my js file and all errors disappered in ie. If you are into writing javascript (for ie or firefox), do validate your code with this tool.</p>
]]></content:encoded>
			<wfw:commentRss>http://devblog.muziboo.com/2009/04/22/javascript-and-css-debugging-on-internet-explorer-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

