<?xml version="1.0" encoding="UTF-8"?>
<feed xml:lang="en-US" xmlns="http://www.w3.org/2005/Atom">
  <title>WyeWorks Blog - Home</title>
  <id>tag:blog.wyeworks.com,2010:mephisto/</id>
  <generator version="0.8.0" uri="http://mephistoblog.com">Mephisto Drax</generator>
  <link href="http://blog.wyeworks.com/feed/atom.xml" rel="self" type="application/atom+xml"/>
  <link href="http://blog.wyeworks.com/" rel="alternate" type="text/html"/>
  <updated>2010-02-10T11:43:56Z</updated>
  <entry xml:base="http://blog.wyeworks.com/">
    <author>
      <name>sebastian.martinez</name>
    </author>
    <id>tag:blog.wyeworks.com,2010-02-10:3061</id>
    <published>2010-02-10T11:43:00Z</published>
    <updated>2010-02-10T11:43:56Z</updated>
    <category term="Ruby"/>
    <category term="datamapper"/>
    <category term="paperclip"/>
    <category term="sinatra"/>
    <link href="http://blog.wyeworks.com/2010/2/10/making-paperclip-work-with-sinatra-datamapper" rel="alternate" type="text/html"/>
    <title>Making Paperclip work with Sinatra &amp; Datamapper</title>
    <!-- ckey="01574853" -->
<content type="html">
            &lt;p&gt;I was working lately on a Sinatra project, and got fascinated on how fast you can get things up and running.
Everything was beautiful, until I tried to upload a file using paperclip.&lt;/p&gt;


	&lt;p&gt;Although Paperclip was originally built for rails &lt;a href=&quot;http://invalidlogic.com/dm-paperclip/&quot;&gt;Ken Robertson&lt;/a&gt; ported it to Datamapper.
Let me explain in few steps how you can upload with Paperclip, using Datamapper.&lt;/p&gt;


Start declaring your model like this:
&lt;pre&gt;&lt;code&gt;class Resource
  include DataMapper::Resource
  include Paperclip::Resource

  property :id,     Serial

  has_attached_file :file,
                    :url =&amp;gt; &quot;/system/:attachment/:id/:style/:basename.:extension&quot;,
                    :path =&amp;gt; &quot;#{APP_ROOT}/public/system/:attachment/:id/:style/:basename.:extension&quot; 
end
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;You&#8217;ll need to specify your :url and :path options as the ones built into dm-paperclip are merb centric which won&#8217;t quite work. Also set &lt;span class=&quot;caps&quot;&gt;APP&lt;/span&gt;_ROOT to where ever your application root directory with your static Sinatra folder is.&lt;/p&gt;


Now your routes should look something like this:
&lt;pre&gt;&lt;code&gt;post '/upload' do
  resource = Resource.new(:file =&amp;gt; make_paperclip_mash(params[:file]))
  halt &quot;There were some errors processing your request...&quot; unless resource.save
