<?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>Progress Please!</title>
	<atom:link href="http://stefanwille.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://stefanwille.com</link>
	<description>Stefan Wille</description>
	<lastBuildDate>Thu, 05 Jan 2012 18:02:14 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Creating smaller images in Rmagick</title>
		<link>http://stefanwille.com/2011/11/creating-smaller-images-in-rmagick/</link>
		<comments>http://stefanwille.com/2011/11/creating-smaller-images-in-rmagick/#comments</comments>
		<pubDate>Tue, 15 Nov 2011 15:36:04 +0000</pubDate>
		<dc:creator>Stefan</dc:creator>
				<category><![CDATA[Ruby on Rails]]></category>

		<guid isPermaLink="false">http://stefanwille.com/?p=450</guid>
		<description><![CDATA[When you create an image in Rmagick and save it, chances are high that your image will be way too big. The reason is that, by default, Rmagick creates uncompressed images. Try to run &#8216;optipng &#8216; for PNG or &#8216;jpegoptim &#8211;strip-all &#8216; for JPG on your file, and you will probably see a file size [...]]]></description>
			<content:encoded><![CDATA[<p>When you create an image in Rmagick and save it, chances are high that your image will be way too big. The reason is that, by default, Rmagick creates uncompressed images. Try to run &#8216;optipng <filename>&#8216; for PNG or &#8216;jpegoptim &#8211;strip-all <filename>&#8216; for JPG on your file, and you will probably see a file size reduction of 20% &#8211; 90%. That is without loosing image quality! </p>
<p>One way to improve on this is to set the compression level in Rmagick&#8217;s write method. Here is some clunky code to do this:</p>
<p><span id="more-450"></span></p>
<blockquote>
<pre>
compression =
        case image_file_name
          when /(jpg)|(jpeg)$/i
            Magick::LosslessJPEGCompression
          else
          when /png$/i
            Magick::ZipCompression
          else
            nil
        end
image.write(output_file_name) do
  self.compression = compression if compression
end
</pre>
</blockquote>
<p>The results are not as good as with the command line tools, but definitely better than uncompressed images.</p>
<p>If your images are part of a web page, then you can reduce your page load time by reducing image size. To me this was a big deal on my current project.</p>
]]></content:encoded>
			<wfw:commentRss>http://stefanwille.com/2011/11/creating-smaller-images-in-rmagick/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Printing the page content in Capybara</title>
		<link>http://stefanwille.com/2010/12/printing-the-page-content-in-capybara/</link>
		<comments>http://stefanwille.com/2010/12/printing-the-page-content-in-capybara/#comments</comments>
		<pubDate>Thu, 02 Dec 2010 17:08:37 +0000</pubDate>
		<dc:creator>Stefan</dc:creator>
				<category><![CDATA[Ruby on Rails]]></category>

		<guid isPermaLink="false">http://stefanwille.com/?p=422</guid>
		<description><![CDATA[Capybara is a great integration testing framework that easily replaces Webrat. Plus, it works with Rails 3, which Webrat seems not to do. If you need to print the current page&#8217;s content, for example to debug your test, you can do so with: puts page.body This trick is a bit hard to find in the [...]]]></description>
			<content:encoded><![CDATA[<p><a href="https://github.com/jnicklas/capybara" onclick="pageTracker._trackPageview('/outgoing/github.com/jnicklas/capybara?referer=');">Capybara</a> is a great integration testing framework that easily replaces Webrat. Plus, it works with Rails 3, which Webrat seems not to do.</p>
<p>If you need to print the current page&#8217;s content, for example to debug your test, you can do so with:</p>
<p><span id="more-422"></span></p>
<pre>    puts page.body
</pre>
<p>This trick is a bit hard to find in the documentation.</p>
<p><strong>Update</strong>: There is also </p>
<pre>    save_and_open_page
</pre>
<p>which opens the page content in a browser.</p>
]]></content:encoded>
			<wfw:commentRss>http://stefanwille.com/2010/12/printing-the-page-content-in-capybara/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Ruby on Rails: Fix for &#8216;invalid multibyte char (US-ASCII)&#8217;</title>
		<link>http://stefanwille.com/2010/08/ruby-on-rails-fix-for-invalid-multibyte-char-us-ascii/</link>
		<comments>http://stefanwille.com/2010/08/ruby-on-rails-fix-for-invalid-multibyte-char-us-ascii/#comments</comments>
		<pubDate>Tue, 31 Aug 2010 19:34:55 +0000</pubDate>
		<dc:creator>Stefan</dc:creator>
				<category><![CDATA[Ruby on Rails]]></category>

		<guid isPermaLink="false">http://stefanwille.com/?p=402</guid>
		<description><![CDATA[A fix for this error in Ruby on Rails:

/Users/stefan/.../controllers/categories_controller.rb:37: invalid multibyte char (US-ASCII)]]></description>
			<content:encoded><![CDATA[<p>You probably got this error message in Ruby on Rails:</p>
<p><code>/Users/stefan/.../controllers/categories_controller.rb:37: invalid multibyte char (US-ASCII)</code></p>
<p>The problem is that Ruby 1.9 expects you to use ASCII characters in your source code, and you have used a non ASCII character.</p>
<p>The solution is to tell Ruby that your source file is UTF-8 by including this directive as the first line of your file:</p>
<p><span id="more-402"></span><br />
<code># encoding: utf-8</code></p>
<p>You probably use UTF-8 for all your files. Once you include a non-ASCII character, the difference between ASCII and UTF-8 becomes relevant for Ruby. That&#8217;s when you need this directive.</p>
]]></content:encoded>
			<wfw:commentRss>http://stefanwille.com/2010/08/ruby-on-rails-fix-for-invalid-multibyte-char-us-ascii/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Rails Plugin for Single Sign On with Atlassian Crowd</title>
		<link>http://stefanwille.com/2010/07/rails-plugin-for-single-sign-on-with-atlassian-crowd/</link>
		<comments>http://stefanwille.com/2010/07/rails-plugin-for-single-sign-on-with-atlassian-crowd/#comments</comments>
		<pubDate>Tue, 27 Jul 2010 14:15:29 +0000</pubDate>
		<dc:creator>Stefan</dc:creator>
				<category><![CDATA[Ruby on Rails]]></category>

		<guid isPermaLink="false">http://stefanwille.com/?p=363</guid>
		<description><![CDATA[Implement single sign on with Ruby on Rails and Atlassian Crowd 2.0 using the Rails plugin crowd_rails.]]></description>
			<content:encoded><![CDATA[<p>Atlassian Crowd (<a title="Atlassian Crowd" href="http://www.atlassian.com/software/crowd/" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.atlassian.com/software/crowd/?referer=');">http://www.atlassian.com/software/crowd/</a>) offers a simple solution for single sign on. It comes with an authentication server, a web based administration console and Java client libraries. Other Atlassian products such as Jira, Confluence and Bamboo  integrate with Crowd.</p>
<p>With the crowd_rails plugin, Ruby on Rails can also benefit from single sign on with Atlassian Crowd 2.0.</p>
<p><span id="more-363"></span></p>
<h2>Installing the Plugin</h2>
<p>The plugin is available at</p>
<blockquote><p>http://github.com/stefanwille/crowd_rails</p></blockquote>
<p>To install the crowd_rails plugin, run</p>
<blockquote><p>gem install crowd_rails<br />
gem crowd-stefanwille</p></blockquote>
<p><em>crowd-stefanwille</em> is a Ruby client library for Crowd, and <em>crowd_rails</em> is the Rails plugin.</p>
<h2>Installing a Crowd Server</h2>
<p>Beyond these gems, you will also need a Crowd server with version 2.0 or greater.<br />
The easiest way to get started is to install an evaluation copy of Crowd on your local machine.</p>
<p>After you have installed your local Crowd server, test it using its demo application. Go to</p>
<blockquote><p>http://localhost:8095/demo</p></blockquote>
<p>Make sure that you can log in.</p>
<h2>Running the Demo Application</h2>
<p>On Github you can clone a simple demo application that uses <em>crowd_rails</em> for authentication. The URL is:</p>
<blockquote><p>http://github.com/stefanwille/crowd_rails_test</p></blockquote>
<p>To run it, you will need</p>
<ul>
<li>a Crowd server on localhost, port 8095</li>
<li>an application configured in Crowd with app name and password ‘soaptest’</li>
<li>the application ‘soaptest’ set &#8216;directory&#8217; set to ‘True’</li>
</ul>
<p>Type</p>
<blockquote><p>git clone git&#64;github.com:stefanwille/crowd_rails_test.git<br />
cd crowd_rails_test<br />
bundle install<br />
ruby script/server</p></blockquote>
<p>And then point your browser to</p>
<blockquote><p>http://localhost:3000/demo</p></blockquote>
<p>You will get the browser&#8217;s log in dialog. When you enter correct credentials, you will see a success page. Next, you can try if you are also logged in for Crowd&#8217;s demo application, which should run at</p>
<blockquote><p>http://localhost:8095/demo</p></blockquote>
<p>on your local Crowd server.</p>
<h2>Using the Plugin</h2>
<p>To use the plugin in your own application, you need to configure the Crowd client library and then mix the module <em>Crowd::SingleSignOn</em> into your <em>ApplicationController</em>.</p>
<p>Add a file</p>
<blockquote><p>config/initializers/crowd_setup.rb</p></blockquote>
<p>and this content:</p>
<blockquote><p>require &#8216;crowd&#8217;</p>
<p>Crowd.crowd_url = &#8216;http://127.0.0.1:8095/crowd/services/SecurityServer&#8217;<br />
Crowd.crowd_app_name = &#8216;soaptest&#8217;<br />
Crowd.crowd_app_pword = &#8216;soaptest&#8217;<br />
Crowd.crowd_validation_factors_need_user_agent = false  # false for Crowd 2.0.5, true for Crowd 2.0.2<br />
Crowd.crowd_session_validationinterval = 0  # Set &gt; 0 for authentication caching.</p></blockquote>
<p>This file contains the Crowd configuration for your application. Change the configuration according to your needs.</p>
<p>Then add this to your <em>ApplicationController</em> class:</p>
<blockquote><p>class ApplicationController &lt; ActionController::Base<br />
include Crowd::SingleSignOn</p>
<p>&#8230;<br />
before_filter :authenticate</p>
<p>private<br />
def authenticate<br />
return if RAILS_ENV == &#8220;test&#8221;</p>
<p>return if crowd_authenticated?</p>
<p>authenticate_or_request_with_http_basic(&#8216;My Application&#8217;) do |user_name, password|<br />
crowd_authenticate(user_name, password)<br />
end<br />
end<br />
end</p></blockquote>
<p>This will give you the browser&#8217;s grey password dialog (aka &#8216;basic auth&#8217;). Replace the call to Rails&#8217; <em>authenticate_or_request_with_http_basic()</em> that asks the user for username and password if you want something fancier.</p>
<p>The demo app uses the same basic auth approach.</p>
<h2>Log Out</h2>
<p>There is little gotcha with respect to log out. The plugin offers the method crowd_log_out, which is also used in the demo application. The problem is that basic authentication makes it more or less impossible to log a user out, because the browser keeps sending the user&#8217;s crendentials with every request. So if you want a log out feature, you need to replace basic authentication with a login form.</p>
<h2>Interoperability</h2>
<p>I haved tested <em>crowd_rails</em> plugin with Crowd 2.0.2 and 2.0.5. Also, I tested single sign on interoperability with Jira, Confluence and Bamboo.</p>
]]></content:encoded>
			<wfw:commentRss>http://stefanwille.com/2010/07/rails-plugin-for-single-sign-on-with-atlassian-crowd/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>Version 0.5.10 of Crowd Gem Released</title>
		<link>http://stefanwille.com/2010/07/version-0-5-10-of-crowd-gem-released/</link>
		<comments>http://stefanwille.com/2010/07/version-0-5-10-of-crowd-gem-released/#comments</comments>
		<pubDate>Mon, 26 Jul 2010 08:50:12 +0000</pubDate>
		<dc:creator>Stefan</dc:creator>
				<category><![CDATA[Other]]></category>

		<guid isPermaLink="false">http://stefanwille.com/?p=361</guid>
		<description><![CDATA[The new version 0.5.10 of the crowd-stefanwille fixes a bug in handling of validation factors. Correct handling of validation factors is necessary for interoperable single sign on with other Atlassian products.]]></description>
			<content:encoded><![CDATA[<p>The new version 0.5.10 of the crowd-stefanwille fixes a bug in handling of validation factors.</p>
<p>Correct handling of validation factors is necessary for interoperable single sign on with other Atlassian products.</p>
]]></content:encoded>
			<wfw:commentRss>http://stefanwille.com/2010/07/version-0-5-10-of-crowd-gem-released/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Ruby Gem for Crowd 2</title>
		<link>http://stefanwille.com/2010/07/ruby-gem-for-crowd-2/</link>
		<comments>http://stefanwille.com/2010/07/ruby-gem-for-crowd-2/#comments</comments>
		<pubDate>Mon, 19 Jul 2010 20:45:55 +0000</pubDate>
		<dc:creator>Stefan</dc:creator>
				<category><![CDATA[Other]]></category>

		<guid isPermaLink="false">http://stefanwille.com/?p=347</guid>
		<description><![CDATA[I took the Ruby client gem for Atlassian Crowd 1.6 from http://liff.github.com/crowd and updated it for Crowd 2. Also I added a new demo script that makes it easier to get started.  Tested with Crowd 2.0.5. Get it via gem install crowd-stefanwille Get more info from http://github.com/stefanwille/crowd.]]></description>
			<content:encoded><![CDATA[<p>I took the Ruby client gem for Atlassian Crowd 1.6 from http://liff.github.com/crowd and updated it for Crowd 2. Also I added a new demo script that makes it easier to get started.  Tested with Crowd 2.0.5.</p>
<p>Get it via</p>
<blockquote><p>gem install crowd-stefanwille</p></blockquote>
<p>Get more info from <a href="http://github.com/stefanwille/crowd" onclick="pageTracker._trackPageview('/outgoing/github.com/stefanwille/crowd?referer=');">http://github.com/stefanwille/crowd</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://stefanwille.com/2010/07/ruby-gem-for-crowd-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Why &#8216;bundle install&#8217; is slow (and how to make it fast)</title>
		<link>http://stefanwille.com/2010/07/why-is-bundle-install-slow-and-how-to-get-it-fast/</link>
		<comments>http://stefanwille.com/2010/07/why-is-bundle-install-slow-and-how-to-get-it-fast/#comments</comments>
		<pubDate>Mon, 12 Jul 2010 18:28:37 +0000</pubDate>
		<dc:creator>Stefan</dc:creator>
				<category><![CDATA[Ruby on Rails]]></category>

		<guid isPermaLink="false">http://stefanwille.com/?p=318</guid>
		<description><![CDATA[A plain 'bundle install' in Capistrano is usually quite slow, but can be much faster.]]></description>
			<content:encoded><![CDATA[<p>I use Bundler&#8217;s command <code>bundle install</code> with Capistrano and it used to takes many seconds to complete. The reason was that Bundler fetched all required gems unless they were already installed and then checked for all dependent gems if there is are newer versions available and installed these. It&#8217;s the last step that took so long.</p>
<p><span id="more-318"></span></p>
<p>The solution is to do a <code>bundle lock</code> in development and to add the resulting file <code>Gemfile.lock</code> to your VCS. During <code>bundle lock</code>, Bundler writes all dependent gems and their specific version numbers to <code>Gemfile.lock</code>. This way, it will only search these gems and will not try to use the latest ones. And because these gems are already deployed after the first deployment, <code>bundle install</code> can complete quickly.</p>
<p>Another advantage is that your deployment environment will use exactly the same gem versions as your development system.</p>
<p>The bundler home page explains <a href="http://gembundler.com/bundle_lock.html" onclick="pageTracker._trackPageview('/outgoing/gembundler.com/bundle_lock.html?referer=');">how to use bundle lock</a>.</p>
<p><strong>Update</strong>: The latest bundler version 0.9.26 always performs a <em>bundle lock</em> implicitly when you run <em>bundle install</em>.</p>
]]></content:encoded>
			<wfw:commentRss>http://stefanwille.com/2010/07/why-is-bundle-install-slow-and-how-to-get-it-fast/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Why You Should Split Your Epics Into Smaller User Stories</title>
		<link>http://stefanwille.com/2010/04/why-you-should-split-your-epics-into-smaller-user-stories/</link>
		<comments>http://stefanwille.com/2010/04/why-you-should-split-your-epics-into-smaller-user-stories/#comments</comments>
		<pubDate>Tue, 06 Apr 2010 19:50:40 +0000</pubDate>
		<dc:creator>Stefan</dc:creator>
				<category><![CDATA[Agile]]></category>

		<guid isPermaLink="false">http://stefanwille.com/?p=252</guid>
		<description><![CDATA[Probably every agile book recommends to split large user stories (epics) into smaller ones. But why?  The reason is usually 'because they are more manageable', but I didn't really understand what that was supposed to mean. Until recently, when we worked on two epics. And I had an insight that I am eager to share.
]]></description>
			<content:encoded><![CDATA[<p>Probably every agile book recommends to split large user stories (epics) into smaller ones. But why?  The reason is usually &#8216;because they are more manageable&#8217;, but I didn&#8217;t really understand what that was supposed to mean. Until recently, when we worked on two epics. And I had an insight that I am eager to share.</p>
<p><span id="more-252"></span></p>
<p><strong>How not to do it</strong></p>
<p>We kept the first epic as a single big story. During development, it was hard to see where we really stood with the story and how much work was left. Quite frustrating. And it took longer than estimated. In between we wanted to cut features, but we developers didn&#8217;t understand the motivation behind each, so it was hard to come up with suggestions. In the end it was a few 100% over estimate.</p>
<p><strong>Splitting Epics</strong></p>
<p>After this experience, we got smarter and we split the second epic into many small stories. This made a big difference. Estimating the small stories was much easier. We could prioritize the smaller stories against each other. Progress was easily measurable. We could select a subset of stories that would allow us to start using the epic even before it was complete. Which meant that we generated business value and got feedback early on.</p>
<p><strong>Schedule Independently<br />
</strong></p>
<p>So far this was great, yet not surprising. But I found an important extra benefit: When it was clear that building all stories in one go would take too much time, we could move the expensive, lower value stories further down in our backlog. It was fairly easy to delay the lower value elements and build other, non related stories first.</p>
<p>Effectively, we categorized the epic&#8217;s stories into three categories:</p>
<ol>
<li>The parts that we <em>really</em> couldn&#8217;t live without for another month</li>
<li>The elements that we <em>really</em> needed at some later point, plus the really quick ones</li>
<li>Everything else</li>
</ol>
<p>We built category 1 immediately. Then we built some other pressing stuff, which was completely unrelated to the epic. Then we got to category 2. Which means we could interleave some important, nonrelated stories within our epic, and yet have cohesive feature sets in each step. A big benefit.</p>
<p><strong>Save Effort<br />
</strong></p>
<p>After we build category 2, we <em>axed</em> category 3. We just didn&#8217;t build it. This is yet another benefit: Splitting stories makes it easier to find the elements that are not really required.</p>
<p>Next time your PO brings an epic, make sure to slice it into stories that can be completed in a few days or less.</p>
]]></content:encoded>
			<wfw:commentRss>http://stefanwille.com/2010/04/why-you-should-split-your-epics-into-smaller-user-stories/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Let Business People Get Their Statistics Themselves</title>
		<link>http://stefanwille.com/2010/01/let-business-people-get-their-statistics-themselves/</link>
		<comments>http://stefanwille.com/2010/01/let-business-people-get-their-statistics-themselves/#comments</comments>
		<pubDate>Wed, 13 Jan 2010 09:51:57 +0000</pubDate>
		<dc:creator>Stefan</dc:creator>
				<category><![CDATA[Agile]]></category>

		<guid isPermaLink="false">http://stefanwille.com/?p=224</guid>
		<description><![CDATA[I found that, once you have a productive software, your business people ask for numbers, statistics and reports from your database, on a weekly or monthly basis. And this keeps interrupting your workflow. And it also keeps you from coding. So what to do? Not so good: I tried to give business people a report [...]]]></description>
			<content:encoded><![CDATA[<p>I found that, once you have a productive software, your business people ask for numbers, statistics and reports from your database, on a weekly or monthly basis. And this keeps interrupting your workflow. And it also keeps you from coding. So what to do?</p>
<p><span id="more-224"></span></p>
<p>Not so good: I tried to give business people a report generator, and have somebody prepare reports. Doesn&#8217;t work well, because reports definitions break with DDL changes.</p>
<p>What works for me is to let business people query the database themselves. In the morning, the production database gets copied to a separate server. There, my colleagues access it using MySQL query browser via an SSH tunnel. We collect the SQL queries that they typically use in a Wiki, and they adapt the queries if they need small variations. Of course, this only works because my colleagues understand a bit of SQL. </p>
<p>Less interruptions, more joy.</p>
]]></content:encoded>
			<wfw:commentRss>http://stefanwille.com/2010/01/let-business-people-get-their-statistics-themselves/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Looking for Ruby on Rails Developer for Balao in Hamburg</title>
		<link>http://stefanwille.com/2009/10/looking-for-ruby-on-rails-developer-for-balao-gmbh-in-hamburg/</link>
		<comments>http://stefanwille.com/2009/10/looking-for-ruby-on-rails-developer-for-balao-gmbh-in-hamburg/#comments</comments>
		<pubDate>Wed, 28 Oct 2009 17:23:17 +0000</pubDate>
		<dc:creator>Stefan</dc:creator>
				<category><![CDATA[Ruby on Rails]]></category>

		<guid isPermaLink="false">http://stefanwille.com/?p=210</guid>
		<description><![CDATA[I am searching for a new colleague: A sharp, experienced Ruby on Rails developer for our internet startup Balao in Hamburg. See this. Our company offers an internet service called GratisPay that monetarizes virtual goods in online games. Update: Finished searching]]></description>
			<content:encoded><![CDATA[<p>I am searching for a new colleague: A sharp, experienced Ruby on Rails developer for our internet startup Balao in Hamburg. See <a href="http://gratispay.de/jobs/rails-developer.pdf" onclick="pageTracker._trackPageview('/outgoing/gratispay.de/jobs/rails-developer.pdf?referer=');">this</a>.</p>
<p>Our company offers an internet service called <a href="http://gratispay.com" target="_blank" onclick="pageTracker._trackPageview('/outgoing/gratispay.com?referer=');">GratisPay</a> that monetarizes virtual goods in online games. </p>
<p>Update: Finished searching</p>
]]></content:encoded>
			<wfw:commentRss>http://stefanwille.com/2009/10/looking-for-ruby-on-rails-developer-for-balao-gmbh-in-hamburg/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

