<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss 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/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>Railsware Blog</title>
	
	<link>http://blog.railsware.com</link>
	<description>Benefit Driven Approach</description>
	<lastBuildDate>Thu, 17 May 2012 11:20:29 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/railsware" /><feedburner:info uri="railsware" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item>
		<title>PivotalBooster version 1.1.0.beta – what’s new?</title>
		<link>http://feedproxy.google.com/~r/railsware/~3/0TWVxLlKuqI/</link>
		<comments>http://blog.railsware.com/2012/05/11/pivotalbooster-version-1-1-0-beta-whats-new/#comments</comments>
		<pubDate>Fri, 11 May 2012 17:50:13 +0000</pubDate>
		<dc:creator>Sergey Korolev</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Mac OSX]]></category>
		<category><![CDATA[Management]]></category>
		<category><![CDATA[Products]]></category>
		<category><![CDATA[osx]]></category>
		<category><![CDATA[pivotal]]></category>
		<category><![CDATA[pivotlabooster]]></category>

		<guid isPermaLink="false">http://blog.railsware.com/?p=2049</guid>
		<description><![CDATA[We are glad to announce you a major release of PivotalBooster version 1.1.0.beta. With its new and enhanced features, working with your projects, tasks and stories will become even more convenient and flexible. For example, now it is much easier &#8230; <a href="http://blog.railsware.com/2012/05/11/pivotalbooster-version-1-1-0-beta-whats-new/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>We are glad to announce you a major release of <a href="http://pivotalbooster.com/" title="PivotalBooster" target="_blank">PivotalBooster</a> version 1.1.0.beta. </br>With its new and enhanced features, working with your projects, tasks and stories will become even more convenient and flexible. For example, now it is much easier to create a new story or update an existing one in our absolutely new story detail view. Plus, the new drag-and-drop attachment feature provides you with a faster way of adding attachments. And, if you are managing several projects at once, the new filtering by the project feature is just right for you. That’s not all that new PivotalBooster has to offer to you.
<a href="http://blog.railsware.com/wp-content/uploads/2012/05/EditStoryDetails_1.png.png"><img src="http://blog.railsware.com/wp-content/uploads/2012/05/EditStoryDetails_1.png.png" alt="" title="EditStoryDetails_1.png" width="1135" height="831" class="aligncenter size-full wp-image-2066" /></a>
</p>

<span id="more-2049"></span>

<div>
<h2>What&#8217;s new</h2>
<div><strong>More Ways to Login</div></strong>
<div>Now you can login to PivotalBooster with your email or username plus password or just with your API token.</div>
<div></br></div>
<div><strong>Creating New Story With a Single Button</div></strong>
<div>There is no way faster to create a new story. You just need to click the “New Story” button or use shortcut ⌘+N. As a result, the editing form is open for you with pre-field controls ready for use.</div>
<div></br></div>
<div><strong>Updating Story Details</div></strong>
<div>Now you have full control on the story content. Simply edit your story and press ⌘+S to save changes to the service.</div>
<div></br></div>
<div><strong>Managing Tasks</div></strong>
<div>Switch to the “Tasks” tab and all the tasks of a single story will be shown. You can add new task, edit or remove old items, as well as change the order of tasks in the list.</div>
<div></br></div>
<div><strong>Enhanced Commenting</div></strong>
<div>Switch to the “Comments” tab and all the comments of the story will be fetched and displayed for you. You can now easily add new or remove old comments.</div>
<div></br></div>
<div><strong>Projects Filtering</div></strong>
<div>Managing your multiple projects is now much more convenient with new filtering by projects feature and improvements brought to the smart filtering system. You can now easily switch between projects, and your filter will be applied to the stories list and all new stories will be created in the active project.</div>
<div></br></div>
<div><strong>Switching Stories Mode</div></strong>
<div>The new story mode indicator and switcher allows you to easily switch between available modes.</div>
<div></br></div>
<div><strong>Attachments Drag-and-drop</div></strong>
<div>Just drag and drop single or multiple files to the special area and attachments will be immediately stored on the service.</div>
<div></br></div>
<div><strong>Additional Improvements</div></strong>
<div>Moreover, we’ve significantly improved cache-cleaning process, made autosync even smarter, speed up views rendering, and more. All these make work with PivotalBooster smooth and comfortable.</div>

</div>

<h2>Hot keys</h2>

<h4>Common</h4>

<ul>
    <li>⌘+N &#8211; Create a new story</li>
    <li>⌘+R &#8211; Refresh stories list</li>
    <li>⇧+⌘+R &#8211; Reset cache</li>
    <li>⌘+M &#8211; Switch stories mode</li>
    <li>⌘+L &#8211; Logout</li>
    <li>⇧+⌘+P &#8211; Open tracker dashboard on the web http://www.pivotaltracker.com/dashboard</li>
    <li>⌘+Mouse click &#8211; Open story on the web http://www.pivotaltracker.com/story/show/$STORY_ID</li>
</ul>

<h4>ID-Button</h4>

<ul>
    <li>Mouse-click &#8211; Copy <em>“$STORY_ID”</em> to the clipboard</li>
    <li>⌥+Mouse-click &#8211; Copy <em>“[#$STORY_ID]”</em> to the clipboard. Supper feature if you use integration of Pivotal Tracker with GitHub</li>
    <li>⇧+Mouse-click &#8211; Copy <em>“http://www.pivotaltracker.com/story/show/$STORY_ID”</em> to the clipboard</li>
</ul>

<h4>Story Details View</h4>

<ul>
    <li>⌘+S &#8211; Save changes to the service</li>
    <li>⌥+⌘+R &#8211; Refresh story details, comments, tasks or attachments</li>
    <li>⌘+Enter &#8211; Save new comment or task to the service</li>
</ul>
<p><a class="a2a_button_facebook_like addtoany_special_service" data-href="http://blog.railsware.com/2012/05/11/pivotalbooster-version-1-1-0-beta-whats-new/"></a><a class="a2a_button_twitter_tweet addtoany_special_service" data-count="horizontal" data-url="http://blog.railsware.com/2012/05/11/pivotalbooster-version-1-1-0-beta-whats-new/" data-text="PivotalBooster version 1.1.0.beta &#8211; what&#8217;s new?"></a><a class="a2a_button_google_plusone addtoany_special_service" data-href="http://blog.railsware.com/2012/05/11/pivotalbooster-version-1-1-0-beta-whats-new/"></a><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fblog.railsware.com%2F2012%2F05%2F11%2Fpivotalbooster-version-1-1-0-beta-whats-new%2F&amp;title=PivotalBooster%20version%201.1.0.beta%20%E2%80%93%20what%E2%80%99s%20new%3F" id="wpa2a_2"><img src="http://blog.railsware.com/wp-content/plugins/add-to-any/share_save_120_16.png" width="120" height="16" alt="Share"/></a></p><img src="http://feeds.feedburner.com/~r/railsware/~4/0TWVxLlKuqI" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.railsware.com/2012/05/11/pivotalbooster-version-1-1-0-beta-whats-new/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://blog.railsware.com/2012/05/11/pivotalbooster-version-1-1-0-beta-whats-new/</feedburner:origLink></item>
		<item>
		<title>Libskypekit and Skypekit – C and Ruby interface for Skype</title>
		<link>http://feedproxy.google.com/~r/railsware/~3/zkvTn8qaoxI/</link>
		<comments>http://blog.railsware.com/2012/05/11/libskypekit-and-skypekit-c-and-ruby-interface-for-skype/#comments</comments>
		<pubDate>Fri, 11 May 2012 10:22:03 +0000</pubDate>
		<dc:creator>Andriy Yanko</dc:creator>
				<category><![CDATA[Random]]></category>
		<category><![CDATA[c]]></category>
		<category><![CDATA[ffi]]></category>
		<category><![CDATA[libskypekit]]></category>
		<category><![CDATA[skypekit]]></category>

		<guid isPermaLink="false">http://blog.railsware.com/?p=2023</guid>
		<description><![CDATA[Preface There are two methods to programmatically use Skype: Via the native desktop Skype application using Skype Desktop API Via SkypeKit Runtime using SkypeKit SDK wrapper. The first method is rather slow due to an interaction with the user interface. &#8230; <a href="http://blog.railsware.com/2012/05/11/libskypekit-and-skypekit-c-and-ruby-interface-for-skype/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<h2>Preface</h2>

<p>There are two methods to programmatically use Skype:</p>

<ul>
<li>Via the native desktop Skype application using <a href="http://developer.skype.com/public-api-reference">Skype Desktop API</a></li>
<li>Via <a href="http://developer.skype.com/public/skypekit">SkypeKit</a> Runtime using SkypeKit SDK wrapper.</li>
</ul>

<p>The first method is rather slow due to an interaction with the user interface. The second one is more interesting as there is no UI application.</p>

<p>SkypeKit SDK includes only wrappers for:</p>

<ul>
<li>C++</li>
<li>Python</li>
<li>Java</li>
</ul>

<p>Is Ruby wrapper missed? No more!</p>

<span id="more-2023"></span>

<h2>On the way to gem</h2>

<p>Before releasing gem, we tried several approaches. We tried to implement SkypeKit in pure Ruby as it done in SkypeKit Python Wrapper. But then, we realized that even if we make do it, its implementation will not be as fast as it should be. Then, we started to write a C extension for Ruby using the SkypeKit C++ Wrapper. But  then, we admitted that this implementation will be inefficient due to asynchronous SkypeKit API and pure Ruby thread. Finally, we came to the implementation via Ruby FFI. We think that it&#8217;s the best way to do it because:</p>

<ul>
<li>Thread stuff are completely on C side.</li>
<li>Synchronous program is easy to debug an test.</li>
<li>SkypeKit gem works in Ruby.</li>
<li>SkypeKit gem works in <strong>jRuby</strong>!</li>
<li>It&#8217;s possible to quickly implement SkypeKit in Perl/Python/lua/etc.</li>
</ul>

<h2>SkypeKit C library</h2>

<p><a href="https://github.com/railsware/libskypekit">Libskypekit</a> is a simple C library that brings <strong>asynchronous</strong> SkypeKit C++ wrapper functionality to the usual <strong>synchronous</strong> C applications.</p>

<p>The goal of Libskypekit is to catch all asynchronous callbacks of SkypeKit C++ SDK and push them as events into a simple queue. Then synchronous application can pull this queue, retrieve each event and process it.</p>

<p>Libskypekit is rather a young library, but we have already implemented the next basic events:</p>

<ul>
<li>Account status changed</li>
<li>Chat message received</li>
</ul>

<p>It&#8217;s enough to write simple chat applications. If your are familiar with C language look at
<a href="https://github.com/railsware/libskypekit/blob/master/examples/ping_pong.c">ping_pong example</a></p>

<p>Is Ruby wrapper still missed? No more! <img src='http://blog.railsware.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>

<h2>Skypekit Ruby gem</h2>

<p>Thus LibskypeKit has a simple API, it&#8217;s was relatively easy to create a Ruby library using <a href="https://github.com/ffi/ffi">Ruby FFI</a>.</p>

<p>Plus the <a href="https://github.com/railsware/skypekit">Skypekit Ruby library</a> provides a simple interface. For example, look at <em>ping_pong</em> example:</p>


<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="ruby"><pre class="de1"><span class="kw3">require</span> <span class="st0">&quot;skypekit&quot;</span>
&nbsp;
<span class="re0">$skype</span> = <span class="re2">Skypekit::Skype</span>.<span class="me1">new</span><span class="br0">&#40;</span><span class="re3">:keyfile</span> <span class="sy0">=&gt;</span> <span class="st0">'myskypekit.pem'</span><span class="br0">&#41;</span>
&nbsp;
<span class="re0">$skype</span>.<span class="me1">start</span>
<span class="re0">$skype</span>.<span class="me1">login</span><span class="br0">&#40;</span><span class="st0">'myskypename'</span>, <span class="st0">'mypassword'</span><span class="br0">&#41;</span>
&nbsp;
<span class="kw1">def</span> terminate
  <span class="kw3">puts</span> <span class="st0">&quot;Terminating&quot;</span>
  <span class="re0">$skype</span>.<span class="me1">stop</span>
  <span class="kw3">exit</span>
<span class="kw1">end</span>
&nbsp;
<span class="kw3">trap</span><span class="br0">&#40;</span><span class="st0">'INT'</span><span class="br0">&#41;</span> <span class="kw1">do</span>
  terminate
<span class="kw1">end</span>
&nbsp;
<span class="kw3">loop</span> <span class="kw1">do</span>
  event = <span class="re0">$skype</span>.<span class="me1">get_event</span>
&nbsp;
  <span class="kw1">unless</span> event
    <span class="kw3">sleep</span> <span class="nu0">5</span>
    <span class="kw1">next</span>
  <span class="kw1">end</span>
&nbsp;
  <span class="kw1">case</span> event.<span class="me1">type</span>
  <span class="kw1">when</span> <span class="re3">:account_status</span>
&nbsp;
    <span class="kw1">if</span> event.<span class="me1">data</span>.<span class="me1">logged_in</span>?
      <span class="kw3">puts</span> <span class="st0">&quot;Congrats! We are Logged in!&quot;</span>
    <span class="kw1">end</span>
&nbsp;
    <span class="kw1">if</span> event.<span class="me1">data</span>.<span class="me1">logged_out</span>?
      <span class="kw3">puts</span> <span class="st0">&quot;Authentication failed: #{event.data.reason}&quot;</span>
      terminate
    <span class="kw1">end</span>
&nbsp;
  <span class="kw1">when</span> <span class="re3">:chat_message</span>
    message = event.<span class="me1">data</span>
&nbsp;
    <span class="kw3">puts</span> <span class="st0">&quot;@&quot;</span> <span class="sy0">*</span> <span class="nu0">80</span>
    <span class="kw3">p</span> message
    <span class="kw3">puts</span> <span class="st0">&quot;@&quot;</span> <span class="sy0">*</span> <span class="nu0">80</span>
&nbsp;
    <span class="kw1">if</span> message.<span class="me1">body</span> == <span class="st0">&quot;ping&quot;</span>
      <span class="re0">$skype</span>.<span class="me1">send_chat_message</span><span class="br0">&#40;</span>message.<span class="me1">convo_id</span>, <span class="st0">&quot;pong&quot;</span><span class="br0">&#41;</span>
    <span class="kw1">end</span>
&nbsp;
  <span class="kw1">end</span>
<span class="kw1">end</span></pre></div></div></div></div></div></div></div>




<h2>I want try it</h2>

<p>In order to play with SkypeKit gem you need:</p>

<ul>
<li>Register at <a href="http://developer.skype.com/">developer.skype.com</a></li>
<li>Obtain SkypeKit SDK</li>
<li>Obtain SkypeKit Runtime</li>
<li>Obtain SkypeKit personal keypair</li>
</ul>

<p>Then:</p>

<ul>
<li>Compile SkypeKit SDK &#8211; see SDK documentation</li>
<li>Compile LibSkypeKit &#8211; see README in repository</li>
<li>Install SkypeKit gem &#8211; see README in repository</li>
</ul>

<p>Now you can play with it.</p>

<h2>Legal part</h2>

<p>Libskypekit and Skypekit gem are both released under the <a href="http://www.opensource.org/licenses/MIT">MIT license</a>.</p>

<p>But SkypeKit SDK is not!</p>

<p>Please <em>carefully</em> read <a href="http://developer.skype.com/skypekit/legal/license">SkypeKit License Agreement</a>.</p>

<p>There are a lot of restrictions!</p>

<h2>References</h2>

<ul>
<li><a href="http://developer.skype.com/public/skypekit">SkypeKit SDK</a></li>
<li><a href="http://developer.skype.com/public-api-reference">SkypeKit Desktop API</a></li>
<li><a href="http://developer.skype.com/certify-market/legal/desktop-api/terms-of-use">Skype API Terms of Use</a></li>
<li><a href="http://railsware.github.com/libskypekit">Skypekit C library</a></li>
<li><a href="http://railsware.github.com/skypekit/">Skypekit Ruby library</a></li>
<li><a href="https://rubygems.org/gems/skypekit">Skypekit Ruby gem</a></li>
<li><a href="https://github.com/ffi/ffi">Ruby FFI gem</a></li>
</ul>
<p><a class="a2a_button_facebook_like addtoany_special_service" data-href="http://blog.railsware.com/2012/05/11/libskypekit-and-skypekit-c-and-ruby-interface-for-skype/"></a><a class="a2a_button_twitter_tweet addtoany_special_service" data-count="horizontal" data-url="http://blog.railsware.com/2012/05/11/libskypekit-and-skypekit-c-and-ruby-interface-for-skype/" data-text="Libskypekit and Skypekit &#8211; C and Ruby interface for Skype"></a><a class="a2a_button_google_plusone addtoany_special_service" data-href="http://blog.railsware.com/2012/05/11/libskypekit-and-skypekit-c-and-ruby-interface-for-skype/"></a><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fblog.railsware.com%2F2012%2F05%2F11%2Flibskypekit-and-skypekit-c-and-ruby-interface-for-skype%2F&amp;title=Libskypekit%20and%20Skypekit%20%E2%80%93%20C%20and%20Ruby%20interface%20for%20Skype" id="wpa2a_4"><img src="http://blog.railsware.com/wp-content/plugins/add-to-any/share_save_120_16.png" width="120" height="16" alt="Share"/></a></p><img src="http://feeds.feedburner.com/~r/railsware/~4/zkvTn8qaoxI" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.railsware.com/2012/05/11/libskypekit-and-skypekit-c-and-ruby-interface-for-skype/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://blog.railsware.com/2012/05/11/libskypekit-and-skypekit-c-and-ruby-interface-for-skype/</feedburner:origLink></item>
		<item>
		<title>Effective similarity search in PostgreSQL</title>
		<link>http://feedproxy.google.com/~r/railsware/~3/-nmrph0Rc2M/</link>
		<comments>http://blog.railsware.com/2012/05/10/effective-similarity-search-in-postgresql/#comments</comments>
		<pubDate>Thu, 10 May 2012 05:00:09 +0000</pubDate>
		<dc:creator>Alexey Vasiliev</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[extension]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[postgresql]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[search]]></category>
		<category><![CDATA[smlar]]></category>

		<guid isPermaLink="false">http://blog.railsware.com/?p=1941</guid>
		<description><![CDATA[Hello my dear friends. In &#8220;PostgreSQL most useful extensions&#8221; I showed a list of some useful extensions for PostgreSQL. Of course, that article didn&#8217;t cover all useful extensions (in my humble opinion) and some extensions I want to describe in &#8230; <a href="http://blog.railsware.com/2012/05/10/effective-similarity-search-in-postgresql/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Hello my dear friends. In &#8220;<a href="http://blog.railsware.com/2012/04/23/postgresql-most-useful-extensions/">PostgreSQL most useful extensions</a>&#8221; I showed a list of some useful extensions for PostgreSQL. Of course, that article didn&#8217;t cover all useful extensions (in my humble opinion) and some extensions I want to describe in separate articles. Today we will talk about effective similarity search in PostgreSQL.</p>

<p>Similarity search in large databases is an important issue in nowadays informational services, such as recommender systems, blogs (similar articles), online shops (similar products), image hosting services (similar images, search image duplicates) etc. PostgreSQL allows to make such things more easy. First you need to understand how we will calculate the similarity of two objects.
<span id="more-1941"></span></p>

<h1>Similarity</h1>

<p>Any object can be described by a list of characteristics. For example, article in blog can be described by tags, product in online shop &#8211; by size, weight, color etc. It means that for each object we can create the digital signature &#8211; array of numbers, which describing the object (<a href="http://en.wikipedia.org/wiki/Fingerprint">fingerprint</a>, <a href="http://en.wikipedia.org/wiki/N-gram">n-grams</a>). Let&#8217;s create an array of not ordered numbers for every object. What should we do next?</p>

<h1>Similarity calculation</h1>

<p>There are several methods for calculating the similarity of objects by signatures. First of all, the legend for calculations:</p>

<p>Na, Nb &#8211; the number of unique elements in the arrays</p>

<p>Nu &#8211; the number of unique elements in the union of sets</p>

<p>Ni &#8211; the number of unique elements in the intersection of arrays</p>

<p>One of the simplest calculation of the similarity of two objects is the number of unique elements in the intersection of arrays divided by the number of unique elements in two arrays:</p>

<p><img src="http://latex.codecogs.com/png.latex?\LARGE%20\dpi{120}%20\fn_phv%20S(A,B)%20=%20\frac{N_{i}}{(N_{a}%20+%20N_{b})}" alt="simplest" class="aligncenter size-full" /></p>

<p>or only</p>

<p><img src="http://latex.codecogs.com/png.latex?\LARGE%20\dpi{120}%20\fn_phv%20S(A,B)%20=%20\frac{N_{i}}{N_{u}}" alt="simplest" class="aligncenter size-full" /></p>

<p>Pros:</p>

<ul>
<li>Easy to understand</li>
<li>Speed of calculation: N * log(N)</li>
<li>Works well at similar and large Na and Nb</li>
</ul>

<p>Similarity can also be calculated using the formula of cosines:</p>

<p><img src="http://latex.codecogs.com/png.latex?\LARGE%20\dpi{120}%20\fn_phv%20S(A,B)%20=%20\frac{N_{i}}{\sqrt{N_{a}%20*%20N_{b}}}" alt="simplest" class="aligncenter size-full" /></p>

<p>Pros:</p>

<ul>
<li>Speed of calculation: N * log(N)</li>
<li>Works well for large N</li>
</ul>

<p>But both of these metrics have common problems:</p>

<ul>
<li>Few elements -> large scatter of similarity</li>
<li>Frequent elements -> weight below</li>
</ul>

<p><a href="http://en.wikipedia.org/wiki/Tf*idf">TF/IDF</a> metric avoids these problems to calculate the similarity:</p>

<p><img src="http://latex.codecogs.com/png.latex?\LARGE%20\dpi{120}%20\fn_phv%20S(A,B)%20=%20\frac{\sum_{i%20%3C%20N_{a},%20j%20%3C%20N_{b},%20A_{i}%20=%20B_{j}}TF_{i}%20*%20TF_{j}}{\sqrt{\sum_{i%20%3C%20N_{a}}TF_{i}^{2}%20*%20\sum_{j%20%3C%20N_{b}}TF_{j}^{2}}}" alt="simplest" class="aligncenter size-full" /></p>

<p>where</p>

<p><img src="http://latex.codecogs.com/png.latex?\LARGE%20\dpi{120}%20\fn_phv%20IDF_{element}%20=%20log(\frac{N_{objects}}{N_{objects\%20with\%20element}}%20+%201)" alt="simplest" class="aligncenter size-full" /></p>

<p><img src="http://latex.codecogs.com/png.latex?\LARGE%20\dpi{120}%20\fn_phv%20TF_{element}%20=%20IDF_{element}%20*%20N_{occurrences}" alt="simplest" class="aligncenter size-full" /></p>

<p>Now it would be great to use this knowledge in practice.</p>

<h1>Smlar extension for PostgreSQL</h1>

<p>Oleg Bartunov and Teodor Sigaev developed PostgreSQL extension, called smlar, which provides several methods to calculate sets similarity (all built-in data types supported), similarity operator with indexing support on the base of GiST and GIN frameworks. Let&#8217;s look how to work with this extension. First of all, we need install it (PostgreSQL should be already installed):</p>

<pre><code>git clone git://sigaev.ru/smlar
cd smlar
USE_PGXS=1 make &amp;&amp; make install
</code></pre>

<p>On PostgreSQL 9.2 this extension should build without problem, for PostgreSQL 9.1 and earlier you need to make a little fix. In file &#8220;smlar_guc.c&#8221; on line 214 change call</p>

<pre><code>set_config_option("smlar.threshold", buf,
                                            PGC_USERSET, PGC_S_SESSION ,GUC_ACTION_SET, true, 0);
</code></pre>

<p>to this (delete last argument)</p>

<pre><code>set_config_option("smlar.threshold", buf,
                                            PGC_USERSET, PGC_S_SESSION ,GUC_ACTION_SET, true);
</code></pre>

<p>Let&#8217;s test instaled extension:</p>

<pre><code>$ psql -d test
psql (9.1.3)
Type "help" for help.

test=# CREATE EXTENSION smlar;
CREATE EXTENSION

test=# SELECT smlar('{1,4,6}'::int[], '{5,4,6}' );
  smlar  
----------
 0.666667
(1 row)


test=# SELECT smlar('{1,4,6}'::int[], '{5,4,6}', 'N.i / sqrt(N.a * N.b)' );
  smlar  
----------
 0.666667
(1 row)
</code></pre>

<p>If you have the same output in console, you&#8217;ve installed extension successful. More information about this extension you can read in README file.</p>

<p>Function smlar computes similary of two arrays (arrays should be the same type) and return float from 0 to 1 (0 &#8211; absolutely no similar objects, 1 &#8211; absolutely similar arrays, equal). Function can take the third argument &#8211; the formula, that calculates the similarity of the two arrays. Module provides several GUC variables and it&#8217;s highly recommended to add to postgesql.conf:</p>

<pre><code>custom_variable_classes = 'smlar'       # list of custom variable class names
smlar.threshold = 0.8  # or any other value &gt; 0 and &lt; 1
</code></pre>

<p>Array&#8217;s with similarity lower than &#8216;smlar.threshold&#8217; are not similar by % operation.</p>

<pre><code>test=# SELECT '{1,4,6,5,7,9}'::int[] % '{1,5,4,6,7,8,9}'::int[] as similar;
 similar
---------
 t
(1 row)
</code></pre>

<p>GiST/GIN support for % operation. The parameter &#8220;similar.type&#8221; allows you to specify what kind of formula used to calculate the similarity: cosine (default), overlap or tfidf. For &#8220;tfidf&#8221; need to make additional configuration, but I will not consider this in the article (all can be found in the README file). Now let&#8217;s consider an example of using this extension.</p>

<h1>Finding duplicate of images</h1>

<p>For example, I select the search for duplicate images. Other options for shopping, blogs are implemented in a similar way. The algorithm helps to find similar images that are slightly different: desaturated images, add watermark, passed through the filters.</p>

<p>In our algorithm, we will create a pixel matrix of each image. Let it be 15&#215;15 pixels. The next step: we do not know the color of a pixel, but its intensity (the intensity is given by 0.299 * red + 0,587 * green + 0,114 * blue). Calculating the intensity will help us find the image is not paying attention to the colors of the images.</p>

<p><a href="http://blog.railsware.com/wp-content/uploads/2012/04/1.jpg"><img src="http://blog.railsware.com/wp-content/uploads/2012/04/1.jpg" alt="" title="1" width="800" height="600" class="aligncenter size-full wp-image-1950" /></a></p>

<p>Once you have to calculate the intensity of all pixels in a 15&#215;15 matrix, we find the ratio of the intensity of each pixel to the mean intensity of the matrix, and generate a unique number for each cell (in the code to generate unique for each cell, I added the coordinates to intensity) and obtain an array of 225 elements length (15 * 15 = 225). Excellent.</p>

<p><a href="http://blog.railsware.com/wp-content/uploads/2012/04/2.jpg"><img src="http://blog.railsware.com/wp-content/uploads/2012/04/2.jpg" alt="" title="2" width="800" height="333" class="aligncenter size-full wp-image-1951" /></a></p>

<p>Below is the code to generate a digital signature for images on Ruby and PHP languages:</p>

<p><a href="https://gist.github.com/2521687">Ruby</a></p>

<script src="https://gist.github.com/2521687.js"> </script>

<p><a href="https://gist.github.com/2521710">PHP</a></p>

<script src="https://gist.github.com/2521710.js"> </script>

<table style="margin-left: auto; margin-right: auto;">
<tbody>
<tr>
<td>
<a href="http://blog.railsware.com/wp-content/uploads/2012/04/chart1.png"><img src="http://blog.railsware.com/wp-content/uploads/2012/04/chart1.png" alt="" title="chart1" width="300" height="225" class="alignleft size-full wp-image-1956" /></a>
</td>
<td>
<a href="http://blog.railsware.com/wp-content/uploads/2012/04/chart2.png"><img src="http://blog.railsware.com/wp-content/uploads/2012/04/chart2.png" alt="" title="chart2" width="300" height="225" class="alignleft size-full wp-image-1957" /></a>
</td>
</tr>
<tr>
<td style="padding: 5px; text-align: center;" colspan="2">
<strong>61,33% similarity</strong>
</td>
</tr>
</tbody>
</table>

<table style="margin-left: auto; margin-right: auto;">
<tbody>
<tr>
<td>
<a href="http://blog.railsware.com/wp-content/uploads/2012/04/11.png"><img src="http://blog.railsware.com/wp-content/uploads/2012/04/11-300x300.png" alt="" title="11" width="300" height="300" class="aligncenter size-medium wp-image-1952" /></a>
</td>
<td>
<a href="http://blog.railsware.com/wp-content/uploads/2012/04/12.gif"><img src="http://blog.railsware.com/wp-content/uploads/2012/04/12-264x300.gif" alt="" title="12" width="264" height="300" class="aligncenter size-medium wp-image-1953" /></a>
</td>
</tr>
<tr>
<td style="padding: 5px; text-align: center;" colspan="2">
<strong>23,56% similarity</strong>
</td>
</tr>
</tbody>
</table>

<table style="margin-left: auto; margin-right: auto;">
<tbody>
<tr>
<td>
<a href="http://blog.railsware.com/wp-content/uploads/2012/04/689545_65148464.jpg"><img src="http://blog.railsware.com/wp-content/uploads/2012/04/689545_65148464-300x225.jpg" alt="" title="689545_65148464" width="300" height="225" class="aligncenter size-medium wp-image-1954" /></a>
</td>
<td>
<a href="http://blog.railsware.com/wp-content/uploads/2012/04/689545_651484642.jpg"><img src="http://blog.railsware.com/wp-content/uploads/2012/04/689545_651484642-300x225.jpg" alt="" title="689545_651484642" width="300" height="225" class="aligncenter size-medium wp-image-1955" /></a>
</td>
</tr>
<tr>
<td style="padding: 5px; text-align: center;" colspan="2">
<strong>87,55% similarity</strong>
</td>
</tr>
</tbody>
</table>

<p>Excellent, but it is comparing two images. Now let&#8217;s use PostgreSQL for searching. In PostgreSQL is an array type of the field. We will write the digital signature of the image:</p>

<pre><code>CREATE TABLE images (
 id serial PRIMARY KEY,
 name varchar(50),
 image_array integer[]
);

INSERT into images(image_array) VALUES ('{1010257,...,2424257}');

test=# SELECT count(*) from images;
 count 
--------
 200000
(1 row)

test=# EXPLAIN ANALYZE SELECT id FROM images WHERE images.image_array % '{1010259,...,2424252}'::int[];


Aggregate  (cost=14.58..14.59 rows=1 width=0) (actual time=1.785..1.785 rows=1 loops=1)
   -&gt;  Seq Scan on images  (cost=0.00..14.50 rows=33 width=0) (actual time=0.115..1.772 rows=20 loops=1)
         Filter: (image_array % '{1010259,1011253,...,2423253,2424252}'::integer[])
 Total runtime: 5152.819 ms
(4 rows)
</code></pre>

<p>It works, but search works without index. Let&#8217;s create it:</p>

<pre><code>CREATE INDEX image_array_gin ON images USING GIN(image_array _int4_sml_ops);
</code></pre>

<p>or</p>

<pre><code>CREATE INDEX image_array_gist ON images USING GIST(image_array _int4_sml_ops);
</code></pre>

<p>Difference between GiST and GIN indexes you can read <a href="http://www.postgresql.org/docs/9.1/static/textsearch-indexes.html">here</a>.</p>

<pre><code>test=# EXPLAIN ANALYZE SELECT id FROM images WHERE images.image_array % '{1010259,1011253,...,2423253,2424252}'::int[];



 Aggregate  (cost=815.75..815.76 rows=1 width=0) (actual time=320.428..320.428 rows=1 loops=1)
   -&gt;  Bitmap Heap Scan on images  (cost=66.42..815.25 rows=200 width=0) (actual time=108.127..304.524 rows=40000 loops=1)
         Recheck Cond: (image_array % '{1010259,1011253,...,2424252}'::integer[])
         -&gt;  Bitmap Index Scan on image_array_gist  (cost=0.00..66.37 rows=200 width=0) (actual time=90.814..90.814 rows=40000 loops=1)
               Index Cond: (image_array % '{1010259,1011253,...,2424252}'::integer[])
 Total runtime: 320.487 ms
(6 rows)
</code></pre>

<p>Perfect! Let&#8217;s check performance.</p>

<pre><code>test=# SELECT count(*) from images;
  count 
---------
 1000000
(1 row)


test=# EXPLAIN ANALYZE SELECT count(*) FROM images WHERE images.image_array % '{1010259,1011253,...,2423253,2424252}'::int[];


 Bitmap Heap Scan on images  (cost=286.64..3969.45 rows=986 width=4) (actual time=504.312..2047.533 rows=200000 loops=1)
   Recheck Cond: (image_array % '{1010259,1011253,...,2423253,2424252}'::integer[])
   -&gt;  Bitmap Index Scan on image_array_gist  (cost=0.00..286.39 rows=986 width=0) (actual time=446.109..446.109 rows=200000 loops=1)
         Index Cond: (image_array % '{1010259,1011253,...,2423253,2424252}'::integer[])
 Total runtime: 2152.411 ms
(5 rows)
</code></pre>

<p>Let&#8217;s add sorting in SQL (the most similar images were the first), and add similarity as extra field:</p>

<pre><code>EXPLAIN ANALYZE SELECT smlar(images.image_array, '{1010259,...,2424252}'::int[]) as similarity FROM images WHERE images.image_array % '{1010259,1011253, ...,2423253,2424252}'::int[] ORDER BY similarity DESC; 


 Sort  (cost=4020.94..4023.41 rows=986 width=924) (actual time=2888.472..2901.977 rows=200000 loops=1)
   Sort Key: (smlar(image_array, '{...,2424252}'::integer[]))
   Sort Method: quicksort  Memory: 15520kB
   -&gt;  Bitmap Heap Scan on images  (cost=286.64..3971.91 rows=986 width=924) (actual time=474.436..2729.638 rows=200000 loops=1)
         Recheck Cond: (image_array % '{...,2424252}'::integer[])
         -&gt;  Bitmap Index Scan on image_array_gist  (cost=0.00..286.39 rows=986 width=0) (actual time=421.140..421.140 rows=200000 loops=1)
               Index Cond: (image_array % '{...,2424252}'::integer[])
 Total runtime: 2912.207 ms
(8 rows)
</code></pre>

<p>Added sorting did not complicate query execution.</p>

<p><a href="https://gist.github.com/2521808">Here</a> you can see all results in raw format.</p>

<h1>Conclusion</h1>

<p>PostgreSQL extension smlar can be used in systems where we need search similar objects, like texts, images, videos.</p>

<p><em>That’s all folks!</em> Thank you for reading till the end.</p>
<p><a class="a2a_button_facebook_like addtoany_special_service" data-href="http://blog.railsware.com/2012/05/10/effective-similarity-search-in-postgresql/"></a><a class="a2a_button_twitter_tweet addtoany_special_service" data-count="horizontal" data-url="http://blog.railsware.com/2012/05/10/effective-similarity-search-in-postgresql/" data-text="Effective similarity search in PostgreSQL"></a><a class="a2a_button_google_plusone addtoany_special_service" data-href="http://blog.railsware.com/2012/05/10/effective-similarity-search-in-postgresql/"></a><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fblog.railsware.com%2F2012%2F05%2F10%2Feffective-similarity-search-in-postgresql%2F&amp;title=Effective%20similarity%20search%20in%20PostgreSQL" id="wpa2a_6"><img src="http://blog.railsware.com/wp-content/plugins/add-to-any/share_save_120_16.png" width="120" height="16" alt="Share"/></a></p><img src="http://feeds.feedburner.com/~r/railsware/~4/-nmrph0Rc2M" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.railsware.com/2012/05/10/effective-similarity-search-in-postgresql/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		<feedburner:origLink>http://blog.railsware.com/2012/05/10/effective-similarity-search-in-postgresql/</feedburner:origLink></item>
		<item>
		<title>Speed up your ActiveResources!</title>
		<link>http://feedproxy.google.com/~r/railsware/~3/o9V1_L3ZgQk/</link>
		<comments>http://blog.railsware.com/2012/04/26/speed-up-your-activeresources/#comments</comments>
		<pubDate>Thu, 26 Apr 2012 15:43:06 +0000</pubDate>
		<dc:creator>Andriy Yanko</dc:creator>
				<category><![CDATA[Random]]></category>
		<category><![CDATA[activeresource]]></category>
		<category><![CDATA[http]]></category>
		<category><![CDATA[keep-alive]]></category>
		<category><![CDATA[soa]]></category>

		<guid isPermaLink="false">http://blog.railsware.com/?p=1925</guid>
		<description><![CDATA[Preface In non trivial projects we often use SOA approach. Thereby one big monolithic application can be segregated into smaller applications or services. The benefit is obvious &#8211; it&#8217;s easy to control and maintain small applications. If you use Rails &#8230; <a href="http://blog.railsware.com/2012/04/26/speed-up-your-activeresources/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<h2>Preface</h2>

<p>In non trivial projects we often use <a href="http://en.wikipedia.org/wiki/Service-oriented_architecture">SOA</a> approach.
Thereby one big monolithic application can be segregated into smaller applications or services. The benefit is obvious &#8211; it&#8217;s easy to control and maintain small applications. If you use <a href="http://rubyonrails.org/">Rails framework</a> you probably already use <a href="https://github.com/rails/ActiveResource">ActiveResource</a> for requesting your services because if follows ActiveRecord conventions.</p>

<p>Definitely ActiveResource operations are much slower than ActiveRecord operations because first one use HTTP connection and second one use usually <em>persistent</em> connection to database and database is usually always faster than application service.</p>

<p>But modern HTTP/1.1 servers support <a href="http://en.wikipedia.org/wiki/HTTP_persistent_connection">persistent connection</a> and as Ilya Grigorik already mentioned in his awesome <a href="http://www.igvita.com/2011/10/04/optimizing-http-keep-alive-and-pipelining/">article</a> we can have serious speedup for resources usage.</p>

<p>The problem is that <a href="https://rails.lighthouseapp.com/projects/8994/tickets/1513-activeresource-does-not-support-keep-alive-connections">ActiveResource does not support keep-alive connections</a>.</p>

<p>But not for Railsware <img src='http://blog.railsware.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> .</p>

<span id="more-1925"></span>

<h2>ActiveResource is Persistent</h2>

<p>After playing a bit with sources we released small gem <a href="https://rubygems.org/gems/activeresource-persistent">ActiveResource::Persistent</a> that allows ActiveResource to use HTTP keep-alive feature.</p>

<h2>Installation</h2>

<p>Installation is trivial. Just drop line into your Gemfile</p>

<pre><code>gem 'activeresource-persistent', :require =&gt; 'active_resource/persistent'
</code></pre>

<p>And all your resources will automatically reuse connections to services!
You should NOT modify any line of your code.</p>

<h2>Under the hood</h2>

<p>Persistent connections are handled by excellent <a href="https://rubygems.org/gems/net-http-persistent">net-http-persistent</a> library. The gem actually is very simple and provides ActiveResource::Persistent::HTTP object wrapper for ActiveResource.</p>

<p>However we covered library with specs that ensure it will work with different ActiveResource versions.</p>

<p>Currently it works with:</p>

<ul>
<li>v2.3.x</li>
<li>v3.0.x</li>
<li>v3.1.x</li>
<li>v3.2.x</li>
</ul>

<p>Enjoy! <img src='http://blog.railsware.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>

<h2>References</h2>

<ul>
<li><a href="https://rubygems.org/gems/activeresource-persistent">ActiveResource::Persistent gem</a></li>
<li><a href="https://github.com/railsware/activeresource-persistent">ActiveResource::Persistent repository</a></li>
<li><a href="http://www.igvita.com/2011/10/04/optimizing-http-keep-alive-and-pipelining/">Optimizing HTTP: Keep-alive and Pipelining</a></li>
<li><a href="https://rails.lighthouseapp.com/projects/8994/tickets/1513-activeresource-does-not-support-keep-alive-connections">ActiveResource does not support keep-alive connections</a></li>
<li><a href="https://rubygems.org/gems/net-http-persistent">net-http-persistent gem</a></li>
</ul>
<p><a class="a2a_button_facebook_like addtoany_special_service" data-href="http://blog.railsware.com/2012/04/26/speed-up-your-activeresources/"></a><a class="a2a_button_twitter_tweet addtoany_special_service" data-count="horizontal" data-url="http://blog.railsware.com/2012/04/26/speed-up-your-activeresources/" data-text="Speed up your ActiveResources!"></a><a class="a2a_button_google_plusone addtoany_special_service" data-href="http://blog.railsware.com/2012/04/26/speed-up-your-activeresources/"></a><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fblog.railsware.com%2F2012%2F04%2F26%2Fspeed-up-your-activeresources%2F&amp;title=Speed%20up%20your%20ActiveResources%21" id="wpa2a_8"><img src="http://blog.railsware.com/wp-content/plugins/add-to-any/share_save_120_16.png" width="120" height="16" alt="Share"/></a></p><img src="http://feeds.feedburner.com/~r/railsware/~4/o9V1_L3ZgQk" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.railsware.com/2012/04/26/speed-up-your-activeresources/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://blog.railsware.com/2012/04/26/speed-up-your-activeresources/</feedburner:origLink></item>
		<item>
		<title>From Photoshop to Fireworks and back. Part 1.</title>
		<link>http://feedproxy.google.com/~r/railsware/~3/fBDvUlEYX9k/</link>
		<comments>http://blog.railsware.com/2012/04/26/from-photoshop-to-fireworks-and-back-part-1/#comments</comments>
		<pubDate>Thu, 26 Apr 2012 11:00:27 +0000</pubDate>
		<dc:creator>Andrey Khorolets</dc:creator>
				<category><![CDATA[Design]]></category>
		<category><![CDATA[comparison]]></category>
		<category><![CDATA[FireWorks]]></category>
		<category><![CDATA[Photoshop]]></category>
		<category><![CDATA[UI]]></category>

		<guid isPermaLink="false">http://blog.railsware.com/?p=1879</guid>
		<description><![CDATA[Here is the first part of the tour I&#8217;ve announced earlier. I&#8217;m going to use Photoshop CS4 and Fireworks CS5 and hope there will be no significant differences if you are using other versions. Also, my way around PS could &#8230; <a href="http://blog.railsware.com/2012/04/26/from-photoshop-to-fireworks-and-back-part-1/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Here is the first part of the tour I&#8217;ve announced <a title="From Photoshop to Fireworks and back. Intro." href="http://blog.railsware.com/2012/04/05/from-photoshop-to-fireworks-and-back/" target="_blank">earlier</a>.</p>

<p>I&#8217;m going to use Photoshop CS4 and Fireworks CS5 and hope there will be no significant differences if you are using other versions. Also, my way around PS could be different from yours, so please don&#8217;t take any of my advise as immediate call to action, be flexible. 
<span id="more-1879"></span></p>

<h1>Concept</h1>

<p>What I&#8217;m trying to do here is to get most of our PS experience to FW. Since we are not switching to FW completely &#8212; I&#8217;d recommend you not to use FW features full throttle yet, at least not all of them. And to keep the balance &#8212; same goes for PS. We&#8217;ll try to avoid using some specific stuff in both applications to make our files reasonably compatible and switching back and forth as easy as possible.</p>

<p>OK, a little less conversation, a little more action.</p>

<h1>Preferences</h1>

<p>The one and only thing I recommend adjusting there for now is to turn mouse highlight off in Edit section of FW (it will show you object boundaries when you mouse over). It&#8217;s the first thing that will make FW interface feel alien to you comparing to PS and we don&#8217;t want that, do we?
<img src="http://dl.dropbox.com/u/2085924/p1/preferences.png" alt="" />
I guess It could be handy while exploring a file of your colleague&#8217;s creation to overview the structure, but you should well know what is where in your own, so it looks a bit excessive to me.</p>

<h1>Keyboard shortcuts</h1>

<p>You can select &#8220;Photoshop&#8221; shortcuts from the &#8220;Current set&#8221;, but if you are anything like me you have a lot of shortcuts remapped to easy use with one hand and a bunch of your own exclusive ones for frequent operations &#8212; this option can&#8217;t get you covered completely. So transit as much of your PS shortcuts to FW as you can and create new ones as you explore FW.
<img src="http://dl.dropbox.com/u/2085924/p1/hotkeys.png" alt="Keyboard Shortcuts" /></p>

<p><strong>Few hints:</strong></p>

<ul>
    <li>There is a useful, in some cases, tool &#8211; the <img src="http://dl.dropbox.com/u/2085924/p1/selectbehind.png" alt="Select Behind tool" /><em>Select Behind tool</em> that hides under the <img src="http://dl.dropbox.com/u/2085924/p1/pointer.png" alt="Pointer tool" /><em>Pointer tool</em>, but since there is no such thing in PS and I&#8217;ve selected it by mistake a few times&#8211;you may consider removing a hotkey from it or assign a separate one.</li>
    <li>Same goes for the <img src="http://dl.dropbox.com/u/2085924/p1/vectorpath.png" alt="Vector path tool" /><em>Vector Path tool</em> and the <img src="http://dl.dropbox.com/u/2085924/p1/redraw.png" alt="Redraw path tool" /><em>Redraw Path tool</em> &#8212; those go in pack with the <img src="http://dl.dropbox.com/u/2085924/p1/pen.png" alt="Pen tool" /><em>Pen tool</em> and we can put them aside for now. I can tell you that working with shapes is way more convenient and advanced in FW, but we will get to it later.</li>
    <li>There are a lot of cool vector shapes in FW, but we are trying to use stuff that we are already familiar with, so let&#8217;s stick with rectangle, round, polygonal and rounded rectangle.<img class="aligncenter" title="Shapes" src="http://dl.dropbox.com/u/2085924/p1/shapes.png" alt="" width="215" height="387" /></li>
    <li>If you are using &#8220;save for web&#8221; in PS &#8212; map your shortcut for it to file/image preview, it&#8217;s a close enough analogue.<img class="aligncenter" title="Save" src="http://dl.dropbox.com/u/2085924/p1/save.png" alt="" /></li>
</ul>

<h1>Panels</h1>

<p>Everybody has own panel arrangement, so pull familiar ones, add Pages, States, and both Libraries. Arrange them the way you&#8217;ve used to in PS. Notice the Properties panel on the bottom &#8212; it&#8217;s the important one, leave it there and map a hotkey to show/hide it so it won&#8217;t be in your way in some cases. Now give your layout a name and save it. Btw, if you are on Windows and know how to remove the top panel &#8212; let me know. It&#8217;s useless for me, now it&#8217;s there and I didn&#8217;t find a way to hide it properly.<img class="alignleft" title="Top panel" src="http://dl.dropbox.com/u/2085924/p1/toppanel.png" alt="" width="106" height="37"/></p>

<p>Here is my current PS and FW layout.<a href="http://dl.dropbox.com/u/2085924/p1/ps.png"><img class="alignnone" title="PS" src="http://dl.dropbox.com/u/2085924/p1/ps.png" alt="" width="1366" height="768"/></a><a href="http://dl.dropbox.com/u/2085924/p1/fw.png"><img class="alignnone" title="FW" src="http://dl.dropbox.com/u/2085924/p1/fw.png" alt="" width="1366" height="768"/></a></p>

<h1>GO!</h1>

<p>Now open a new document, turn rulers on (they are always in pixels &#8212; nice, huh?) and try to sketch something basic. I hope you&#8217;ll feel at home. Btw, here is a feature that I never used in PS, but found it in FW &#8212; by click and drag from the rulers corner you can move &#8220;zero&#8221; mark, so that it can be where your bleed ends and actual artwork begins. How cool is that?</p>

<h1>What&#8217;s next?</h1>

<p>Next time we will wireframe using libraries, pages, states and some more FW features that PS-only users can only dream about! Stay tuned!</p>
<p><a class="a2a_button_facebook_like addtoany_special_service" data-href="http://blog.railsware.com/2012/04/26/from-photoshop-to-fireworks-and-back-part-1/"></a><a class="a2a_button_twitter_tweet addtoany_special_service" data-count="horizontal" data-url="http://blog.railsware.com/2012/04/26/from-photoshop-to-fireworks-and-back-part-1/" data-text="From Photoshop to Fireworks and back. Part 1."></a><a class="a2a_button_google_plusone addtoany_special_service" data-href="http://blog.railsware.com/2012/04/26/from-photoshop-to-fireworks-and-back-part-1/"></a><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fblog.railsware.com%2F2012%2F04%2F26%2Ffrom-photoshop-to-fireworks-and-back-part-1%2F&amp;title=From%20Photoshop%20to%20Fireworks%20and%20back.%20Part%201." id="wpa2a_10"><img src="http://blog.railsware.com/wp-content/plugins/add-to-any/share_save_120_16.png" width="120" height="16" alt="Share"/></a></p><img src="http://feeds.feedburner.com/~r/railsware/~4/fBDvUlEYX9k" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.railsware.com/2012/04/26/from-photoshop-to-fireworks-and-back-part-1/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://blog.railsware.com/2012/04/26/from-photoshop-to-fireworks-and-back-part-1/</feedburner:origLink></item>
		<item>
		<title>Collaborate, learn and get things done. Our Front-End Jam Session</title>
		<link>http://feedproxy.google.com/~r/railsware/~3/6tsAjVDEdQM/</link>
		<comments>http://blog.railsware.com/2012/04/24/collaborate-learn-and-get-things-done-our-front-end-jam-session/#comments</comments>
		<pubDate>Tue, 24 Apr 2012 06:00:53 +0000</pubDate>
		<dc:creator>Pavel Pavlovsky</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Front End]]></category>
		<category><![CDATA[css]]></category>
		<category><![CDATA[front-end]]></category>
		<category><![CDATA[html]]></category>
		<category><![CDATA[oocss]]></category>

		<guid isPermaLink="false">http://blog.railsware.com/?p=418</guid>
		<description><![CDATA[Is it possible to deliver a child with 9 women in 1 month? Answer is obvious. However we&#8217;ve tried to prove an opposite during one of our last experiment. Amongst other goals of our client we got a fairly decent &#8230; <a href="http://blog.railsware.com/2012/04/24/collaborate-learn-and-get-things-done-our-front-end-jam-session/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><a href="http://blog.railsware.com/wp-content/uploads/2011/05/IMG_00081.jpg"><img class="size-full wp-image-423 alignnone" src="http://blog.railsware.com/wp-content/uploads/2011/05/IMG_00081.jpg" alt="Front-End team" width="558" height="417" /></a></p>
<p>Is it possible to deliver a child with 9 women in 1 month? Answer is obvious.<br />
However we&#8217;ve tried to prove an opposite during one of our last experiment.<br />
<span id="more-418"></span></p>
<p>Amongst other goals of our client we got a fairly decent challenge — refresh the UI and put new layout together. Funny enough all that we had was 3 days and a bunch of approved designs.</p>
<p>Initial estimation for the front-end guys was 40 hours. Taking into account <span style="color: #ff6600;"><span style="color: #000000;">limited amount of the lead time and the fact that resources</span> </span>are shared between different products we&#8217;ve found out that the only one way to hit the delivery goal is to boost front-end performance.</p>
<p>We&#8217;ve gathered 4 front-end engineers from 4 different products — our kind of 4&#215;4 in this case. Here they are — say Hi to Oksana, Alex, Sergei and Dima.</p>
<p>Upon starting this up we wanted to achieve a lot more than just plain scope execution.</p>
<p>What we&#8217;ve aimed for:</p>
<ul>
<li>Implement defined scope</li>
<li>Build up self-organized team</li>
<li>Hit the scope, present to the customer</li>
<li>Share everybody’s knowledge</li>
<li>Apply best practices in everyone’s product</li>
<li>Have ton’s of fun</li>
</ul>
<p><!--span style="color: #ff6600;"><span style="color: #000000;">Railswarians are usually using Pivotal Tracker to scope things out. If you&#8217;re curious — this is how it looked like when the we was about to begin:</span> Can we insert Pivotal screens with backlog/icebox?</span--></p>
<p>Few nights, hundreds lines of code and countless pizzas later the new born team finally got everything together. You&#8217;re welcome to compare the results yourself (great design is by Andrey Khorolets):</p>
<p><span style="color: #ff6600;"><img class="alignnone" title="Home Page" src="https://img.skitch.com/20110603-bmq3nbehjypw38pb23ia6mwd71.jpg" alt="Home Page" width="596" height="233" /></span></p>
<p>Goals completed:</p>
<ul>
<li>Scope was completed! 3 days instead of planned 4 though</li>
<li>Everyone is now willing to use learned practices in products they are doing</li>
<li>And everybody agreed that we certainly need to conductmore of those sessions. At least once a month and not only for front-end stuff</li>
<li>Yep, and it was a whole lot of fun</li>
</ul>
<p>Lessons learned:</p>
<ul>
<li>Participants has to be pro-active, self-organized, open and focused on the problem solving</li>
<li>The scope should be clearly defined and prioritized. Ask a question if there is any concern.</li>
<li>Synchronization and again synchronization. Start day at same time, periodically go through work done and recap remaining scope</li>
</ul>
<p>Hopefully you&#8217;ve enjoying reading it. Railswarians have by far more awesomeness to show so stay tuned!</p>
<p>Here some of Code examples stuff:<br />
1.<br />
<img class="alignleft size-full wp-image-502" title="1" src="http://blog.railsware.com/wp-content/uploads/2011/05/1.png" alt="" width="844" height="24" /></p>
<p>2.<br />
<img class="alignleft size-full wp-image-504" title="3" src="http://blog.railsware.com/wp-content/uploads/2011/05/3.png" alt="" width="748" height="52" /></p>
<p>3.<br />
<img class="alignleft size-full wp-image-503" title="2" src="http://blog.railsware.com/wp-content/uploads/2011/05/2.png" alt="" width="669" height="47" /></p>
<p><a class="a2a_button_facebook_like addtoany_special_service" data-href="http://blog.railsware.com/2012/04/24/collaborate-learn-and-get-things-done-our-front-end-jam-session/"></a><a class="a2a_button_twitter_tweet addtoany_special_service" data-count="horizontal" data-url="http://blog.railsware.com/2012/04/24/collaborate-learn-and-get-things-done-our-front-end-jam-session/" data-text="Collaborate, learn and get things done. Our Front-End Jam Session"></a><a class="a2a_button_google_plusone addtoany_special_service" data-href="http://blog.railsware.com/2012/04/24/collaborate-learn-and-get-things-done-our-front-end-jam-session/"></a><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fblog.railsware.com%2F2012%2F04%2F24%2Fcollaborate-learn-and-get-things-done-our-front-end-jam-session%2F&amp;title=Collaborate%2C%20learn%20and%20get%20things%20done.%20Our%20Front-End%20Jam%20Session" id="wpa2a_12"><img src="http://blog.railsware.com/wp-content/plugins/add-to-any/share_save_120_16.png" width="120" height="16" alt="Share"/></a></p><img src="http://feeds.feedburner.com/~r/railsware/~4/6tsAjVDEdQM" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.railsware.com/2012/04/24/collaborate-learn-and-get-things-done-our-front-end-jam-session/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://blog.railsware.com/2012/04/24/collaborate-learn-and-get-things-done-our-front-end-jam-session/</feedburner:origLink></item>
		<item>
		<title>PostgreSQL most useful extensions</title>
		<link>http://feedproxy.google.com/~r/railsware/~3/zkQ-4jGm-ww/</link>
		<comments>http://blog.railsware.com/2012/04/23/postgresql-most-useful-extensions/#comments</comments>
		<pubDate>Mon, 23 Apr 2012 09:31:12 +0000</pubDate>
		<dc:creator>Alexey Vasiliev</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[extension]]></category>
		<category><![CDATA[hstore]]></category>
		<category><![CDATA[postgis]]></category>
		<category><![CDATA[postgresql]]></category>
		<category><![CDATA[postpic]]></category>

		<guid isPermaLink="false">http://blog.railsware.com/?p=1823</guid>
		<description><![CDATA[Hello my dear friends. Today we will talk about PostgreSQL and most useful modules for this database. PostgreSQL is an object-relational database management system (ORDBMS). The main features of PostgreSQL are: database support of virtually unlimited size; powerful and reliable &#8230; <a href="http://blog.railsware.com/2012/04/23/postgresql-most-useful-extensions/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Hello my dear friends. Today we will talk about PostgreSQL and most useful modules for this database.</p>

<p><strong>PostgreSQL</strong> is an object-relational database management system (ORDBMS). 
<span id="more-1823"></span>
The main features of PostgreSQL are:</p>

<ul>
<li>database support of virtually unlimited size;</li>
<li>powerful and reliable mechanisms for transactional replication;</li>
<li>built-in extensible programming languages;</li>
<li>inheritance;</li>
<li>easy expandability by extensions.</li>
</ul>

<p>The last feature allows to extend the capabilities of PostgreSQL. Let&#8217;s look at some of these extensions.</p>

<h2>PostGIS</h2>

<p><a href="http://postgis.refractions.net/">http://postgis.refractions.net/</a></p>

<p>PostGIS adds support of geographic objects to the PostgreSQL object-relational database. In fact, PostGIS &#8220;spatially enables&#8221; the PostgreSQL server, allowing it to be used as a backend spatial database for geographic information systems (GIS), much like ESRI&#8217;s SDE or Oracle&#8217;s Spatial extension. PostGIS follows the OpenGIS &#8220;Simple Features Specification for SQL&#8221; and has been certified as compliant with the &#8220;Types and Functions&#8221; profile.</p>

<p>This extension is very useful if you want do location-based queries in database, such as &#8220;find the closest N items to this location.&#8221;.</p>

<h2>PostPic</h2>

<p><a href="http://github.com/drotiro/postpic">http://github.com/drotiro/postpic</a></p>

<p>PostPic is an extension that enables image processing inside the database, like PostGIS does for spatial data. It adds the new &#8216;image&#8217; type to the SQL, and several functions to process images (crop, resize, rotate, etc) and to extract their attributes (width, height, date, etc.).</p>

<h2>PL/Proxy</h2>

<p><a href="http://pgfoundry.org/projects/plproxy/">http://pgfoundry.org/projects/plproxy/</a></p>

<p>PL/Proxy is database partitioning system implemented as PL language. Main idea is that proxy function will be created with same signature as remote function to be called, so only destination info needs to be specified inside proxy function body.</p>

<h2>Texcaller</h2>

<p><a href="http://www.profv.de/texcaller/">http://www.profv.de/texcaller/</a></p>

<p>Texcaller is a convenient interface to the <a href="http://en.wikipedia.org/wiki/TeX">TeX</a> command line tools that handles all kinds of errors without much fuzz. It is written in plain C, is fairly portable, and has no external dependencies besides TeX.</p>

<h2>PgMemcache</h2>

<p><a href="http://pgfoundry.org/projects/pgmemcache/">http://pgfoundry.org/projects/pgmemcache/</a></p>

<p>PgMemcache is a set of PostgreSQL user-defined functions that provide an interface to memcached. Installing pgmemcache is easy, but does have a few trivial requirements &#8211; libmemcached 0.38 or newer and PostgreSQL 8.4 or newer. With this extension the PostgreSQL can write, read, search, and delete data from memcached.</p>

<h2>Prefix</h2>

<p><a href="http://pgfoundry.org/projects/prefix">http://pgfoundry.org/projects/prefix</a></p>

<p>The prefix project implements text prefix matches operator (prefix @> text) and provide a GiST opclass for indexing support of prefix searches.
Typical query like the following is now able to benefit from index lookups, as soon as the prefix column is of type prefix_range: 
SELECT * FROM prefixes WHERE prefix @> &#8217;0123456789&#8242; ORDER BY length(prefix::text) LIMIT 1</p>

<h2>pgSphere</h2>

<p><a href="http://pgsphere.projects.postgresql.org/">http://pgsphere.projects.postgresql.org/</a></p>

<p>pgSphere contains methods for working with spherical coordinates and objects. It also supports indexing of spherical objects. Used to work with geographic (can be used instead of the PostGIS) or astronomical data types.</p>

<h2>Multicorn</h2>

<p><a href="http://multicorn.org/">http://multicorn.org/</a></p>

<p>As of version 9.1, PostgreSQL can link to other systems to retrieve data via Foreign Data Wrappers (FDWs). These can take the form of any data source, such as a file system, another RDBMS, or a web service. That means that the regular database queries can use these data sources like regular tables, and even join multiple data sources together. Many extensions for FDW is available:</p>

<ul>
<li><a href="http://pgfoundry.org/projects/oracle-fdw/">oracle_fdw</a> &#8211; connects to Oracle databases.</li>
<li><a href="https://github.com/dpage/mysql_fdw">mysql_fdw</a> &#8211; connects to MySQL databases.</li>
<li><a href="https://github.com/tureba/tds_fdw">tds_fdw</a> &#8211; connects to Sybase and Microsoft SQL Server databases.</li>
<li><a href="https://github.com/ZhengYang/odbc_fdw">odbc_fdw</a> &#8211; connects to any ODBC source.</li>
<li><a href="https://github.com/ZhengYang/couchdb_fdw">couchdb_fdw</a> &#8211; connects to CouchDB databases.</li>
<li><a href="https://github.com/dpage/redis_fdw">redis_fdw</a> &#8211; connects to Redis databases.</li>
<li><a href="https://github.com/umitanuki/twitter_fdw">twitter_fdw</a> &#8211; fetches messages from Twitter.</li>
<li><a href="https://github.com/guedes/ldap_fdw">ldap_fdw</a> &#8211; queries LDAP servers.</li>
<li><a href="http://www.postgresql.org/docs/9.1/static/file-fdw.html">file_fdw</a> &#8211; access data files in the server&#8217;s file system and query them as tables.</li>
<li><a href="https://github.com/adunstan/file_fixed_length_record_fdw">file_fixed_length_record_fdw</a> &#8211; reads flat files with columns of fixed width.</li>
<li><a href="http://wiki.postgresql.org/wiki/PGStrom">PGStrom</a> &#8211; uses GPU devices to accelerate sequential scan on massive amount of records with complex qualifiers.</li>
<li><a href="https://github.com/umitanuki/s3_fdw">s3_fdw</a> &#8211; reads files located in Amazon S3.</li>
<li><a href="https://github.com/cyga/www_fdw">www_fdw</a> &#8211; accesses web services as a data source.</li>
</ul>

<p><strong>Multicorn</strong> is an extension that enables Foreign Data Wrappers to be written in Python. There are a number of foreign data wrappers it provides as standard:</p>

<ul>
<li><a href="http://multicorn.org/foreign-data-wrappers/#sqlalchemy-foreign-data-wrapper">multicorn.sqlalchemyfdw</a> &#8211; used to access data stored in any database supported by the sqlalchemy python toolkit, such as MySQL, SQLite, Oracle, Microsoft SQL Server and many others.</li>
<li><a href="http://multicorn.org/foreign-data-wrappers/#filesystem-foreign-data-wrapper">multicorn.fsfdw</a> &#8211; used to access data stored in various files, in a filesystem.</li>
<li><a href="http://multicorn.org/foreign-data-wrappers/#csv-foreign-data-wrapper">multicorn.csvfdw</a> &#8211; used to access data stored in CSV files.</li>
<li><a href="http://multicorn.org/foreign-data-wrappers/#rss-foreign-data-wrapper">multicorn.rssfdw</a> &#8211; used to access items from an RSS feed.</li>
</ul>

<h2>Hstore</h2>

<p><a href="http://www.postgresql.org/docs/9.1/static/hstore.html">http://www.postgresql.org/docs/9.1/static/hstore.html</a></p>

<p>This module implements a data type hstore for storing sets of (key,value) pairs within a single PostgreSQL data field. This can be useful in various scenarios, such as rows with many attributes that are rarely examined, or semi-structured data. hstore has GiST and GIN index support for the @>, ?, ?&amp; and ?| operators. hstore also supports btree or hash indexes for the = operator. This allows hstore columns to be declared UNIQUE, or to be used in GROUP BY, ORDER BY or DISTINCT expressions. The sort ordering for hstore values is not particularly useful, but these indexes may be useful for equivalence lookups.</p>

<h2>Intarray</h2>

<p><a href="http://www.postgresql.org/docs/9.1/static/intarray.html">http://www.postgresql.org/docs/9.1/static/intarray.html</a></p>

<p>The intarray module provides a number of useful functions and operators for manipulating null-free arrays of integers. There is also support for indexed searches using some of the operators.</p>

<p>All of these operations will throw an error if a supplied array contains any NULL elements. I used this extension when developed simple method for comparison of images by PostgreSQL (<a href="http://leopard.in.ua/2010/12/09/bystroe-sravnenie-izobrazhenij-s-pomoshhyu-rubyphp-i-postgresql/">http://leopard.in.ua/2010/12/09/bystroe-sravnenie-izobrazhenij-s-pomoshhyu-rubyphp-i-postgresql/</a>, russian article).</p>

<h2>Dblink</h2>

<p><a href="http://www.postgresql.org/docs/9.1/static/dblink.html">http://www.postgresql.org/docs/9.1/static/dblink.html</a></p>

<p>Adds support for connections to other PostgreSQL databases from within a database session. Also dblink allows to do <a href="http://www.orafaq.com/wiki/Atonomous_transaction">autonomous transactions (like in Oracle)</a>.</p>

<p><em>That&#8217;s all folks!</em></p>
<p><a class="a2a_button_facebook_like addtoany_special_service" data-href="http://blog.railsware.com/2012/04/23/postgresql-most-useful-extensions/"></a><a class="a2a_button_twitter_tweet addtoany_special_service" data-count="horizontal" data-url="http://blog.railsware.com/2012/04/23/postgresql-most-useful-extensions/" data-text="PostgreSQL most useful extensions"></a><a class="a2a_button_google_plusone addtoany_special_service" data-href="http://blog.railsware.com/2012/04/23/postgresql-most-useful-extensions/"></a><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fblog.railsware.com%2F2012%2F04%2F23%2Fpostgresql-most-useful-extensions%2F&amp;title=PostgreSQL%20most%20useful%20extensions" id="wpa2a_14"><img src="http://blog.railsware.com/wp-content/plugins/add-to-any/share_save_120_16.png" width="120" height="16" alt="Share"/></a></p><img src="http://feeds.feedburner.com/~r/railsware/~4/zkQ-4jGm-ww" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.railsware.com/2012/04/23/postgresql-most-useful-extensions/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		<feedburner:origLink>http://blog.railsware.com/2012/04/23/postgresql-most-useful-extensions/</feedburner:origLink></item>
		<item>
		<title>Send stories from Pivotal Tracker to OmniFocus easily</title>
		<link>http://feedproxy.google.com/~r/railsware/~3/r7RvsSUVIpM/</link>
		<comments>http://blog.railsware.com/2012/04/19/send-stories-from-pivotal-tracker-to-omnifocus/#comments</comments>
		<pubDate>Thu, 19 Apr 2012 14:11:00 +0000</pubDate>
		<dc:creator>Leonid Shevtsov</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[extension]]></category>
		<category><![CDATA[OmniFocus]]></category>
		<category><![CDATA[Pivotal Tracker]]></category>
		<category><![CDATA[productivity]]></category>

		<guid isPermaLink="false">http://blog.railsware.com/?p=1810</guid>
		<description><![CDATA[Get the extension on the Chrome WebStore: Send to OmniFocus from Pivotal Tracker Pivotal Tracker is a great project management tool for teams, which we at RailsWare use extensively for all our projects. However, for a GTD practitioner such as &#8230; <a href="http://blog.railsware.com/2012/04/19/send-stories-from-pivotal-tracker-to-omnifocus/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><em>Get the extension on the Chrome WebStore: <a href="https://chrome.google.com/webstore/detail/hmcfpopmnaoakmhljnebeoihhclgnkdf">Send to OmniFocus from Pivotal Tracker</a></em>
<span id="more-1810"></span></p>

<p><a href="https://www.pivotaltracker.com">Pivotal Tracker</a> is a great project management tool for teams, which we at <a href="http://railsware.com">RailsWare</a> use extensively for all our projects.</p>

<p>However, for a GTD practitioner such as myself, the Tracker violates the virtue of having all your tasks in one place. And, even if you think you can split your work and your personal life and use the Tracker only for the former, it&#8217;s still not well suited for GTD.</p>

<p>Thus, I consider Pivotal Tracker an Inbox and copy all my stories into my <a href="http://www.omnigroup.com/products/omnifocus/">OmniFocus</a>. Doing boring stuff manually is not the RailsWare way, so I wrote an extension for Google Chrome, that sends stories to OmniFocus with one click of a button.</p>

<p><a href="http://blog.railsware.com/wp-content/uploads/2012/04/send_to_omnifocus_screenshot.png"><img src="http://blog.railsware.com/wp-content/uploads/2012/04/send_to_omnifocus_screenshot.png" alt="" title="send_to_omnifocus_screenshot" width="640" height="400" class="alignnone size-full wp-image-1811" /></a></p>

<p>Get the extension on the Chrome WebStore: <a href="https://chrome.google.com/webstore/detail/hmcfpopmnaoakmhljnebeoihhclgnkdf">Send to OmniFocus from Pivotal Tracker</a></p>
<p><a class="a2a_button_facebook_like addtoany_special_service" data-href="http://blog.railsware.com/2012/04/19/send-stories-from-pivotal-tracker-to-omnifocus/"></a><a class="a2a_button_twitter_tweet addtoany_special_service" data-count="horizontal" data-url="http://blog.railsware.com/2012/04/19/send-stories-from-pivotal-tracker-to-omnifocus/" data-text="Send stories from Pivotal Tracker to OmniFocus easily"></a><a class="a2a_button_google_plusone addtoany_special_service" data-href="http://blog.railsware.com/2012/04/19/send-stories-from-pivotal-tracker-to-omnifocus/"></a><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fblog.railsware.com%2F2012%2F04%2F19%2Fsend-stories-from-pivotal-tracker-to-omnifocus%2F&amp;title=Send%20stories%20from%20Pivotal%20Tracker%20to%20OmniFocus%20easily" id="wpa2a_16"><img src="http://blog.railsware.com/wp-content/plugins/add-to-any/share_save_120_16.png" width="120" height="16" alt="Share"/></a></p><img src="http://feeds.feedburner.com/~r/railsware/~4/r7RvsSUVIpM" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.railsware.com/2012/04/19/send-stories-from-pivotal-tracker-to-omnifocus/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://blog.railsware.com/2012/04/19/send-stories-from-pivotal-tracker-to-omnifocus/</feedburner:origLink></item>
		<item>
		<title>Shared Mustache Templates for Rails 3</title>
		<link>http://feedproxy.google.com/~r/railsware/~3/3aiM3AeliR8/</link>
		<comments>http://blog.railsware.com/2012/04/12/shared-mustache-templates-for-rails-3/#comments</comments>
		<pubDate>Thu, 12 Apr 2012 13:16:04 +0000</pubDate>
		<dc:creator>Alexey Vasiliev</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[mustache]]></category>
		<category><![CDATA[rails 3]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[templates]]></category>

		<guid isPermaLink="false">http://blog.railsware.com/?p=1764</guid>
		<description><![CDATA[Hello my dear friends. Today we will talk about how we share mustache templates in Rails 3. Let&#8217;s imagine that we have a task, where on first load of the page we show only 10 products. But when user scroll, &#8230; <a href="http://blog.railsware.com/2012/04/12/shared-mustache-templates-for-rails-3/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Hello my dear friends. Today we will talk about how we share mustache templates in Rails 3.</p>

<p>Let&#8217;s imagine that we have a task, where on first load of the page we show only 10 products. But when user scroll, we should automatically load more products on page (aka continuous pagination).
Of course, this task can be solved in several ways, but I want solve this task by sharing one template between Rails and JavaScript.</p>

<span id="more-1764"></span>

<p>There are many JavaScripts templates exists today &#8211; <a href="http://twitter.github.com/hogan.js/">Hogan.js</a>, <a href="http://handlebarsjs.com/">Handlebars</a>, <a href="http://mustache.github.com/">Mustache</a> etc. I choose Mustache, because it&#8217;s simple and has template engine implemented on many languages (we need JavaScript and Ruby). We created a gem for such type of tasks &#8211; <a href="https://github.com/railsware/smt_rails">smt_rails</a>. 
How it works?</p>

<p>First of all you have to add this gem to your Gemfile and start &#8216;bundle install&#8217;:</p>

<pre><code>gem 'smt_rails', git: 'git://github.com/railsware/smt_rails.git'
</code></pre>

<p>Next launch generator:</p>

<pre><code>rails g smt_rails:install
</code></pre>

<p>That&#8217;s all.</p>

<p>Now you can create a directory in &#8216;app/templates&#8217; mustache templates (these templates ends with &#8216;.mustache&#8217; by default). Let&#8217;s create partial for the product:</p>

<p>File: &#8216;app/templates/products/_product.mustache</p>

<p>Content:</p>

<pre><code>&lt;a href="{{url}}"&gt;{{title}}&lt;/a&gt;
&lt;p&gt;{{description}}&lt;/p&gt;
</code></pre>

<p>You can render this partial in ActiveView:</p>

<pre><code>&lt;%= render "products/product", :mustache =&gt; product.as_json %&gt; 
</code></pre>

<p>And in JavaScript:</p>

<pre><code>var product = … ; come from ajax call as json
var content = SMT['products/product'](product);
</code></pre>

<p>So in the end you&#8217;ll have only one template, which is shared between Rails and JavaScript.</p>

<p>Demo application with scroll pagination you can find <a href="http://smt-rails-example.herokuapp.com/">here</a></p>

<p>Source code: <a href="https://github.com/le0pard/smt_rails_example">https://github.com/le0pard/smt_rails_example</a></p>

<p>That&#8217;s all folks!</p>

<p>SMT_rails (Shared Mustache Templates for Rails)</p>

<p>Rubygems: <a href="https://rubygems.org/gems/smt_rails">https://rubygems.org/gems/smt_rails</a></p>

<p>Source code: <a href="https://github.com/railsware/smt_rails">https://github.com/railsware/smt_rails</a></p>
<p><a class="a2a_button_facebook_like addtoany_special_service" data-href="http://blog.railsware.com/2012/04/12/shared-mustache-templates-for-rails-3/"></a><a class="a2a_button_twitter_tweet addtoany_special_service" data-count="horizontal" data-url="http://blog.railsware.com/2012/04/12/shared-mustache-templates-for-rails-3/" data-text="Shared Mustache Templates for Rails 3"></a><a class="a2a_button_google_plusone addtoany_special_service" data-href="http://blog.railsware.com/2012/04/12/shared-mustache-templates-for-rails-3/"></a><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fblog.railsware.com%2F2012%2F04%2F12%2Fshared-mustache-templates-for-rails-3%2F&amp;title=Shared%20Mustache%20Templates%20for%20Rails%203" id="wpa2a_18"><img src="http://blog.railsware.com/wp-content/plugins/add-to-any/share_save_120_16.png" width="120" height="16" alt="Share"/></a></p><img src="http://feeds.feedburner.com/~r/railsware/~4/3aiM3AeliR8" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.railsware.com/2012/04/12/shared-mustache-templates-for-rails-3/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		<feedburner:origLink>http://blog.railsware.com/2012/04/12/shared-mustache-templates-for-rails-3/</feedburner:origLink></item>
		<item>
		<title>4 Steps To Scope Your Product Right</title>
		<link>http://feedproxy.google.com/~r/railsware/~3/BAR5lMsp1cg/</link>
		<comments>http://blog.railsware.com/2012/04/10/4-steps-to-scope-your-product-right/#comments</comments>
		<pubDate>Tue, 10 Apr 2012 11:33:42 +0000</pubDate>
		<dc:creator>Tanya Lyashenko</dc:creator>
				<category><![CDATA[Design]]></category>
		<category><![CDATA[Products]]></category>
		<category><![CDATA[approach]]></category>
		<category><![CDATA[client]]></category>
		<category><![CDATA[colorscope]]></category>
		<category><![CDATA[flowdoc]]></category>
		<category><![CDATA[Railsware]]></category>
		<category><![CDATA[scoping]]></category>

		<guid isPermaLink="false">http://blog.railsware.com/?p=1683</guid>
		<description><![CDATA[Usually, the business owner starts working with designers and engineers with only 20% of his product scope understanding. Our overall goal is to build product vision together at the very beginning of a development cycle and not at the end &#8230; <a href="http://blog.railsware.com/2012/04/10/4-steps-to-scope-your-product-right/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Usually, the business owner starts working with designers and engineers with only 20% of his product scope understanding.</p>

<p>Our overall goal is to build product vision together at the very beginning of a development cycle and not at the end of developing a product-he-doesn&#8217;t-need and which doesn’t solve consumers problems. Here are few general words about how <a href="http://www.railsware.com">Railsware</a> does that approach.</p>

<span id="more-1683"></span>

<h2>Step 1. Interview, definition of benefits</h2>

<p>First and foremost, we particularize what product should be created during the interview with business owner. The very most important part is a deep understanding of what benefits the business should deliver to its consumers.</p>

<h2>Step 2. ColorScope &ndash; a way for critical (close to 100%) data acquisition and prioritization</h2>

<p>All the data collected during interviews is being divided into descriptive parts, then being coded by color according to its magnitude and priority.<br /></p>

<p><img height="380px;" src="https://lh5.googleusercontent.com/4Z0k4epwq2Z4gli_3XEjU27nBCLIXVIsZORd6TUyDE6wfj9zcXHIetAhiY_n0PJAt60nh9DGOFRo3Yzo3vAM65N11WO-6Qgm6zyBldWrY2SFHETEcDU" width="680px;" /></p>

<p><em>Steps 1 and 2 can be repeated as many times as needed.</em></p>

<h2>Step 3. User Stories</h2>

<p>Product functionality consists of logical parts. Within every single part, user can make only one action (e.g., to sign in). All possible behaviors of a functional part (e.g., entering wrong data, output of errors) are described in user stories. Every user story is finished by its benefit description. So you can see all the components and screens needed to be created, including the smallest ones.</p>

<h2>Step 4. Flow Document</h2>

<p>When product vision is finally created, it is time to step forward and visualize product by screens based on user stories. Instead of sending tons of emails, we decided to organize space for all screens and comments grouped into iterations. This documentation method we call FlowDoc.</p>

<p>FlowDoc &ndash; is a <a href="http://sites.google.com/">Google Sites</a> document comprising product description divided into iterations (flows), with mockups and final designs. FlowDoc makes it easy to synchronize team members, to share updates, to edit and comment.<br /><br />
 <img height="535px;" src="https://lh6.googleusercontent.com/iMyWjbMmT5BwF35OCRMWbhMhndTbQEk6InCDnlDot4jbeKQZhFVNB_zy9gjbio8QxCLQw70bqbdRW7s1dLgTp1wdJO4wfrvoH0GVy428WcqO7xkpv5I" width="651px;" /></p>

<p>We use <a href="http://www.dropbox.com/">DropBox</a> as a screen storage space. Screens are to be placed in Public folder. For screen sharing, you need to copy Public Link of a file and put it into Google Sites document. All folders with screens are named according to documentation parts (e.g., Register on Site). A screen filename is the name of a certain user story.<br /><br />
<img height="208px;" src="https://lh4.googleusercontent.com/HlnV88s2jYFq87ozAH-9HDsNjdzIfEu8cb-SYLOMgYqALnwCPNuzqp6GGHihXBJBE4LBi_Esr1Q1MkI5MWwKR7nxpT8ofw56SxQb1oFXK-AtRHvqj7Y" width="498px;" /><br /></p>

<p>Designer needs to put pictures into the document just once. To provide full-automatic screen updating he or she just need to renew files in DropBox. This update action can be implemented by one click. Below are some tips for popular graphics editors.</p>

<p><strong>Exporting screens from Adobe Fireworks</strong><br />
This program natively supports multi-page mode. It means you can hold all product screens in one file. So, page-by-page export can be provided into any graphic format by Export Pages to Files.<br /><br />
<img height="363px;" src="https://lh5.googleusercontent.com/nBLFEEXu8No4wC4FTV_SdAAP74B0wY8h8f0HEAs7anKrRQpp7jzCME-4MdeMfLWdLi9RSXIeCtNccm9QeFI4rV6ek7OMy9KoNZvLiIdwSzt-n3uEyWc" width="424px;" /><br /></p>

<h3>Exporting screens from Adobe Photoshop</h3>

<p>There is no multi-page support in Photoshop. In this case, we need to use one trick – Layer Comps. Layer Comp is a special layer with information about object placement, visibility and style. Comps can be accessed through the Layer Comps Panel.<br /><br />
<img height="242px;" src="https://lh6.googleusercontent.com/CuH7OFFQn6Cf8QLadXlMcg6Tue87W987nmDLeseOXt3zjEm5MCeEL7-o0h-AJ2DRncTOj9J4A_55KBURWQtbMZvp8humVZf9C-pbmeVErhYh9rSBebw" width="378px;" /><br /></p>

<p>We can imitate multiple pages by saving layers’ and folders’ visibility in Layer Comps being named as the respective application pages. In this case, switching between Layer Comps looks like switching between application screens. Every Comp can be exported as a separate JPEG or PNG file. Thus, exporting all pages from one file takes less time than exporting pages from separate files – only few seconds. You just need to run a script from the menu <el>File > Scripts > Layer Comps to Files</el>.<br /><br />
<img height="383px;" src="https://lh3.googleusercontent.com/hnOksdjVVXbEJy-6VDBjEJoZ528ybOm4EbOjHDJrjX0RKR85pJ7DlRbvdSe0NN0DKBPuUhltJJVEDxg-zaNZOifSLdnv5Noyxq3qx8KXdbt-5lyaKv4" width="407px;" /><br /></p>

<p>That’s how easy and vivid product design method looks like. It is ours and it works! <img src='http://blog.railsware.com/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </p>
<p><a class="a2a_button_facebook_like addtoany_special_service" data-href="http://blog.railsware.com/2012/04/10/4-steps-to-scope-your-product-right/"></a><a class="a2a_button_twitter_tweet addtoany_special_service" data-count="horizontal" data-url="http://blog.railsware.com/2012/04/10/4-steps-to-scope-your-product-right/" data-text="4 Steps To Scope Your Product Right"></a><a class="a2a_button_google_plusone addtoany_special_service" data-href="http://blog.railsware.com/2012/04/10/4-steps-to-scope-your-product-right/"></a><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fblog.railsware.com%2F2012%2F04%2F10%2F4-steps-to-scope-your-product-right%2F&amp;title=4%20Steps%20To%20Scope%20Your%20Product%20Right" id="wpa2a_20"><img src="http://blog.railsware.com/wp-content/plugins/add-to-any/share_save_120_16.png" width="120" height="16" alt="Share"/></a></p><img src="http://feeds.feedburner.com/~r/railsware/~4/BAR5lMsp1cg" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.railsware.com/2012/04/10/4-steps-to-scope-your-product-right/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://blog.railsware.com/2012/04/10/4-steps-to-scope-your-product-right/</feedburner:origLink></item>
	</channel>
</rss><!-- Performance optimized by W3 Total Cache. Learn more: http://www.w3-edge.com/wordpress-plugins/

Database Caching 32/38 queries in 0.009 seconds using disk: basic

Served from: blog.railsware.com @ 2012-05-17 14:27:14 -->