end
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;And there&#8217;s the tricky part, on the &lt;strong&gt;make_paperclip_mash&lt;/strong&gt; method.
Paperclip expects the file object loaded from the form to be in a different form than what is created by default. To fix this you should create a Mash (which is just a Hash, unless you&#8217;re actually using merb):&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;def make_paperclip_mash(file_hash)
  mash = Mash.new
  mash['tempfile'] = file_hash[:tempfile]
  mash['filename'] = file_hash[:filename]
  mash['content_type'] = file_hash[:type]
  mash['size'] = file_hash[:tempfile].size
  mash
end
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;And that&#8217;s it, now you can upload files using Paperclip right on your Sinatra app with Datamapper.
You can check out the code of this example at: &lt;a href=&quot;http://gist.github.com/291877&quot;&gt;sinatra_paperclip.rb&lt;/a&gt;&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://blog.wyeworks.com/">
    <author>
      <name>santiago.pastorino</name>
    </author>
    <id>tag:blog.wyeworks.com,2010-02-01:3009</id>
    <published>2010-02-01T13:11:00Z</published>
    <updated>2010-02-01T13:12:47Z</updated>
    <category term="Ruby"/>
    <category term="lists"/>
    <category term="patch"/>
    <category term="ruby"/>
    <category term="timeline"/>
    <category term="twitter"/>
    <link href="http://blog.wyeworks.com/2010/2/1/4-ways-to-retrieve-a-twitter-list-timeline" rel="alternate" type="text/html"/>
    <title>4 Ways to Retrieve a Twitter List Timeline</title>
    <!-- ckey="01574853" -->
<content type="html">
            &lt;p&gt;For past few days we had been working on the new version of the WyeWorks site, so stay tunned.
This new version will have a twitter section, where the last 5 tweets of our team will be displayed.&lt;/p&gt;


So first thing I had to do was installing the twitter gem:
&lt;pre&gt;&lt;code&gt;gem install twitter&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;In order to achieve this, I&#8217;ve found 3 different ways using the twitter gem, plus one not yet implemented on the gem, that I&#8217;ve already proposed the patch.
The dumbest one would be:&lt;/p&gt;


&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;#!/usr/bin/env ruby

require 'rubygems'
require 'twitter'

users = %w(wyeworks spastorino joseicosta smartinez87 nartub)

tweets = users.map { |user_name| Twitter::Search.new.from(user_name) }.
               inject([]) { |tweets, search| tweets + search.fetch(5).results }.
               sort { |t1, t2| Date.parse(t2.created_at) &amp;lt;=&amp;gt; Date.parse(t1.created_at) }[0,5]

tweets.each do |tweet|
  puts tweet.created_at
  puts tweet.from_user
  puts tweet.profile_image_url
  puts tweet.text
end&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;What this does is retrieve the last 5 tweets of each user and merge them sorted by date.
Obviously, best thing to do would be directly retrieving the last 5 tweets from the @wyeworks/team list.
Only way to do this using the gem requires authentication, despite the list being public.
In order to authenticate, we may take two paths, the first one would be using &lt;span class=&quot;caps&quot;&gt;HTTP&lt;/span&gt; Authentication:&lt;/p&gt;


&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;#!/usr/bin/env ruby

require 'rubygems'
require 'twitter'

httpauth = Twitter::HTTPAuth.new('wyeworks', 'password')
base = Twitter::Base.new(httpauth)
base.list_timeline('wyeworks', 'team', :page =&amp;gt; 1, :per_page =&amp;gt; 5).each do |tweet|
  puts tweet.created_at
  puts tweet.user.screen_name
  puts tweet.user.profile_image_url
  puts tweet.text
end&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;The other and preferred way for authentication is OAuth, since we don&#8217;t have to send the user and password through the network.
In order to make OAuth work with twitter, we have to create an application at &lt;a href=&quot;http://twitter.com/apps&quot;&gt;http://twitter.com/apps&lt;/a&gt;
Once we&#8217;ve created the app, twitter provides us with a Consumer Key and a Consumer Secret, needed to authenticate using OAuth&lt;/p&gt;


&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;#!/usr/bin/env ruby

require 'rubygems'
require 'twitter'

oauth = Twitter::OAuth.new('consumer token', 'consumer secret')

begin
  oauth.authorize_from_access(oauth.request_token.token, oauth.request_token.secret)

  base = Twitter::Base.new(oauth)
  base.list_timeline('wyeworks', 'team', :page =&amp;gt; 1, :per_page =&amp;gt; 5).each do |tweet|
    puts tweet.created_at
    puts tweet.user.screen_name
    puts tweet.user.profile_image_url
    puts tweet.text
 end
rescue OAuth::Unauthorized
  puts &quot;&amp;gt; FAIL!&quot; 
end&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;Either of these ways works just fine, but no one completely satisfied me, since we are working with a &lt;strong&gt;public&lt;/strong&gt; list, so as far as I can see authentication is out the question, even more when anyone can see it directly from the web without authenticating.
For this reason, I started looking at the &lt;a href=&quot;http://apiwiki.twitter.com&quot;&gt;Twitter &lt;span class=&quot;caps&quot;&gt;API&lt;/span&gt;&lt;/a&gt; searching for a non-authentication way to do it: &lt;a href=&quot;http://apiwiki.twitter.com/Twitter-REST-API-Method:-GET-list-statuses&quot;&gt;Here&#8217;s&lt;/a&gt; what I found.
You can test that making a request to &lt;a href=&quot;http://api.twitter.com/1/wyeworks/lists/team/statuses.json?page=1&amp;amp;per_page=5&quot;&gt;http://api.twitter.com/1/wyeworks/lists/team/statuses.json?page=1&#38;per_page=5&lt;/a&gt;, obtaining the list as a json, or xml in case you change the .json to .xml&lt;/p&gt;


	&lt;p&gt;So I&#8217;ve came up with this monkey-patch:&lt;/p&gt;


&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;module Twitter
  # :per_page = max number of statues to get at once
  # :page = which page of tweets you wish to get
  def self.list_timeline(list_owner_username, slug, query = {})
    response = HTTParty.get(&quot;http://api.twitter.com/1/#{list_owner_username}/lists/#{slug}/statuses.json&quot;, :query =&amp;gt; query, :format =&amp;gt; :json)
    response.map{|tweet| Hashie::Mash.new tweet}
  end
end&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;Being able to get the list without authenticating by:&lt;/p&gt;


&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;Twitter.list_timeline('wyeworks', 'team', :page =&amp;gt; 1, :per_page =&amp;gt; 5).each do |tweet|
   puts tweet.created_at
   puts tweet.user.screen_name
   puts tweet.user.profile_image_url
   puts tweet.text
end&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;I&#8217;ve already contacted the gem&#8217;s authors, proposing this patch: &lt;a href=&quot;http://github.com/spastorino/twitter/commit/aed3a298b613a508bb9caf93afc7f12c50626ad7&quot;&gt;http://github.com/spastorino/twitter/commit/aed3a298b613a508bb9caf93afc7f12c50626ad7&lt;/a&gt;. Wynn Netherland already told me it&#8217;s pretty probable that it will be approved.&lt;/p&gt;


	&lt;p&gt;Until then, you can make use of this functionality from my fork &lt;a href=&quot;http://twitter.com/spastorino/twitter&quot;&gt;http://twitter.com/spastorino/twitter&lt;/a&gt;&lt;/p&gt;


	&lt;p&gt;&lt;strong&gt;&lt;span class=&quot;caps&quot;&gt;UPDATE&lt;/span&gt; #1:&lt;/strong&gt; My fork was merged into &lt;a href=&quot;http://github.com/jnunemaker/twitter&quot;&gt;http://github.com/jnunemaker/twitter&lt;/a&gt; master branch and twitter 0.8.3 was published through &lt;a href=&quot;http://gemcutter.org/gems/twitter&quot;&gt;Gemcutter&lt;/a&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://blog.wyeworks.com/">
    <author>
      <name>santiago.pastorino</name>
    </author>
    <id>tag:blog.wyeworks.com,2010-01-19:2907</id>
    <published>2010-01-19T20:10:00Z</published>
    <updated>2010-01-21T13:48:15Z</updated>
    <category term="Ruby"/>
    <category term="bugmash"/>
    <category term="rails"/>
    <link href="http://blog.wyeworks.com/2010/1/19/rails-bugmash-an-exciting-first-experience" rel="alternate" type="text/html"/>
    <title>Rails Bugmash an exciting first experience</title>
    <!-- ckey="01574853" -->
<content type="html">
            &lt;p&gt;As many of you must know, last weekend a &lt;a href=&quot;http://bugmash.com&quot;&gt;Railsbridge Bugmash&lt;/a&gt; was celebrated, and I had the honor to be part of it for the first time.
For those who are not aware about what this is, it&#8217;s a virtual event that takes place on irc.freenode.net at #railsbridge channel.
The general idea of these events is to work on the Rails Core, taking a look at the &lt;a href=&quot;https://rails.lighthouseapp.com/projects/8994-ruby-on-rails/overview&quot;&gt;Rails Issue Tracker&lt;/a&gt;. However, given that Rails 3 is about to see the light, this opportunity was intended to deeply test it looking for:&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;Fix a known issue&lt;/li&gt;
		&lt;li&gt;Report a bug&lt;/li&gt;
		&lt;li&gt;Make sure your favorite gem or plugin still works. If not, fork it and make it so.&lt;/li&gt;
		&lt;li&gt;Write a blog post about a certain component&lt;/li&gt;
		&lt;li&gt;Write some documentation&lt;/li&gt;
		&lt;li&gt;Get an app up and running and document what you had to do to upgrade.&lt;/li&gt;
		&lt;li&gt;Create a screencast&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;Each accepted contribution or patch done by a participant, gives him chances to win one of several &lt;a href=&quot;http://bugmash.com/sponsors&quot;&gt;prizes&lt;/a&gt;, the more contributions the more chances you have to win. For further details check out the &lt;a href=&quot;http://railsbridge.org/BugMashGuide.pdf&quot;&gt;Railsbridge Bugmash Guide&lt;/a&gt; and the &lt;a href=&quot;http://wiki.railsbridge.org&quot;&gt;RailsBridge Wiki&lt;/a&gt;.&lt;/p&gt;


	&lt;p&gt;Many bugs were fixed during the event, some &lt;a href=&quot;http://wiki.rubyonrails.org/rails/version3/plugins_and_gems&quot;&gt;plugins and gems were tested&lt;/a&gt;, really interesting discussions took place (specially regarding &lt;a href=&quot;http://guides.rails.info/generators.html&quot;&gt;generators&lt;/a&gt;) and some other articles were made. To mention some:&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;&lt;a href=&quot;http://caffeinedd.com/guides/331-making-generators-for-rails-3-with-thor&quot;&gt;Making Generators for Rails 3 with Thor&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;a href=&quot;http://blog.envylabs.com/2010/01/getting-started-with-the-rails-3-bugmash&quot;&gt;Getting Started with the Rails 3 Bugmash&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;a href=&quot;http://jamesarosen.com/post/339319063&quot;&gt;Getting Rails 3 (pre) up on &lt;span class=&quot;caps&quot;&gt;OSX&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;a href=&quot;http://cakebaker.42dh.com/2010/01/17/rails-3-and-passenger&quot;&gt;Rails 3 and Passenger&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;a href=&quot;http://caffeinedd.com/guides/348-upgrading-to-rails-3&quot;&gt;Upgrading an Application to Rails 3 &#8211; Part 1&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;a href=&quot;http://zigzag.github.com/2010/01/18/customizing-your-scaffold-template-become-easier-in-rails3.html&quot;&gt;Customizing your scaffold template become easier in Rails3&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;a href=&quot;http://hasmanyquestions.wordpress.com/2010/01/17/let-your-sql-growl-in-rails-3&quot;&gt;Let your &lt;span class=&quot;caps&quot;&gt;SQL&lt;/span&gt; Growl in Rails 3&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;a href=&quot;http://blog.trydionel.com/2010/01/16/rails-bugmash-2010&quot;&gt;Rails Bugmash 2010&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;a href=&quot;http://www.madcowley.com/madcode/?p=12&quot;&gt;migrating a rails app from 2.x to 3.0&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;a href=&quot;http://blazingcloud.net/2010/01/17/notes-from-rails-3-bugmash&quot;&gt;Notes from Rails 3 bugmash&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;a href=&quot;http://rails3.community-tracker.com/permalinks/5/notes-from-the-field-upgrading-to-rails-3&quot;&gt;Notes from the field upgrading to Rails 3&lt;/a&gt;&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;And then Jose Valim, motivated by the posts done regarding rails 3 generators, published one himself called &lt;a href=&quot;http://blog.plataformatec.com.br/2010/01/discovering-rails-3-generators&quot;&gt;Discovering Rails 3 Generators&lt;/a&gt;&lt;/p&gt;


	&lt;p&gt;This was my first participation and it was a bloody great experience. During the event I was specially devoted to search bugs on Rails 3 and try to patch them. I managed myself to find 4 code bugs and 1 documentation bug, proposing a solution for all of them. One of them was not approved though, for there was a bigger problem that required José Valim&#8217;s intervention, the 3 other patches were approved.&lt;/p&gt;


	&lt;p&gt;I would also want to highlight the gigantic work done by the organizers, the core team members, and also to all the participants. I strongly valued the support &lt;a href=&quot;http://twitter.com/josevalim&quot;&gt;José Valim&lt;/a&gt;, &lt;a href=&quot;http://twitter.com/lifo&quot;&gt;Pratik Naik&lt;/a&gt; and &lt;a href=&quot;http://twitter.com/nzkoz&quot;&gt;Michael Koziarski&lt;/a&gt; gave me. They were a hell of a help when trying to find solutions for the bugs. Would also want to thank &lt;a href=&quot;http://twitter.com/ryanbigg&quot;&gt;Ryan Bigg&lt;/a&gt; for his cooperation, and specially to &lt;a href=&quot;http://twitter.com/lenary&quot;&gt;Sam Elliott&lt;/a&gt;, an incredible 18 year old guy with a great future ahead.
Besides working together with Ryan and Sam, we kept a really nice chat during almost the entire bugmash. The awesome will to help at #railsbridge really overwhelmed me, where everybody was willing to help each other, something that makes it so much easier for the ones starting to contribute to Rails.&lt;/p&gt;


	&lt;p&gt;I would also want to congrat and thank all the participants for trying to make Rails better. So don&#8217;t hesitate to join the next time, it&#8217;s not as hard as I expected it to be and you would definitely not regret it. Now I&#8217;m really motivated to help others so I&#8217;m going to join to &lt;a href=&quot;http://www.railsmentors.org&quot;&gt;Rails Mentors&lt;/a&gt; on &lt;a href=&quot;http://www.railsbridge.com&quot;&gt;RailsBridge&lt;/a&gt; to give back the good things I received during this experience.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://blog.wyeworks.com/">
    <author>
      <name>sebastian.martinez</name>
    </author>
    <id>tag:blog.wyeworks.com,2009-11-16:2167</id>
    <published>2009-11-16T14:57:00Z</published>
    <updated>2010-02-22T17:22:18Z</updated>
    <category term="active merchant"/>
    <category term="payment"/>
    <category term="recurring"/>
    <link href="http://blog.wyeworks.com/2009/11/16/active-merchant-recurring-billing-part-2" rel="alternate" type="text/html"/>
    <title>Modifying Recurring Billing Transactions</title>
    <!-- ckey="01574853" -->
<content type="html">
            &lt;p&gt;Ok, it&#8217;s been some time we don&#8217;t post something in the blog, past weeks have been crazy at the office but now everything is back to normal, hopefully.&lt;/p&gt;


	&lt;p&gt;In this post I just want to tell that we added an extra ability to the recurring billing for BeanStream Gateway: &lt;strong&gt;Modify an existing transaction.&lt;/strong&gt;&lt;/p&gt;


	&lt;p&gt;It&#8217;s pretty easy, you just need to do something like this:&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;  response = gateway.update_recurring(new_amount ,  new_options) &lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;Remember, same for canceling, as BeanStream uses another &lt;span class=&quot;caps&quot;&gt;API&lt;/span&gt; for managing these kind of transactions, we need to use the account_id for identifying the same, so you must include it on the options.
Then all same options can be passed.&lt;/p&gt;


	&lt;p&gt;Check it out here: &lt;a href=&quot;http://github.com/wyeworks/active_merchant&quot;&gt;http://github.com/wyeworks/active_merchant&lt;/a&gt;.&lt;/p&gt;


	&lt;p&gt;That&#8217;s all, don&#8217;t forget to comment!&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://blog.wyeworks.com/">
    <author>
      <name>sebastian.martinez</name>
    </author>
    <id>tag:blog.wyeworks.com,2009-10-07:1237</id>
    <published>2009-10-07T11:28:00Z</published>
    <updated>2010-02-22T17:19:37Z</updated>
    <category term="active merchant"/>
    <category term="beanstream"/>
    <category term="billing"/>
    <category term="payment"/>
    <category term="recurring"/>
    <link href="http://blog.wyeworks.com/2009/10/7/active-merchant-recurring-billing" rel="alternate" type="text/html"/>
    <title>Active Merchant Recurring Billing</title>
    <!-- ckey="01574853" -->
<content type="html">
            &lt;p&gt;Working on a payment system we had to sort some difficulties when making recurring payments using active merchant. Why? Because we needed to use BeanStream gateway and active merchant does not support recurring billing for this gateway yet.
So I just added the functionality to it.&lt;/p&gt;


	&lt;p&gt;You can check out my fork of Active Merchant that supports recurring billing for this merchant on &lt;a href=&quot;http://github.com/wyeworks/active_merchant&quot;&gt;http://github.com/wyeworks/active_merchant&lt;/a&gt;.&lt;/p&gt;


	&lt;p&gt;Here I leave you an example on how to use it:&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;
require 'rubygems'
require 'active_merchant'

 ActiveMerchant::Billing::Base.mode = :test

  # ActiveMerchant accepts all amounts as Integer values in cents
  # $10.00
  amount = 1000

  # The card verification value is also known as CVV2, CVC2, or CID
  credit_card = ActiveMerchant::Billing::CreditCard.new(
                  :first_name         =&amp;gt; 'Bob',
                  :last_name          =&amp;gt; 'Bobsen',
                  :number             =&amp;gt; '4242424242424242',
                  :month              =&amp;gt; '8',
                  :year               =&amp;gt; '2012',
                  :verification_value =&amp;gt; '123'
                )

  # Validating the card automatically detects the card type
  if credit_card.valid?

    # Create a gateway object for the BeansTream service
    gateway = ActiveMerchant::Billing::BeanstreamGateway.new(
                :login =&amp;gt; 'TestMerchant',
                :password =&amp;gt; 'password',
                :pass_code =&amp;gt; 'pass_code'
              )

    # Make recurring payment for the amount
    response = gateway.recurring(amount, credit_card, {
      :recurring_billing =&amp;gt; {
         :end_of_month =&amp;gt; '1',
         :tax1 =&amp;gt; 0,
         :interval =&amp;gt; {
            :unit =&amp;gt; :months,
            :length =&amp;gt; '1'
          },
          :duration =&amp;gt; {
            :start_date =&amp;gt; Date.today,
            :occurrences =&amp;gt; 5
          }
        })

    if response.success?
      puts &quot;Successfully charged $#{sprintf(&quot;%.2f&quot;, amount / 100)} to the credit card #{credit_card.display_number}. The Account number is #{response.params['rbAccountId']}&quot; 
    else
      raise StandardError, response.message
    end
  end

&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;And that&#8217;s it, you have now created a recurring billing payment.&lt;/p&gt;


	&lt;p&gt;Now, what if you want to cancel the same?
Heres is how to do that:&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;
 gateway.cancel_recurring({ :account_id =&amp;gt; account_id })
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;Pretty easy&#8230;the account_id is the number the gateway responses with when making a recurrent payment, and the passcode is the way of authenticating  in order to make this kind of transactions, and you can find it at the beanstream administrative console.&lt;/p&gt;


	&lt;p&gt;So try it out and have fun!&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://blog.wyeworks.com/">
    <author>
      <name>jose.costa</name>
    </author>
    <id>tag:blog.wyeworks.com,2009-09-18:622</id>
    <published>2009-09-18T16:22:00Z</published>
    <updated>2009-09-18T16:34:19Z</updated>
    <category term="Ruby"/>
    <category term="gems"/>
    <category term="ruby"/>
    <link href="http://blog.wyeworks.com/2009/9/18/generating-pdf-with-odf-report-and-images-support" rel="alternate" type="text/html"/>
    <title>Generating PDF with odf-report and images support</title>
    <!-- ckey="01574853" -->
<content type="html">
            &lt;p&gt;Well i guess many of you might have checked the last edition of the &lt;a href=&quot;http://railsmagazine.com/issues/4&quot;&gt;Rails Magazine&lt;/a&gt;. If not, you may should.&lt;/p&gt;


	&lt;p&gt;In particular one of the articles by Rodrigo Rosenfeld Rosas talks about &lt;span class=&quot;caps&quot;&gt;PDF&lt;/span&gt; generation with odf templates, something I&#8217;ve been playing around in the last few weeks.
He explains the mechanism that can be used for this purpose and finally mentions the &lt;strong&gt;odf-report&lt;/strong&gt; gem by Sandro Duarte which i&#8217;ve been using and forked to add support for image substitutions.&lt;/p&gt;


	&lt;p&gt;&lt;strong&gt;More info here&lt;/strong&gt;: &lt;a href=&quot;http://github.com/josecosta/odf-report&quot;&gt;http://github.com/josecosta/odf-report&lt;/a&gt;&lt;/p&gt;


	&lt;p&gt;Give it a try!&lt;/p&gt;


	&lt;p&gt;&lt;strong&gt;&lt;span class=&quot;caps&quot;&gt;UPDATE&lt;/span&gt;&lt;/strong&gt;
Fork was merged to &lt;a href=&quot;http://github.com/sandrods/odf-report&quot;&gt;master branch&lt;/a&gt;.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://blog.wyeworks.com/">
    <author>
      <name>santiago.pastorino</name>
    </author>
    <id>tag:blog.wyeworks.com,2009-09-11:39</id>
    <published>2009-09-11T18:10:00Z</published>
    <updated>2009-09-12T00:14:41Z</updated>
    <category term="Emacs"/>
    <category term="Ruby"/>
    <category term="emacs"/>
    <category term="ide"/>
    <category term="rails"/>
    <category term="ruby"/>
    <link href="http://blog.wyeworks.com/2009/9/11/my-emacs-for-rails" rel="alternate" type="text/html"/>
    <title>My Emacs for Rails</title>
    <!-- ckey="01574853" -->
<content type="html">
            &lt;p&gt;I&#8217;d like to share with the community my emacs init file and a set of plugins to give a nicer experience on Ruby on Rails development, which you can checkout from http://github.com/spastorino/my_emacs_for_rails/tree/master. 
I have been using this environment under emacs 23, and it has not been tested on other emacs versions, so all feedback is welcome, if something goes wrong please feel free to contact me.&lt;/p&gt;


	&lt;h2&gt;What&#8217;s in the package?&lt;/h2&gt;


	&lt;p&gt;The package provides my customized Emacs init file and some plugins I found very useful to enhance Ruby on Rails development experience.&lt;/p&gt;


	&lt;h3&gt;Plugins&lt;/h3&gt;


	&lt;ul&gt;
	&lt;li&gt;anything&lt;/li&gt;
		&lt;li&gt;auto-complete&lt;/li&gt;
		&lt;li&gt;autotest&lt;/li&gt;
		&lt;li&gt;&lt;a href=&quot;http://cedet.sourceforge.net/&quot;&gt;cedet&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;color-theme&lt;/li&gt;
		&lt;li&gt;&lt;a href=&quot;http://ecb.sourceforge.net/&quot;&gt;ecb&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;find-recursive&lt;/li&gt;
		&lt;li&gt;flymake&lt;/li&gt;
		&lt;li&gt;javascript&lt;/li&gt;
		&lt;li&gt;&lt;a href=&quot;http://ourcomments.org/Emacs/nXhtml/doc/nxhtml.html&quot;&gt;nxhtml&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;a href=&quot;http://eigenclass.org/hiki.rb?rcodetools&quot;&gt;rcodetools&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;rdebug&lt;/li&gt;
		&lt;li&gt;redo&lt;/li&gt;
		&lt;li&gt;ri-emacs&lt;/li&gt;
		&lt;li&gt;&lt;a href=&quot;http://rinari.rubyforge.org/&quot;&gt;rinari&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;ruby-block&lt;/li&gt;
		&lt;li&gt;ruby-mode&lt;/li&gt;
		&lt;li&gt;toggle&lt;/li&gt;
		&lt;li&gt;yaml-mode&lt;/li&gt;
		&lt;li&gt;&lt;a href=&quot;http://code.google.com/p/yasnippet/&quot;&gt;yasnippet&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;a href=&quot;http://github.com/eschulte/yasnippets-rails/tree/master&quot;&gt;yasnippets-rails&lt;/a&gt;&lt;/li&gt;
	&lt;/ul&gt;


	&lt;h2&gt;Installation&lt;/h2&gt;


	&lt;p&gt;Before you can use some plugins you have to install a few packages:&lt;/p&gt;


To use rcodetools you need to install the rcodetools, gem with
&lt;pre&gt;&lt;code&gt;sudo gem install rcodetools&lt;/code&gt;&lt;/pre&gt;
To use autotest you need the ZenTest gem, install it with
&lt;pre&gt;&lt;code&gt;sudo gem install ZenTest&lt;/code&gt;&lt;/pre&gt;
On further post I&#8217;m going to explain how to set it up under the gnome environment using all the beauty that gnome-notifier has.

Checkout the package
&lt;pre&gt;&lt;code&gt;git clone github.com/spastorino/my_emacs_for_rails&lt;/code&gt;&lt;/pre&gt;
 and copy all the files under my_emacs_for_rails directory to ~/.emacs.d directory if it doesn&#8217;t exist you have to create it.

	&lt;h2&gt;Screenshot&lt;/h2&gt;


	&lt;p&gt;You can see here some screenshots to get a taste of the look and feel that this one has.&lt;/p&gt;


	&lt;p&gt;&lt;a href=&quot;http://blog.wyeworks.com/assets/2009/9/11/emacs-screenshot-full.png&quot;&gt;&lt;/a&gt;&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://blog.wyeworks.com/">
    <author>
      <name>sebastian.martinez</name>
    </author>
    <id>tag:blog.wyeworks.com,2009-08-10:308</id>
    <published>2009-08-10T14:55:00Z</published>
    <updated>2009-08-10T14:55:43Z</updated>
    <category term="Ruby"/>
    <category term="cron"/>
    <category term="rails"/>
    <category term="scheduling"/>
    <category term="tasks"/>
    <category term="whenever"/>
    <link href="http://blog.wyeworks.com/2009/8/10/scheduling" rel="alternate" type="text/html"/>
    <title>Scheduling in Ruby</title>
    <!-- ckey="01574853" -->
<content type="html">
            &lt;p&gt;Scheduling tasks is something we all need to know to do, for it&#8217;s quite common in applications. Fetching feeds, indexing some data, processing files at a periodical time, that happens a lot.
You are probably quite familiar then with the linux cron, if you had to deal with scheduling stuff in the past, but there is something you may not. Let me introduce you the &lt;a href=&quot;http://github.com/javan/whenever/tree/master&quot; title=&quot;Whenever&quot;&gt;&lt;strong&gt;Whenever&lt;/strong&gt;&lt;/a&gt; gem. 
What is it? A simple gem to schedule tasks writing them in nice ruby syntax&#8230;just let the gem work it&#8217;s magic and deal with the cron.&lt;/p&gt;


In order to install it, you have to add first the github source, only if you never done it :
&lt;pre&gt;&lt;code&gt;$ gem sources -a http://gems.github.com
$ sudo gem install javan-whenever
&lt;/code&gt;&lt;/pre&gt;

To get started, just place yourself in the app path and type
&lt;pre&gt;&lt;code&gt;$ wheneverize . &lt;/code&gt;&lt;/pre&gt;
This will create an initial config/schedule.rb for you.

	&lt;p&gt;There you can nicely write tasks to run.&lt;/p&gt;


Some examples are: 
&lt;pre&gt;&lt;code&gt;every 3.hours do
    runner &quot;MyModel.some_process&quot; 
    rake &quot;my:rake:task&quot; 
    command &quot;/usr/bin/my_great_command&quot; 
  end

  every 1.day, :at =&amp;gt; '4:30 am' do
    runner &quot;MyModel.task_to_run_at_four_thirty_in_the_morning&quot; 
  end

  every :hour do # Many shortcuts available: :hour, :day, :month, :year, :reboot
    runner &quot;SomeModel.ladeeda&quot; 
  end

  every :sunday, :at =&amp;gt; '12pm' do # Use any day of the week or :weekend, :weekday
    runner &quot;Task.do_something_great&quot; 
  end
&lt;/code&gt;&lt;/pre&gt;

Another nice thing to do is integrate it with Capistrano.
&lt;pre&gt;&lt;code&gt;
 after &quot;deploy:symlink&quot;, &quot;deploy:update_crontab&quot; 

  namespace :deploy do
    desc &quot;Update the crontab file&quot; 
    task :update_crontab, :roles =&amp;gt; :db do
      run &quot;cd #{release_path} &#38;&#38; whenever --update-crontab #{application}&quot; 
    end
  end
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;The official documentation provides this way to integrate it, but we found some little details, and the solution is here for you.&lt;/p&gt;


If you integrate it by the regular way, when making multiple deploys, it will configure several tasks to run in your cron file. Why? Because the path of the current application changed, and the gem uses the path (by adding a comment line) when updating the cron.
What should we do then? Simple,  change the &lt;strong&gt;run&lt;/strong&gt; line with this:
&lt;pre&gt;&lt;code&gt;run &quot;cd #{current_path}; whenever -i #{current_path}/config/schedule.rb&quot; 
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;What have we done? We used the -i option, which makes an update, but passing the comment we want, and make it not to change in every deploy.&lt;/p&gt;


	&lt;p&gt;Feel free to try it and leave your comments !!&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://blog.wyeworks.com/">
    <author>
      <name>jose.costa</name>
    </author>
    <id>tag:blog.wyeworks.com,2009-08-05:237</id>
    <published>2009-08-05T15:02:00Z</published>
    <updated>2009-08-05T15:04:25Z</updated>
    <category term="Ruby"/>
    <category term="brightcove"/>
    <category term="rails"/>
    <category term="ruby"/>
    <link href="http://blog.wyeworks.com/2009/8/5/method-missing-to-simplify-queries-to-an-external-service" rel="alternate" type="text/html"/>
    <title>Method missing to simplify queries to an external service</title>
    <!-- ckey="01574853" -->
<content type="html">
            &lt;p&gt;I know there are several discussions on the usage of method_missing in Ruby.
In this post i&#8217;ll present a pretty simple, yet useful solution that uses method_missing to interact with the &lt;a href=&quot;http://support.brightcove.com/en/docs/getting-started-media-api&quot; title=&quot;Getting Started with the Media API&quot;&gt;Brightcove Media Read &lt;span class=&quot;caps&quot;&gt;API&lt;/span&gt;&lt;/a&gt; (you don&#8217;t need to be familiar with this service, i&#8217;ll explain a little bit in the next few lines).&lt;/p&gt;


	&lt;p&gt;&lt;a href=&quot;http://support.brightcove.com/en/docs/getting-started-media-api&quot; title=&quot;Getting Started with the Media API&quot;&gt;Brightcove Media Read &lt;span class=&quot;caps&quot;&gt;API&lt;/span&gt;&lt;/a&gt; accepts calls of the form:&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;http://api.brightcove.com/services/library?command=find_all_videos
&#38;token=0Z2dtxTdJAxtbZ-d0U7Bhio2V1Rhr5Iafl5FFtDPY8E.

http://api.brightcove.com/services/library?command=find_related_videos
&#38;video_id=123123&#38;token=0Z2dtxTdJAxtbZ-d0U7Bhio2V1Rhr5Iafl5FFtDPY8E.

http://api.brightcove.com/services/library?command=find_videos_by_text
&#38;text=sometextsample&#38;pageSize=100&#38;token=0Z2dtxTdJAxtbZ-d0U7Bhio2V1Rhr5Iafl5FFtDPY8E.&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;A token must be passed on each call, and you could also add more parameters like you would do in a regular &lt;span class=&quot;caps&quot;&gt;GET&lt;/span&gt; request.
What comes back is a &lt;span class=&quot;caps&quot;&gt;JSON&lt;/span&gt; string that can be easily picked up.&lt;/p&gt;


	&lt;p&gt;The key thing here is to notice that there are several commands you could execute from the &lt;a href=&quot;http://docs.brightcove.com/en/media/#Video_Read&quot;&gt;&lt;span class=&quot;caps&quot;&gt;API&lt;/span&gt;&lt;/a&gt;, naturally each with its own name that must be specified in the request right after &#8220;command=&#8221;. Since the &lt;a href=&quot;http://docs.brightcove.com/en/media/#Video_Read&quot;&gt;&lt;span class=&quot;caps&quot;&gt;API&lt;/span&gt;&lt;/a&gt; also provides a set of error codes to address all wrong requests or non-existent commands requests, we simply wanted to forward all the calls to the &lt;a href=&quot;http://docs.brightcove.com/en/media/#Video_Read&quot;&gt;&lt;span class=&quot;caps&quot;&gt;API&lt;/span&gt;&lt;/a&gt; and reply back with its answer. So, in order to avoid defining all &lt;a href=&quot;http://docs.brightcove.com/en/media/#Video_Read&quot;&gt;&lt;span class=&quot;caps&quot;&gt;API&lt;/span&gt;&lt;/a&gt; methods in our Ruby module, we just used the method_missing and forwarded all calls to it, using the name of the method as the &lt;a href=&quot;http://docs.brightcove.com/en/media/#Video_Read&quot;&gt;&lt;span class=&quot;caps&quot;&gt;API&lt;/span&gt;&lt;/a&gt; command.&lt;/p&gt;


	&lt;p&gt;The idea was that a call like:&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;http://api.brightcove.com/services/library?command=find_videos_by_user_id
&#38;user_id=34876423&#38;token=0Z2dtxTdJAxtbZ-d0U7Bhio2V1Rhr5Iafl5FFtDPY8E.&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;became just:&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;Brightcove::ReadProxy.find_videos_by_user_id :user_id =&amp;gt; 34876423&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;We then implemented what we called the Brightcove::ReadProxy in a few lines like shown below:&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;module Brightcove
  module ReadProxy

    TOKEN = '0Z2dtxTdJAxtbZ-d0U7Bhio2V1Rhr5Iafl5FFtDPY8E.'
    SITE = 'http://api.brightcove.com/services/library'

    def self.method_missing(method_id, *args)
      args[0] ||= { }
      args[0].merge!({ :command =&amp;gt; method_id, :token =&amp;gt; TOKEN })
      get SITE, args[0]
    end

    def self.get(url, params)
      http_client = HTTPClient.new
      result = http_client.get(url, params)
      content = nil
      begin
        content = JSON.parse(result.content)
      rescue Exception =&amp;gt; e
        Rails.logger.error e.message
      end
      return content
    end

 end&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;Basically all the magic relies in the method_missing that would convert any call to the Brightcove::ReadProxy module in the format accepted by the &lt;a href=&quot;http://docs.brightcove.com/en/media/#Video_Read&quot;&gt;&lt;span class=&quot;caps&quot;&gt;API&lt;/span&gt;&lt;/a&gt;, without having to define every &lt;a href=&quot;http://docs.brightcove.com/en/media/#Video_Read&quot;&gt;&lt;span class=&quot;caps&quot;&gt;API&lt;/span&gt;&lt;/a&gt; method and maintaining the Rails like finders syntax.
We also used the httpclient gem to simplify the &lt;span class=&quot;caps&quot;&gt;GET&lt;/span&gt; request calls and the json gem to parse the result of the call.&lt;/p&gt;


	&lt;p&gt;I&#8217;m not saying that this is the best usage, but i think in this particular situation it suits pretty well.&lt;/p&gt;


	&lt;p&gt;What do you think?&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://blog.wyeworks.com/">
    <author>
      <name>sebastian.martinez</name>
    </author>
    <id>tag:blog.wyeworks.com,2009-07-27:126</id>
    <published>2009-07-27T16:41:00Z</published>
    <updated>2009-07-27T17:11:41Z</updated>
    <category term="Ruby"/>
    <category term="drag"/>
    <category term="drop"/>
    <category term="list"/>
    <category term="rails"/>
    <category term="ruby"/>
    <category term="sortable"/>
    <link href="http://blog.wyeworks.com/2009/7/27/drag-drop-sortable-lists" rel="alternate" type="text/html"/>
    <title>Drag &amp; Drop Sortable Lists</title>
    <!-- ckey="01574853" -->
<content type="html">
            &lt;p&gt;Time has come for us to make a sortable list, and let&#8217;s face it, drag&#38;drop are the prettiest ones. So, let me explain how to proceed.&lt;/p&gt;


	&lt;p&gt;Suppose you have a playlist with many videos, and want to establish an order on which they will be played. First thing you will need is to add a &#8216;position&#8217; attribute to your Video model. To do that, we&#8217;ll generate a migration first:&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;script/generate migration add_position_to_videos position:integer
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;Now just run &lt;strong&gt;rake db:migrate&lt;/strong&gt;.&lt;/p&gt;


&lt;h3&gt; View Code &lt;/h3&gt;
First thing you need to make sure, is that you have the prototype and scriptaculous libraries in your application. Now let&#8217;s see how your &lt;strong&gt;index.html.erb&lt;/strong&gt; file should look like

&lt;pre&gt;&lt;code&gt;   &amp;lt;h1&amp;gt;Videos&amp;lt;/h1&amp;gt;  
   &amp;lt;ul id=&quot;videos&quot;&amp;gt;  
     &amp;lt;% @videos.each do |video| %&amp;gt;  
       &amp;lt;% content_tag_for :li, video do %&amp;gt;  
         &amp;lt;%= link_to video.name, video_path(video) %&amp;gt;  
       &amp;lt;% end %&amp;gt;  
     &amp;lt;% end %&amp;gt;  
   &amp;lt;/ul&amp;gt;  
   &amp;lt;%= link_to &quot;New Video, new_video_path %&amp;gt;  
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;Now all we have to do to make the list sortable is add the sortable_element helper method to the index view. You need to pass it the id of the element you want to be sortable, and a &lt;span class=&quot;caps&quot;&gt;URL&lt;/span&gt; that is called via an &lt;span class=&quot;caps&quot;&gt;AJAX&lt;/span&gt; request so that the updated positions can be stored in the database.&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;   &amp;lt;%= sortable_element('videos', :url =&amp;gt; 'sort_videos_path') %&amp;gt;  
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;The videos in the list can now be dragged and dropped, but the new order isn’t persisted back to the database.
So let&#8217;s code the sort method in the videos_controller.rb&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;   def sort  
     params[:videos].each_with_index do |id, index|  
       Video.update_all([’position=?’, index+1], [’id=?’, id])  
     end  
     render :nothing =&amp;gt; true  
   end  
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;And that&#8217;s it. We are now updating the position of the videos.
Most probably, we would want now our videos to be shown in the index in the correct order, so we just need to touch the index method on the controller a bit.&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;   def index  
     @videos = Video.all(:order =&amp;gt; ’position’)  
   end  
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;At this point we are almost set to go&#8230;did you guess what&#8217;s missing? Yes, we need to add the route to the sort method :)&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;   map.resources :videos, :collection =&amp;gt; { :sort =&amp;gt; :post}  &lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;The line above adds the new action and makes it a &lt;span class=&quot;caps&quot;&gt;POST&lt;/span&gt; request, which is the type that our &lt;span class=&quot;caps&quot;&gt;AJAX&lt;/span&gt; call uses when making &lt;span class=&quot;caps&quot;&gt;XMLHTTP&lt;/span&gt; requests.
And that&#8217;s pretty much it. Now you have a fully functional sortable list of videos.&lt;/p&gt;


	&lt;p&gt;There are some more tricks we can use to improve this, for example, the &lt;strong&gt;sortable_element&lt;/strong&gt; helper receives one option called &#8216;handle&#8217;. What&#8217;s this? The way to specify the draggable area of the element. This I think is the most used one. Let&#8217;s give it a try:&lt;/p&gt;


We should first add a span tag on the index view:
&lt;pre&gt;&lt;code&gt; &amp;lt;% content_tag_for :li, video do %&amp;gt;  
   &amp;lt;span class=&quot;handle&quot;&amp;gt;[drag]&amp;lt;/span&amp;gt;  
   &amp;lt;%= link_to video.name, video_path(video) %&amp;gt;  
 &amp;lt;% end %&amp;gt; 
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;Note the span has a &#8216;handle&#8217; class, and that&#8217;s what you are going to set as draggable, using the :handle option:&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;   &amp;lt;%= sortable_element(’videos’), :url =&amp;gt; sort_videos_path, :handle =&amp;gt; ’handle’ %&amp;gt;  &lt;/code&gt;&lt;/pre&gt;

You can style this a bit with a &lt;span class=&quot;caps&quot;&gt;CSS&lt;/span&gt;, adding a line similar to this one:
&lt;pre&gt;&lt;code&gt; li .handle { color: #777; cursor: move; font-size: 12px; } &lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;Beautiful&#8230;.just beautiful&#8230;&lt;/p&gt;


	&lt;p&gt;Ok, we have this magical sortable list now, but we added a &#8216;position&#8217; field to videos&#8230;we can handle this manually when creating or updating the videos, or we can use the &lt;strong&gt;acts_as_list&lt;/strong&gt; plugin, which I recommend.
Just install it by typing &lt;pre&gt;&lt;code&gt;script/plugin install git://github.com/rails/acts_as_list.git&lt;/code&gt;&lt;/pre&gt; in your console.
All configuration this needs to work is to add &lt;strong&gt;acts_as_list&lt;/strong&gt; in our model, that should look like this:&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;   class Video &amp;lt; ActiveRecord::Base  
     acts_as_list  
   end  
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;Congrats!!! Enjoy your sortable list !!!&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://blog.wyeworks.com/">
    <author>
      <name>jose.costa</name>
    </author>
    <id>tag:blog.wyeworks.com,2009-07-20:107</id>
    <published>2009-07-20T14:20:00Z</published>
    <updated>2009-07-20T14:20:43Z</updated>
    <category term="Ruby"/>
    <category term="gems"/>
    <category term="ruby"/>
    <category term="rvideo"/>
    <link href="http://blog.wyeworks.com/2009/7/20/rvideo-for-video-processing-and-inspection" rel="alternate" type="text/html"/>
    <title>RVideo for video processing and inspection</title>
    <!-- ckey="01574853" -->
<content type="html">
            &lt;p&gt;At WyeWorks headquarters, every once in a while, we come across some project that needs a media edition/transcoding solution to build into. This was the case of our latest project in which we built a pretty simple interface with &lt;a href=&quot;http://www.brightcove.com/&quot; title=&quot;Brightcove - The Leading Online Video Platform.&quot;&gt;Brightcove&lt;/a&gt;, a powerful video platform on which we may write something about it in our forthcoming posts, but it&#8217;s not the point right now.&lt;/p&gt;


	&lt;p&gt;Turns out to be that Brightcove recommends that files should be encoded using either H.264 or &lt;span class=&quot;caps&quot;&gt;VP6&lt;/span&gt;. As usual, we ask ffmpeg for salvation when we need to transcode media files and this was not the exception. But we didn&#8217;t want to transcode just every file nor make the choice based on the file&#8217;s extension. We wanted a way to check the current file encoding.&lt;/p&gt;


	&lt;p&gt;Searches made at that time lead us to think that the usual way to get a media file encoding is by running:&lt;/p&gt;


	&lt;pre&gt;&lt;code&gt;ffmpeg -i &lt;/code&gt;&lt;/pre&gt;


	&lt;p&gt;which i must say that it&#8217;s pretty ugly for me since that command it&#8217;s supposed to be used for conversion and as far as i know it doesn&#8217;t offer some flag to get only the file information.
In fact, that command returns an error (but still prints the information we need):&lt;/p&gt;


	&lt;pre&gt;&lt;code&gt;jose:~$ ffmpeg -i barsandtone.flv 
FFmpeg version 0.5-svn17737+3:0.svn20090303-1ubuntu6, Copyright (c) 2000-2009 Fabrice Bellard, et al.
  configuration: --enable-gpl --enable-postproc --enable-swscale --enable-x11grab --extra-version=svn17737+3:0.svn20090303-1ubuntu6 --prefix=/usr --enable-avfilter --enable-avfilter-lavf --enable-libgsm --enable-libschroedinger --enable-libspeex --enable-libtheora --enable-libvorbis --enable-pthreads --disable-stripping --disable-vhook --enable-libdc1394 --disable-armv5te --disable-armv6 --disable-armv6t2 --disable-armvfp --disable-neon --disable-altivec --disable-vis --enable-shared --disable-static
  libavutil     49.15. 0 / 49.15. 0
  libavcodec    52.20. 0 / 52.20. 0
  libavformat   52.31. 0 / 52.31. 0
  libavdevice   52. 1. 0 / 52. 1. 0
  libavfilter    0. 4. 0 /  0. 4. 0
  libswscale     0. 7. 1 /  0. 7. 1
  libpostproc   51. 2. 0 / 51. 2. 0
  built on Apr 10 2009 23:18:41, gcc: 4.3.3
Input #0, flv, from 'barsandtone.flv':
  Duration: 00:00:06.00, start: 0.000000, bitrate: 505 kb/s
    Stream #0.0: Video: &lt;strong&gt;vp6f&lt;/strong&gt;, yuv420p, 360x288, 409 kb/s, 1k tbr, 1k tbn, 1k tbc
    Stream #0.1: Audio: mp3, 44100 Hz, stereo, s16, 96 kb/s
  &lt;strong&gt;Must supply at least one output file&lt;/strong&gt;&lt;/code&gt;&lt;/pre&gt;


	&lt;p&gt;The information we need is the video codec (in this case vp6f) to determine if we need to transcode it.&lt;/p&gt;


	&lt;p&gt;Another thing to mention is that nothing that you see as the output there outputs to the stdout.
No rocket science needed but i was kind of lazy to parse this from scratch. Lucky for me, there was this not so new &lt;a href=&quot;http://code.google.com/p/rvideo/&quot; title=&quot;rvideo&quot;&gt;rvideo&lt;/a&gt; gem (still unknown for me) that made me save some precious time.&lt;/p&gt;


	&lt;p&gt;&lt;a href=&quot;http://code.google.com/p/rvideo/&quot; title=&quot;rvideo&quot;&gt;RVideo&lt;/a&gt; still relies in ffmpeg command and also it&#8217;s internal work to get the information we need involves that same output parsing, you just don&#8217;t have to do it yourself. 
After installation (not covered here, just check rvideo readme file), you can do things as shown below:&lt;/p&gt;


	&lt;pre&gt;&lt;code&gt;inspector = RVideo::Inspector.new(:file =&amp;gt; file.path)
inspector.video_codec
=&amp;gt; &quot;vp6f&quot; 
inspector.duration
=&amp;gt; 6000
inspector.audio_codec
=&amp;gt; &quot;mp3&quot;&lt;/code&gt;&lt;/pre&gt;


	&lt;p&gt;We&#8217;ve just made a tiny introduction to inspection. I&#8217;m not covering video processing. Check &lt;a href=&quot;http://code.google.com/p/rvideo/&quot; title=&quot;rvideo&quot;&gt;rvideo&lt;/a&gt; for more details!
Enjoy!&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://blog.wyeworks.com/">
    <author>
      <name>santiago.pastorino</name>
    </author>
    <id>tag:blog.wyeworks.com,2009-07-13:96</id>
    <published>2009-07-13T21:54:00Z</published>
    <updated>2009-07-13T21:57:01Z</updated>
    <category term="Ruby"/>
    <category term="file upload"/>
    <category term="paperclip"/>
    <category term="plugins"/>
    <category term="rails"/>
    <category term="ruby"/>
    <link href="http://blog.wyeworks.com/2009/7/13/paperclip-file-rename" rel="alternate" type="text/html"/>
    <title>Paperclip file rename</title>
    <!-- ckey="01574853" -->
<content type="html">
            &lt;p&gt;While developing an application with Sebastián that allow users to upload videos with some file name restrictions, meaning that it must contain only A-Z and 0-9 digits, underscores (_) as a valid component as well, and also the name must be preceded by it&#8217;s own #id, we came up with the need of applying this custom filter to each uploaded video.
After doing some research on paperclip source code and internet tutorials, we suggest the following solution:&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;class Video &amp;lt; ActiveRecord::Base
  has_attached_file :video,
    :path =&amp;gt; &quot;:rails_root/public/system/:attachment/:id/:style/:normalized_video_file_name&quot;,
    :url =&amp;gt; &quot;/system/:attachment/:id/:style/:normalized_video_file_name&quot; 

  Paperclip.interpolates :normalized_video_file_name do |attachment, style|
    attachment.instance.normalized_video_file_name
  end

  def normalized_video_file_name
    &quot;#{self.id}-#{self.video_file_name.gsub( /[^a-zA-Z0-9_\.]/, '_')}&quot; 
  end
end&lt;/code&gt;&lt;/pre&gt;

What are we doing here? Easy, in &lt;strong&gt;has_attached_file&lt;/strong&gt; we edit the way paperclip returns the &lt;strong&gt;path&lt;/strong&gt; and &lt;strong&gt;url&lt;/strong&gt; by default, the most relevant components when saving and loading the file in order to display it.
Paperclip default values are:
&lt;pre&gt;&lt;code&gt;path default =&amp;gt; &quot;:rails_root/public/system/:attachment/:id/:style/:filename&quot; 
url default =&amp;gt; &quot;/system/:attachment/:id/:style/:filename&quot;&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;Values preceded by  &#8217;:&#8217; are the standard interpolations paperclip has. For further information on this visit &lt;a href=&quot;http://wiki.github.com/thoughtbot/paperclip/interpolations&quot; title=&quot;Interpolations&quot;&gt;http://wiki.github.com/thoughtbot/paperclip/interpolations&lt;/a&gt;.&lt;/p&gt;


	&lt;p&gt;What we did was change &lt;strong cite=&quot;filename&quot;&gt;* with *:normalized_video_file_name&lt;/strong&gt; in both path and url, being the second a custom interpolation and then added the &#8216;normalized_video_file_name&#8217; method to video.rb.&lt;/p&gt;


	&lt;p&gt;By doing this we not only achieve a way for paperclip to handle the file by this normalized way, but also have a method to access the normalized file name, plus being able to access the original file name through paperclip video_file_name method.&lt;/p&gt;


	&lt;p&gt;So remember on video_file_name you have the uploaded filename and on normalized_video_file_name you have the server filename.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://blog.wyeworks.com/">
    <author>
      <name>martin.alcala</name>
    </author>
    <id>tag:blog.wyeworks.com,2009-07-06:127</id>
    <published>2009-07-06T14:38:00Z</published>
    <updated>2009-07-06T20:39:33Z</updated>
    <category term="Marketing"/>
    <category term="innovation"/>
    <category term="rails"/>
    <category term="ruby"/>
    <category term="web"/>
    <category term="wyeworks"/>
    <link href="http://blog.wyeworks.com/2009/7/6/is-your-product-innovative" rel="alternate" type="text/html"/>
    <title>Is your product Innovative?</title>
    <!-- ckey="01574853" -->
<content type="html">
            &lt;p&gt;That&#8217;s a good question, in fact, can we quantify or measure how much &#8220;innovation&#8221; quantity exists in our product or services?. Well, there are as much answers as successful products ;-) but in general terms we can group Innovation in three categories:&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;Business Model

	&lt;p&gt;Is your Business Model Innovative? did you find out a new way to sell? did you find out an hidden need of the community? Starbucks would be a nice example.&lt;/p&gt;
&lt;/li&gt;
		&lt;li&gt;Tech

	&lt;p&gt;Did you invent new super algorithm to ultra-fast classify all the info on the web ;-) &#8211; that a techy innovation -. Tech is a great point for innovation, but not the only one, think about twitter for example.&lt;/p&gt;
&lt;/li&gt;
		&lt;li&gt;Design	&lt;p&gt;Design in fact is key a factor for innovation, for example think about the IPhone or the IPod, the key was the design and the marketing.&lt;/p&gt;


	&lt;p&gt;So you reader, Rails Enthusiast, Ruby Rockstar, Code Ninja, are you ready to innovate in the wide sense or the word?&lt;/p&gt;&lt;/li&gt;
	&lt;/ul&gt;
          </content>  </entry>
  <entry xml:base="http://blog.wyeworks.com/">
    <author>
      <name>sebastian.martinez</name>
    </author>
    <id>tag:blog.wyeworks.com,2009-06-04:79</id>
    <published>2009-06-04T15:11:00Z</published>
    <updated>2009-07-16T18:57:53Z</updated>
    <category term="Ruby"/>
    <category term="delegate"/>
    <category term="delegation"/>
    <category term="rails"/>
    <category term="ruby"/>
    <link href="http://blog.wyeworks.com/2009/6/4/rails-delegate-method" rel="alternate" type="text/html"/>
    <title>Rails delegate method</title>
    <!-- ckey="01574853" -->
<content type="html">
            &lt;p&gt;Delegation is a feature Rails introduced in it&#8217;s 2.2 version, and in my opinion are quite useful and somehow something we don&#8217;t see too much around.
The concept of delegation is to take some methods and send them off to another object to be processed.&lt;/p&gt;


	&lt;p&gt;Let me explain this with a brief example:&lt;/p&gt;


	&lt;p&gt;Suppose you have a User class for anyone registered on your site, and a Customer class for those who have actually placed orders:&lt;/p&gt;


&lt;pre&gt;
&lt;code class=&quot;ruby&quot;&gt;class User &amp;lt; ActiveRecord::Base  
   belongs_to :customer  
end  

class Customer &amp;lt; ActiveRecord::Base  
   has_one :user  
end&lt;/code&gt;
&lt;/pre&gt;

	&lt;p&gt;As for now, if you are in a Customer instance, you can get their User information doing &lt;strong&gt;@customer.user.name&lt;/strong&gt;, or &lt;strong&gt;@customer.user.email&lt;/strong&gt;.
Delegation allows you to simplify this:&lt;/p&gt;


&lt;pre&gt;
&lt;code class=&quot;ruby&quot;&gt;class User &amp;lt; ActiveRecord::Base  
   belongs_to :customer  
end  

class Customer &amp;lt; ActiveRecord::Base  
   has_one :user  
   delegate :name, :name=, :email, :email=, :to =&amp;gt; :user  
end&lt;/code&gt;
&lt;/pre&gt;

	&lt;p&gt;Now you can refer to &lt;strong&gt;@customer.name&lt;/strong&gt; and &lt;strong&gt;@customer.email&lt;/strong&gt; to retrieve and set values for those attributes directly. Pretty nice, huh?&lt;/p&gt;


	&lt;p&gt;We are now working on some code to make possible to inherit behaviour, along with polymorphic associations, so when you create a Cutomer, the User gets created as well with the data you provided when creating the customer, and so on.&lt;/p&gt;


	&lt;p&gt;So keep posted, for there will be more to come&#8230;&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://blog.wyeworks.com/">
    <author>
      <name>jose.costa</name>
    </author>
    <id>tag:blog.wyeworks.com,2009-04-20:37</id>
    <published>2009-04-20T15:27:00Z</published>
    <updated>2009-04-20T15:27:06Z</updated>
    <category term="Ruby"/>
    <category term="full-text search"/>
    <category term="sphinx"/>
    <category term="thinking sphinx"/>
    <link href="http://blog.wyeworks.com/2009/4/20/wildcard-search-with-thinking-sphinx" rel="alternate" type="text/html"/>
    <title>Wildcard search with Thinking Sphinx</title>
    <!-- ckey="01574853" -->
<content type="html">
            &lt;p&gt;Right after starting with &lt;a href=&quot;http://ts.freelancing-gods.com/&quot; title=&quot;Thinking Sphinx plugin&quot;&gt;Thinking Sphinx&lt;/a&gt;, it was quite hard to find a concise guide on how to enable wildcard search.
For those out there who might not know, &lt;a href=&quot;http://www.sphinxsearch.com/&quot; title=&quot;Sphinx  free open-source SQL full-text search engine&quot;&gt;Sphinx&lt;/a&gt; searches default to matching whole words, not partial ones, so you won’t get any results of you search, for example, for one letter or part of a name. So, how to get around this?? .. well .. &lt;a href=&quot;http://www.sphinxsearch.com/&quot; title=&quot;Sphinx  free open-source SQL full-text search engine&quot;&gt;Sphinx&lt;/a&gt; provides wildcard search and below is how you can enable this with &lt;a href=&quot;http://ts.freelancing-gods.com/&quot; title=&quot;Thinking Sphinx plugin&quot;&gt;Thinking Sphinx&lt;/a&gt;&lt;/p&gt;


	&lt;h2&gt;How wildcard search works in Sphinx?&lt;/h2&gt;


There are basically three settings that rule the wildcard search world:
	&lt;ul&gt;
	&lt;li&gt;enable_star&lt;/li&gt;
		&lt;li&gt;min_prefix_len&lt;/li&gt;
		&lt;li&gt;min_infix_len&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;&lt;strong&gt;enabled_star is required plus one of the other two for settings for enabling either prefix or infix search (can&#8217;t have both, at least on the same index).&lt;/strong&gt;&lt;/p&gt;


	&lt;h3&gt;enable_star&lt;/h3&gt;


	&lt;p&gt;This settings enables &#8220;star-syntax&#8221;, or wildcard syntax (means that &#8217;&#42;&#8217; can be used at the start and/or end of the keyword), when searching through indexes which were created with prefix or infix indexing enabled. The star will match zero or more characters.&lt;/p&gt;


	&lt;p&gt;It only affects searching; so it can be changed without reindexing by simply restarting searchd.&lt;/p&gt;


	&lt;p&gt;For example, assume that the index was built with infixes and that enable_star is 1. Searching should work as follows:&lt;/p&gt;


	&lt;ol&gt;
	&lt;li&gt;&#8220;abcdef&#8221; query will match only those documents that contain the exact &#8220;abcdef&#8221; word in them.&lt;/li&gt;
		&lt;li&gt;&#8220;abc&#42;&#8221; query will match those documents that contain any words starting with &#8220;abc&#8221; (including the documents which contain the exact &#8220;abc&#8221; word only);&lt;/li&gt;
		&lt;li&gt;&#8221;&#42;cde&#42;&#8221; query will match those documents that contain any words which have &#8220;cde&#8221; characters in any part of the word (including the documents which contain the exact &#8220;cde&#8221; word only).&lt;/li&gt;
		&lt;li&gt;&#8221;&#42;def&#8221; query will match those documents that contain any words ending with &#8220;def&#8221; (including the documents that contain the exact &#8220;def&#8221; word only).&lt;/li&gt;
	&lt;/ol&gt;


	&lt;h3&gt;min_prefix_len&lt;/h3&gt;


	&lt;p&gt;Minimum word prefix length to index. Optional, default is 0 (do not index prefixes). 
For instance, indexing a keyword &#8220;example&#8221; with min_prefix_len=3 will result in indexing &#8220;exa&#8221;, &#8220;exam&#8221;, &#8220;examp&#8221;, &#8220;exampl&#8221; prefixes along with the word itself. Searches against such index for &#8220;exam&#8221; will match documents that contain &#8220;example&#8221; word, even if they do not contain &#8220;exam&#8221; on itself.  Too short prefixes (below the minimum allowed length) will not be indexed.&lt;/p&gt;


	&lt;h3&gt;min_infix_len&lt;/h3&gt;


	&lt;p&gt;Infix indexing allows to implement wildcard searching by &#8216;start&#42;&#8217;, &#8217;&#42;end&#8217;, and &#8217;&#42;middle&#42;&#8217; wildcards. When mininum infix length is set to a positive number, indexer will index all the possible keyword infixes (ie. substrings) in addition to the keywords themselves. Too short infixes (below the minimum allowed length) will not be indexed.&lt;/p&gt;


	&lt;p&gt;For instance, indexing a keyword &#8220;test&#8221; with min_infix_len=2 will result in indexing:&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;&#8220;te&#8221; &lt;/li&gt;
		&lt;li&gt;&#8220;es&#8221; &lt;/li&gt;
		&lt;li&gt;&#8220;st&#8221; &lt;/li&gt;
		&lt;li&gt;&#8220;tes&#8221; &lt;/li&gt;
		&lt;li&gt;&#8220;est&#8221;&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;infixes along with the word itself. Searches against such index for &#8220;es&#8221; will match documents that contain &#8220;test&#8221; word, even if they do not contain &#8220;es&#8221; on itself.&lt;/p&gt;


	&lt;h2&gt;Drawbacks :(&lt;/h2&gt;


	&lt;p&gt;Indexing prefixes will make the index grow significantly (because of many more indexed keywords), and will degrade both indexing and searching times. 
Also, there&#8217;s no automatic way to rank perfect word matches higher in a prefix index, but there&#8217;s a number of tricks to achieve that (setup to indexes or extended-mode queries. Read more &lt;a href=&quot;http://www.sphinxsearch.com/docs/current.html#searching&quot;&gt;here&lt;/a&gt;).&lt;/p&gt;


	&lt;h2&gt;Show me some code!&lt;/h2&gt;


	&lt;p&gt;So, here it&#8217;s how you can set a wildcard search on a particular index for any of your models. In this case i&#8217;m setting an infix search.&lt;/p&gt;


&lt;pre&gt;
&lt;code class=&quot;ruby&quot;&gt;class Article &amp;lt; ActiveRecord::Base
  ....
  ....

  define_index do
    indexes title, body, author
    set_property :enable_star =&amp;gt; 1
    set_property :min_infix_len =&amp;gt; 3
  end

  ....
  ....
end&lt;/code&gt;
&lt;/pre&gt;

	&lt;p&gt;You can also set these properties in your sphinx.yml settings file under config/ folder for any environment you want. It might look like this:&lt;/p&gt;


&lt;pre&gt;
&lt;code&gt;production:
  enable_star: 1
  min_infix_len: 3&lt;/code&gt;
&lt;/pre&gt;

	&lt;p&gt;and it will apply to all of your indexes.&lt;/p&gt;


	&lt;p&gt;Re-index your data and restart the sphinx deamon (remember i&#8217;m using Thinking Sphinx, so i have a set of nice and short rake tasks to achieve this).&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;rake ts:stop
rake ts:in
rake ts:start&lt;/code&gt;&lt;/pre&gt;

Now you should be able to fire searches like this:
&lt;pre&gt;&lt;code&gt;Article.search &quot;Sphinx&quot; 
Article.search &quot;Think*&quot; 
Article.search &quot;*inx*&quot; 
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;And many more cool stuff that&#8217;s beyond the scope of this post :)
Enjoy!&lt;/p&gt;
          </content>  </entry>
</feed>
