<?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>dan.thoughts &#187; Web Services</title>
	<atom:link href="http://blog.sosedoff.com/category/web-services/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.sosedoff.com</link>
	<description>Web-development, PHP, Ruby, Sinatra, Merb, Rails, MySQL, SQLite, Web Services.</description>
	<lastBuildDate>Wed, 25 Jan 2012 18:54:45 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Mapster &#8211; the right place for your travel feed.</title>
		<link>http://blog.sosedoff.com/2011/01/22/mapster-the-right-place-for-your-travel-feed/</link>
		<comments>http://blog.sosedoff.com/2011/01/22/mapster-the-right-place-for-your-travel-feed/#comments</comments>
		<pubDate>Sun, 23 Jan 2011 02:58:59 +0000</pubDate>
		<dc:creator>Dan Sosedoff</dc:creator>
				<category><![CDATA[Apps]]></category>
		<category><![CDATA[Web Services]]></category>

		<guid isPermaLink="false">http://blog.sosedoff.com/?p=328</guid>
		<description><![CDATA[Hey folks, 
My friend and co-worker Roman Efimov has released his app for photo-sharing and geo-taggin. It is a perfect app if you&#8217;re looking for an alternative of iphone&#8217;s places feature. It lets you upload all your photos and will automatically geo-tag them with locations if you have GPS feature enabled in your photo settings. [...]]]></description>
			<content:encoded><![CDATA[<p>Hey folks, </p>
<p>My friend and co-worker <a href="http://romaonthego.com/">Roman Efimov</a> has released his app for photo-sharing and geo-taggin. It is a perfect app if you&#8217;re looking for an alternative of iphone&#8217;s places feature. It lets you upload all your photos and will automatically geo-tag them with locations if you have GPS feature enabled in your photo settings. </p>
<p>Check out <a href="http://mapster.co/">Mapster</a></p>
<p><center><br />
<a href="http://blog.sosedoff.com/wp-content/uploads/2011/01/Screen-shot-2011-01-22-at-8.47.44-PM.png"><img src="http://blog.sosedoff.com/wp-content/uploads/2011/01/Screen-shot-2011-01-22-at-8.47.44-PM.png" alt="Screen shot 2011-01-22 at 8.47.44 PM" title="Screen shot 2011-01-22 at 8.47.44 PM" width="500" class="alignnone size-full wp-image-329" /></a><br />
</center></p>
<p>It is still in early stage, but you&#8217;re welcome to check it out!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.sosedoff.com/2011/01/22/mapster-the-right-place-for-your-travel-feed/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Basecamp authentication with Rails and Authlogic</title>
		<link>http://blog.sosedoff.com/2011/01/22/basecamp-authentication-with-rails-and-authlogic/</link>
		<comments>http://blog.sosedoff.com/2011/01/22/basecamp-authentication-with-rails-and-authlogic/#comments</comments>
		<pubDate>Sun, 23 Jan 2011 02:27:43 +0000</pubDate>
		<dc:creator>Dan Sosedoff</dc:creator>
				<category><![CDATA[Rails]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Web Services]]></category>
		<category><![CDATA[authlogic]]></category>
		<category><![CDATA[basecamp]]></category>

		<guid isPermaLink="false">http://blog.sosedoff.com/?p=321</guid>
		<description><![CDATA[If you&#8217;re building a service that works directly with Basecamp you might want your users to login with their existing basecamp account. That gives you ability to use your app as if it was build-in into basecamp. I&#8217;ll just write a small example how to use it. I know about openID but this is a [...]]]></description>
			<content:encoded><![CDATA[<p>If you&#8217;re building a service that works directly with Basecamp you might want your users to login with their existing basecamp account. That gives you ability to use your app as if it was build-in into basecamp. I&#8217;ll just write a small example how to use it. I know about openID but this is a little bit different story. </p>
<p>Potential use-case could be an app where you store all your private data without storing it to basecamp. Like configuration files, maybe passwords, etc.</p>
<h3>The task</h3>
<p>- Allow existing basecamp users use the same login without being redirected to signup page<br />
- Any desired app functionality</p>
<h3>Basecamp API</h3>
<p>Take a look at the API documentation &#8211; <a href="http://developer.37signals.com/basecamp/">http://developer.37signals.com/basecamp/</a> for more detailed information.</p>
<p>Authentication wrapper (uses <a href="https://github.com/archiloque/rest-client">RestClient</a> and ActiveSupport)</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">module</span> Basecamp  
  @@config = <span style="color:#006600; font-weight:bold;">&#123;</span><span style="color:#006600; font-weight:bold;">&#125;</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">class</span> WrongCredentials <span style="color:#006600; font-weight:bold;">&lt;</span> <span style="color:#CC00FF; font-weight:bold;">Exception</span> ; <span style="color:#9966CC; font-weight:bold;">end</span>
  <span style="color:#9966CC; font-weight:bold;">class</span> WrongUserType <span style="color:#006600; font-weight:bold;">&lt;</span> <span style="color:#CC00FF; font-weight:bold;">Exception</span> ; <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#008000; font-style:italic;"># Configure Basecamp account</span>
  <span style="color:#008000; font-style:italic;"># account should be a subdomain of your url</span>
  <span style="color:#9966CC; font-weight:bold;">def</span> <span style="color:#0000FF; font-weight:bold;">self</span>.<span style="color:#9900CC;">configure</span><span style="color:#006600; font-weight:bold;">&#40;</span>account<span style="color:#006600; font-weight:bold;">&#41;</span>
    @@config<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:subdomain</span><span style="color:#006600; font-weight:bold;">&#93;</span> = account
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#008000; font-style:italic;"># Authenticate user</span>
  <span style="color:#008000; font-style:italic;"># Options:</span>
  <span style="color:#008000; font-style:italic;">#   :client =&gt; true|false - Check if client of the company</span>
  <span style="color:#9966CC; font-weight:bold;">def</span> <span style="color:#0000FF; font-weight:bold;">self</span>.<span style="color:#9900CC;">authenticate</span><span style="color:#006600; font-weight:bold;">&#40;</span>user, password, opts=<span style="color:#006600; font-weight:bold;">&#123;</span><span style="color:#006600; font-weight:bold;">&#125;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    url = <span style="color:#996600;">&quot;https://#{@@config[:subdomain]}.basecamphq.com/me.xml&quot;</span>
    res = <span style="color:#6666ff; font-weight:bold;">RestClient::Resource</span>.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span>url, <span style="color:#ff3333; font-weight:bold;">:user</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> user, <span style="color:#ff3333; font-weight:bold;">:password</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> password<span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#9966CC; font-weight:bold;">begin</span>
      person = <span style="color:#CC00FF; font-weight:bold;">Hash</span>.<span style="color:#9900CC;">from_xml</span><span style="color:#006600; font-weight:bold;">&#40;</span>res.<span style="color:#9900CC;">get</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'person'</span><span style="color:#006600; font-weight:bold;">&#93;</span>
      <span style="color:#9966CC; font-weight:bold;">if</span> opts.<span style="color:#9900CC;">key</span>?<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:client</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&amp;&amp;</span> opts<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:client</span><span style="color:#006600; font-weight:bold;">&#93;</span>
        <span style="color:#CC0066; font-weight:bold;">raise</span> WrongUserType, <span style="color:#996600;">'Invalid user type!'</span> <span style="color:#9966CC; font-weight:bold;">if</span> person<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'client_id'</span><span style="color:#006600; font-weight:bold;">&#93;</span> == <span style="color:#006666;">0</span>
      <span style="color:#9966CC; font-weight:bold;">end</span>
      person
    <span style="color:#9966CC; font-weight:bold;">rescue</span> <span style="color:#6666ff; font-weight:bold;">RestClient::Unauthorized</span>
      <span style="color:#CC0066; font-weight:bold;">raise</span> WrongCredentials, <span style="color:#996600;">'Invalid username or password'</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>So, the wrapper has only 2 methods &#8211; configuration and authentication.<br />
To configure wrapper you need to provide your account name, which is a part of your url, like ACCOUNT_NAME.basecamphq.com</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">Basecamp.<span style="color:#9900CC;">configure</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'ACCOUNT_NAME'</span><span style="color:#006600; font-weight:bold;">&#41;</span></pre></div></div>

<p>User authentication (<strong><em>P.S it does not support openID logins</em></strong>):</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">begin</span>
   me = Basecamp.<span style="color:#9900CC;">authenticate</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'username'</span>, <span style="color:#996600;">'password'</span><span style="color:#006600; font-weight:bold;">&#41;</span>
   me<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'user_name'</span><span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#008000; font-style:italic;"># =&gt; person username</span>
   me<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'email_address'</span><span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#008000; font-style:italic;"># =&gt; person email address</span>
   <span style="color:#008000; font-style:italic;"># more details are described in api documentation</span>
<span style="color:#9966CC; font-weight:bold;">rescue</span> <span style="color:#6666ff; font-weight:bold;">Basecamp::WrongCredentials</span>
  <span style="color:#008000; font-style:italic;"># if username or password is wrong</span>
<span style="color:#9966CC; font-weight:bold;">rescue</span> <span style="color:#6666ff; font-weight:bold;">Basecamp::WrongUserType</span>
  <span style="color:#008000; font-style:italic;"># will trigger if one of your clients is trying to login to this tool.</span>
  <span style="color:#008000; font-style:italic;"># all members of the account have parameter client_id = 0 </span>
  <span style="color:#008000; font-style:italic;"># so thats the protection from unauthorized access</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>To give a client ability to login into your basecamp-affiliated app just use additional key :client</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">user = Basecamp.<span style="color:#9900CC;">authenticate</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'user'</span>, <span style="color:#996600;">'password'</span>, <span style="color:#ff3333; font-weight:bold;">:client</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#0000FF; font-weight:bold;">true</span><span style="color:#006600; font-weight:bold;">&#41;</span></pre></div></div>

<h3>Integration with Authlogic</h3>
<p>I&#8217;ll just use the default authlogic model for this example:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">class</span> User <span style="color:#006600; font-weight:bold;">&lt;</span> <span style="color:#6666ff; font-weight:bold;">ActiveRecord::Base</span>
  acts_as_authentic
&nbsp;
  validates_presence_of <span style="color:#ff3333; font-weight:bold;">:login</span>, <span style="color:#ff3333; font-weight:bold;">:email</span>, <span style="color:#ff3333; font-weight:bold;">:first_name</span>
  validates_uniqueness_of <span style="color:#ff3333; font-weight:bold;">:login</span>, <span style="color:#ff3333; font-weight:bold;">:email</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> name
    <span style="color:#996600;">&quot;#{self.first_name} #{self.last_name}&quot;</span>.<span style="color:#9900CC;">strip</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#008000; font-style:italic;"># Import user from Basecamp</span>
  <span style="color:#9966CC; font-weight:bold;">def</span> <span style="color:#0000FF; font-weight:bold;">self</span>.<span style="color:#9900CC;">import</span><span style="color:#006600; font-weight:bold;">&#40;</span>h<span style="color:#006600; font-weight:bold;">&#41;</span>
    u = User.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span>
      <span style="color:#ff3333; font-weight:bold;">:login</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> h<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'user_name'</span><span style="color:#006600; font-weight:bold;">&#93;</span>,
      <span style="color:#ff3333; font-weight:bold;">:email</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> h<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'email_address'</span><span style="color:#006600; font-weight:bold;">&#93;</span>,
      <span style="color:#ff3333; font-weight:bold;">:password</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> h<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'password'</span><span style="color:#006600; font-weight:bold;">&#93;</span>,
      <span style="color:#ff3333; font-weight:bold;">:password_confirmation</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> h<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'password'</span><span style="color:#006600; font-weight:bold;">&#93;</span>,
      <span style="color:#ff3333; font-weight:bold;">:first_name</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> h<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'first_name'</span><span style="color:#006600; font-weight:bold;">&#93;</span>,
      <span style="color:#ff3333; font-weight:bold;">:last_name</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> h<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'last_name'</span><span style="color:#006600; font-weight:bold;">&#93;</span>
    <span style="color:#006600; font-weight:bold;">&#41;</span>
    u.<span style="color:#9900CC;">save</span>
    u
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>And controller code (UserSessions#create):</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">def</span> create
  fields = params<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:user_session</span><span style="color:#006600; font-weight:bold;">&#93;</span>
  <span style="color:#0066ff; font-weight:bold;">@user_session</span> = UserSession.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span>fields<span style="color:#006600; font-weight:bold;">&#41;</span>
&nbsp;
  user = User.<span style="color:#9900CC;">find_by_login</span><span style="color:#006600; font-weight:bold;">&#40;</span>fields<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:login</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#9966CC; font-weight:bold;">if</span> user.<span style="color:#0000FF; font-weight:bold;">nil</span>?
    <span style="color:#9966CC; font-weight:bold;">begin</span>
      me = Basecamp.<span style="color:#9900CC;">authenticate</span><span style="color:#006600; font-weight:bold;">&#40;</span>fields<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:login</span><span style="color:#006600; font-weight:bold;">&#93;</span>, fields<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:password</span><span style="color:#006600; font-weight:bold;">&#93;</span>, <span style="color:#ff3333; font-weight:bold;">:client</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#0000FF; font-weight:bold;">false</span><span style="color:#006600; font-weight:bold;">&#41;</span>
      user = User.<span style="color:#9900CC;">import</span><span style="color:#006600; font-weight:bold;">&#40;</span>me.<span style="color:#9900CC;">merge</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'password'</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> fields<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:password</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#9966CC; font-weight:bold;">rescue</span> <span style="color:#6666ff; font-weight:bold;">Basecamp::WrongCredentials</span>
      <span style="color:#0066ff; font-weight:bold;">@user_session</span>.<span style="color:#9900CC;">errors</span>.<span style="color:#9900CC;">add</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:base</span>, <span style="color:#996600;">&quot;Sorry, your username or password wasn't recognized.&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#9966CC; font-weight:bold;">rescue</span> <span style="color:#6666ff; font-weight:bold;">Basecamp::WrongUserType</span>
      <span style="color:#0066ff; font-weight:bold;">@user</span>.<span style="color:#9900CC;">session</span>.<span style="color:#9900CC;">errors</span>.<span style="color:#9900CC;">add</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:base</span>, <span style="color:#996600;">&quot;Sorry, you're not allowed here.&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">if</span> <span style="color:#0066ff; font-weight:bold;">@user_session</span>.<span style="color:#9900CC;">save</span>
    <span style="color:#0000FF; font-weight:bold;">return</span> redirect_to root_path
  <span style="color:#9966CC; font-weight:bold;">else</span>
    <span style="color:#0066ff; font-weight:bold;">@user_session</span>.<span style="color:#9900CC;">errors</span>.<span style="color:#9900CC;">add</span> <span style="color:#ff3333; font-weight:bold;">:base</span>, <span style="color:#996600;">&quot;Sorry, your username or password wasn't recognized.&quot;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  render <span style="color:#ff3333; font-weight:bold;">:action</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#ff3333; font-weight:bold;">:new</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>And then your application has the original behavior and basecamp authentication support. Just add more logic <img src='http://blog.sosedoff.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://blog.sosedoff.com/2011/01/22/basecamp-authentication-with-rails-and-authlogic/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Some fun with Pastie</title>
		<link>http://blog.sosedoff.com/2010/09/30/some-fun-with-pastie/</link>
		<comments>http://blog.sosedoff.com/2010/09/30/some-fun-with-pastie/#comments</comments>
		<pubDate>Thu, 30 Sep 2010 05:49:09 +0000</pubDate>
		<dc:creator>Dan Sosedoff</dc:creator>
				<category><![CDATA[API's]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Web Services]]></category>
		<category><![CDATA[gem]]></category>
		<category><![CDATA[html]]></category>
		<category><![CDATA[paste]]></category>

		<guid isPermaLink="false">http://blog.sosedoff.com/?p=285</guid>
		<description><![CDATA[I really like public paste service &#8211; pastie.org. Too bad it does not have public API.
The most common user case for me &#8211; drop some files. 1 or 2 usually. So i have to copy and paste file contents into the form, select private and then send link to someone. Too many actions i think. [...]]]></description>
			<content:encoded><![CDATA[<p>I really like public paste service &#8211; <a href="http://pastie.org">pastie.org</a>. Too bad it does not have public API.<br />
The most common user case for me &#8211; drop some files. 1 or 2 usually. So i have to copy and paste file contents into the form, select private and then send link to someone. Too many actions i think. </p>
<p>I decided to spend some time and create console tool and simplified api based on html extractions. </p>
<p>Source: <a href="http://github.com/sosedoff.com/pastie">http://github.com/sosedoff/pastie</a></p>
<p>Just install it:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ <span style="color: #c20cb9; font-weight: bold;">sudo</span> gem <span style="color: #c20cb9; font-weight: bold;">install</span> pastie-api</pre></div></div>

<p>And use it (multiple files are supported):</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ pastie <span style="color: #c20cb9; font-weight: bold;">file</span>
$ pastie file1 file2 ... fileN</pre></div></div>

<p>Also, API access:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'rubygems'</span>
<span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'pastie-api'</span>
&nbsp;
<span style="color:#008000; font-style:italic;"># Create a new private paste</span>
<span style="color:#CC0066; font-weight:bold;">p</span> = Pastie.<span style="color:#9900CC;">create</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'Test string'</span><span style="color:#006600; font-weight:bold;">&#41;</span>
&nbsp;
<span style="color:#008000; font-style:italic;"># Create a new public paste</span>
<span style="color:#CC0066; font-weight:bold;">p</span> = Pastie.<span style="color:#9900CC;">create</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'Hello!'</span>, <span style="color:#0000FF; font-weight:bold;">false</span><span style="color:#006600; font-weight:bold;">&#41;</span>
&nbsp;
<span style="color:#008000; font-style:italic;"># View paste details</span>
<span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#996600;">&quot;Paste ID: #{p.id}&quot;</span>
<span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#996600;">&quot;Paste Key: #{p.key}&quot;</span>
<span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#996600;">&quot;URL: #{p.link}&quot;</span>
<span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#996600;">&quot;Raw link: #{p.raw_link}&quot;</span>
&nbsp;
<span style="color:#008000; font-style:italic;"># Find existing paste</span>
<span style="color:#CC0066; font-weight:bold;">p</span> = Pastie.<span style="color:#9900CC;">get</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006666;">1234567</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#008000; font-style:italic;"># find by paste's ID</span>
<span style="color:#CC0066; font-weight:bold;">p</span> = Pastie.<span style="color:#9900CC;">get</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'abcdefabcdef'</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#008000; font-style:italic;"># find by paste's private code</span></pre></div></div>

<p>Planning to add local pastes history and auto-paste from clipboard.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.sosedoff.com/2010/09/30/some-fun-with-pastie/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Using Amazon product images on your website</title>
		<link>http://blog.sosedoff.com/2010/06/15/using-amazon-product-images-on-your-website/</link>
		<comments>http://blog.sosedoff.com/2010/06/15/using-amazon-product-images-on-your-website/#comments</comments>
		<pubDate>Tue, 15 Jun 2010 06:20:17 +0000</pubDate>
		<dc:creator>Dan Sosedoff</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Web Services]]></category>
		<category><![CDATA[amazon]]></category>
		<category><![CDATA[ecs]]></category>
		<category><![CDATA[images]]></category>
		<category><![CDATA[scaling]]></category>

		<guid isPermaLink="false">http://blog.sosedoff.com/?p=237</guid>
		<description><![CDATA[Amazon has an awesome image service. You can use their product images on your site, adjusting them for you needs. All you have to know &#8211; one image url of your product. Having that string will provide you an access to its dynamic image scaling service which i had to use recently. 
So, lets say [...]]]></description>
			<content:encoded><![CDATA[<p>Amazon has an awesome image service. You can use their product images on your site, adjusting them for you needs. All you have to know &#8211; one image url of your product. Having that string will provide you an access to its dynamic image scaling service which i had to use recently. </p>
<p>So, lets say you have books on your website, but you dont have any good images for them. There is 2 ways to solve your problem: 1) download it from whatever place and resize 2) use amazon!</p>
<p>Here goes small overview.</p>
<p>Unfortunately, i didnt have any time to play with image service for different countries, but i assume that wont change that much.  Lets take a look on a regular image:</p>
<p>http://ecx.images-amazon.com/images/I/41ygBmdaIfL._SL500_SS100_.jpg</p>
<p>It has different parts:<br />
1) URL base: http://ecx.images-amazon.com/images/I/<br />
2) Image code: 41ygBmdaIfL<br />
3) Size format (surrounded by underscores): _SL500_SS100_<br />
4) Format: jpg/gif/png</p>
<p>Some words about image format. It can vary from square thumbnails to images with specific max width and height. For example: _SX100_ will produce image that 100 pixels wide, height will be calculated proportionally. SH100 will give opposite result, scaled by 100 pixels maximum height, SS100 &#8211; 100&#215;100 pixels thumbnail. And so on, you can find other similar crop codes while exploring amazon store on different pages, all you need is to take a look on image sources. </p>
<p>Now, we need to use this with Ruby:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'net/http'</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">module</span> Amazon
  <span style="color:#008000; font-style:italic;"># parse amazon image url and get image code and extension</span>
  <span style="color:#9966CC; font-weight:bold;">def</span> <span style="color:#0000FF; font-weight:bold;">self</span>.<span style="color:#9900CC;">parse_image</span><span style="color:#006600; font-weight:bold;">&#40;</span>url<span style="color:#006600; font-weight:bold;">&#41;</span>
    result = url.<span style="color:#9900CC;">scan</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">/</span>^http:\<span style="color:#006600; font-weight:bold;">/</span>\<span style="color:#006600; font-weight:bold;">/</span>ecx.<span style="color:#9900CC;">images</span><span style="color:#006600; font-weight:bold;">-</span>amazon.<span style="color:#9900CC;">com</span>\<span style="color:#006600; font-weight:bold;">/</span>images\<span style="color:#006600; font-weight:bold;">/</span>I\<span style="color:#006600; font-weight:bold;">/</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#91;</span>a<span style="color:#006600; font-weight:bold;">-</span>z0<span style="color:#006600; font-weight:bold;">-</span><span style="color:#006666;">9</span>\<span style="color:#006600; font-weight:bold;">-</span>\<span style="color:#006600; font-weight:bold;">%</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#123;</span><span style="color:#006666;">1</span>,<span style="color:#006600; font-weight:bold;">&#125;</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#40;</span>.<span style="color:#006600; font-weight:bold;">*</span><span style="color:#006600; font-weight:bold;">&#41;</span>_.<span style="color:#006600; font-weight:bold;">&#40;</span>jpg<span style="color:#006600; font-weight:bold;">|</span>jpeg<span style="color:#006600; font-weight:bold;">|</span>gif<span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">/</span>i<span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#9966CC; font-weight:bold;">unless</span> result.<span style="color:#0000FF; font-weight:bold;">nil</span>?
      <span style="color:#9966CC; font-weight:bold;">unless</span> result<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">0</span><span style="color:#006600; font-weight:bold;">&#93;</span>.<span style="color:#0000FF; font-weight:bold;">nil</span>?
        match = result.<span style="color:#9900CC;">first</span>
        <span style="color:#0000FF; font-weight:bold;">return</span> <span style="color:#006600; font-weight:bold;">&#123;</span>:code <span style="color:#006600; font-weight:bold;">=&gt;</span> match.<span style="color:#9900CC;">first</span>.<span style="color:#9900CC;">to_s</span>, <span style="color:#ff3333; font-weight:bold;">:extension</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> match.<span style="color:#9900CC;">last</span>.<span style="color:#9900CC;">to_s</span><span style="color:#006600; font-weight:bold;">&#125;</span>
      <span style="color:#9966CC; font-weight:bold;">end</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#008000; font-style:italic;"># make a new amazon image url based on code and size</span>
  <span style="color:#9966CC; font-weight:bold;">def</span> <span style="color:#0000FF; font-weight:bold;">self</span>.<span style="color:#9900CC;">make_image</span><span style="color:#006600; font-weight:bold;">&#40;</span>image, size<span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#996600;">&quot;http://ecx.images-amazon.com/images/I/#{image[:code]}._#{size.upcase}.#{image[:extension]}&quot;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#008000; font-style:italic;"># check if actual image exists</span>
  <span style="color:#9966CC; font-weight:bold;">def</span> <span style="color:#0000FF; font-weight:bold;">self</span>.<span style="color:#9900CC;">check_image</span><span style="color:#006600; font-weight:bold;">&#40;</span>url<span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#9966CC; font-weight:bold;">begin</span>
      uri = <span style="color:#CC00FF; font-weight:bold;">URI</span>.<span style="color:#9900CC;">parse</span><span style="color:#006600; font-weight:bold;">&#40;</span>url<span style="color:#006600; font-weight:bold;">&#41;</span>
      req = <span style="color:#6666ff; font-weight:bold;">Net::HTTP::Get</span>.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span>uri.<span style="color:#9900CC;">path</span><span style="color:#006600; font-weight:bold;">&#41;</span>
      res = <span style="color:#6666ff; font-weight:bold;">Net::HTTP</span>.<span style="color:#9900CC;">start</span><span style="color:#006600; font-weight:bold;">&#40;</span>uri.<span style="color:#9900CC;">host</span>, uri.<span style="color:#9900CC;">port</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#006600; font-weight:bold;">|</span>http<span style="color:#006600; font-weight:bold;">|</span> http.<span style="color:#9900CC;">request</span><span style="color:#006600; font-weight:bold;">&#40;</span>req<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#125;</span>
      <span style="color:#0000FF; font-weight:bold;">return</span> res.<span style="color:#9900CC;">code</span> == <span style="color:#996600;">'200'</span> <span style="color:#006600; font-weight:bold;">&amp;&amp;</span> res.<span style="color:#9900CC;">content_length</span>.<span style="color:#9900CC;">to_i</span> <span style="color:#006600; font-weight:bold;">&gt;</span> <span style="color:#006666;">0</span>
    <span style="color:#9966CC; font-weight:bold;">rescue</span> <span style="color:#CC00FF; font-weight:bold;">Exception</span>
      <span style="color:#0000FF; font-weight:bold;">false</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>And usage:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">url = <span style="color:#996600;">'http://ecx.images-amazon.com/images/I/51O65dIoZCL._SX117_.jpg'</span>
info = Amazon.<span style="color:#9900CC;">parse_image</span><span style="color:#006600; font-weight:bold;">&#40;</span>url<span style="color:#006600; font-weight:bold;">&#41;</span>
<span style="color:#9966CC; font-weight:bold;">unless</span> info.<span style="color:#0000FF; font-weight:bold;">nil</span>?
  new_url = Amazon.<span style="color:#9900CC;">make_image</span><span style="color:#006600; font-weight:bold;">&#40;</span>info, <span style="color:#996600;">'sx100'</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#9966CC; font-weight:bold;">if</span> Amazon.<span style="color:#9900CC;">check_image</span><span style="color:#006600; font-weight:bold;">&#40;</span>new_url<span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#996600;">&quot;Cool! Resized image: #{new_url}&quot;</span>
  <span style="color:#9966CC; font-weight:bold;">else</span>
    <span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#996600;">&quot;Sorry, this image does not exist!&quot;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">else</span>
  <span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#996600;">&quot;Cant identify image!&quot;</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>Some notes about the process. The only reason why method &#8220;check_image&#8221; uses GET method instead of HEAD is because if image cannot be generated or not found in amazon`s cache the response is still valid sometimes. I`ve checked it on 50k images and sometimes HEAD request indicates that response is valid while it not supposed to. Otherwise i would use HEAD.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.sosedoff.com/2010/06/15/using-amazon-product-images-on-your-website/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Handy HTTP requests with Curb and Ruby</title>
		<link>http://blog.sosedoff.com/2010/06/13/handy-http-requests-with-curb-and-ruby/</link>
		<comments>http://blog.sosedoff.com/2010/06/13/handy-http-requests-with-curb-and-ruby/#comments</comments>
		<pubDate>Sun, 13 Jun 2010 05:43:49 +0000</pubDate>
		<dc:creator>Dan Sosedoff</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Web Services]]></category>
		<category><![CDATA[API's]]></category>
		<category><![CDATA[crawlers]]></category>
		<category><![CDATA[curb]]></category>
		<category><![CDATA[curl]]></category>
		<category><![CDATA[http]]></category>
		<category><![CDATA[networking]]></category>
		<category><![CDATA[requests]]></category>

		<guid isPermaLink="false">http://blog.sosedoff.com/?p=232</guid>
		<description><![CDATA[While working on one of the projects, i tried to find multi-purpose HTTP request class that can use different network interfaces/ip addresses with retry option (if connection slow or server not responding for some reason). 
Here is a small class wrapper build on top of Ruby Curb implemented as a module:

module ApiRequest
  USER_AGENTS = [...]]]></description>
			<content:encoded><![CDATA[<p>While working on one of the projects, i tried to find multi-purpose HTTP request class that can use different network interfaces/ip addresses with retry option (if connection slow or server not responding for some reason). </p>
<p>Here is a small class wrapper build on top of Ruby <a href="http://curb.rubyforge.org/">Curb</a> implemented as a module:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">module</span> ApiRequest
  USER_AGENTS = <span style="color:#006600; font-weight:bold;">&#91;</span>
    <span style="color:#996600;">'Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.6; en-US; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3'</span>,
    <span style="color:#996600;">'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; .NET CLR 2.0.50727)'</span>,
    <span style="color:#996600;">'Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.3) Gecko/20100423 Ubuntu/10.04 (lucid) Firefox/3.6.3'</span>,
    <span style="color:#996600;">'Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_3; en-US) AppleWebKit/533.4 (KHTML, like Gecko) Chrome/5.0.375.70 Safari/533.4'</span>,
    <span style="color:#996600;">'Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.2) Gecko/20100323 Namoroka/3.6.2'</span>,
    <span style="color:#996600;">'Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.9) Gecko/20100401 Ubuntu/9.10 (karmic) Firefox/3.5.9'</span>
  <span style="color:#006600; font-weight:bold;">&#93;</span>
&nbsp;
  CONNECTION_TIMEOUT = <span style="color:#006666;">10</span>
&nbsp;
  @@interfaces = <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006600; font-weight:bold;">&#93;</span>
&nbsp;
  <span style="color:#008000; font-style:italic;"># get random user-agent string for usage</span>
  <span style="color:#9966CC; font-weight:bold;">def</span> random_agent
    USER_AGENTS<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#CC0066; font-weight:bold;">rand</span><span style="color:#006600; font-weight:bold;">&#40;</span>USER_AGENTS.<span style="color:#9900CC;">size</span><span style="color:#006600; font-weight:bold;">-</span><span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#93;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#008000; font-style:italic;"># get random IP/network interface specified in @@interfaces</span>
  <span style="color:#9966CC; font-weight:bold;">def</span> random_interface
    size = @@interfaces.<span style="color:#9900CC;">size</span>
    size <span style="color:#006600; font-weight:bold;">&gt;</span> <span style="color:#006666;">0</span> ? @@interfaces<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#CC0066; font-weight:bold;">rand</span><span style="color:#006600; font-weight:bold;">&#40;</span>size<span style="color:#006600; font-weight:bold;">-</span><span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#93;</span> : <span style="color:#0000FF; font-weight:bold;">nil</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#008000; font-style:italic;"># perform request, assign_to - specify network interface/ip</span>
  <span style="color:#9966CC; font-weight:bold;">def</span> perform<span style="color:#006600; font-weight:bold;">&#40;</span>url, assign_to=<span style="color:#0000FF; font-weight:bold;">nil</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#CC0066; font-weight:bold;">puts</span> url
    interface = assign_to.<span style="color:#0000FF; font-weight:bold;">nil</span>? ? <span style="color:#0000FF; font-weight:bold;">self</span>.<span style="color:#9900CC;">random_interface</span> : assign_to
    req = <span style="color:#6666ff; font-weight:bold;">Curl::Easy</span>.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span>url<span style="color:#006600; font-weight:bold;">&#41;</span>
    req.<span style="color:#9900CC;">timeout</span> = CONNECTION_TIMEOUT
    req.<span style="color:#9900CC;">interface</span> = interface <span style="color:#9966CC; font-weight:bold;">unless</span> interface.<span style="color:#0000FF; font-weight:bold;">nil</span>?
    req.<span style="color:#9900CC;">headers</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'User-Agent'</span><span style="color:#006600; font-weight:bold;">&#93;</span> = <span style="color:#0000FF; font-weight:bold;">self</span>.<span style="color:#9900CC;">random_agent</span>
    <span style="color:#9966CC; font-weight:bold;">begin</span>
      req.<span style="color:#9900CC;">perform</span>
      <span style="color:#9966CC; font-weight:bold;">if</span> req.<span style="color:#9900CC;">response_code</span> == <span style="color:#006666;">200</span>
        <span style="color:#0000FF; font-weight:bold;">return</span> req.<span style="color:#9900CC;">downloaded_bytes</span> <span style="color:#006600; font-weight:bold;">&gt;</span> <span style="color:#006666;">0</span> ? req.<span style="color:#9900CC;">body_str</span> : <span style="color:#0000FF; font-weight:bold;">nil</span>
      <span style="color:#9966CC; font-weight:bold;">else</span>
        <span style="color:#0000FF; font-weight:bold;">nil</span>
      <span style="color:#9966CC; font-weight:bold;">end</span>
    <span style="color:#9966CC; font-weight:bold;">rescue</span> <span style="color:#CC00FF; font-weight:bold;">Exception</span>
      <span style="color:#0000FF; font-weight:bold;">return</span> <span style="color:#0000FF; font-weight:bold;">nil</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#008000; font-style:italic;"># perform request by number of attempts</span>
  <span style="color:#9966CC; font-weight:bold;">def</span> fetch<span style="color:#006600; font-weight:bold;">&#40;</span>url, attempts=<span style="color:#006666;">3</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    result = <span style="color:#0000FF; font-weight:bold;">nil</span>
    1.<span style="color:#9900CC;">upto</span><span style="color:#006600; font-weight:bold;">&#40;</span>attempts<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>a<span style="color:#006600; font-weight:bold;">|</span>
      result = <span style="color:#0000FF; font-weight:bold;">self</span>.<span style="color:#9900CC;">perform</span><span style="color:#006600; font-weight:bold;">&#40;</span>url<span style="color:#006600; font-weight:bold;">&#41;</span>
      <span style="color:#9966CC; font-weight:bold;">break</span> <span style="color:#9966CC; font-weight:bold;">unless</span> result.<span style="color:#0000FF; font-weight:bold;">nil</span>?
    <span style="color:#9966CC; font-weight:bold;">end</span>
    <span style="color:#0000FF; font-weight:bold;">return</span> result
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>And sample usage:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">class</span> TestRequest
  <span style="color:#9966CC; font-weight:bold;">include</span> ApiRequest
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> foo
     body = <span style="color:#0000FF; font-weight:bold;">self</span>.<span style="color:#9900CC;">fetch</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'http://google.com'</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>If module variable &#8220;<em>@@interfaces</em>&#8221; is array of ip addresses or network interfaces then one of them (randomly selected) will be used to perform request. Also, function &#8220;<em>fetch</em>&#8221; has parameter &#8220;<em>attempts</em>&#8221; which set to 3 by default. It means that operation will be invoked n times until result is downloaded from url. Otherwise &#8211; it returns nil.<br />
Function perform has a parameter &#8220;<em>assign_to</em>&#8221; (which it not used in &#8220;<em>fetch</em>&#8221; function) that allows to bind request to specified interface.  It is useful if you have situation when you might use different workers that bound to exact interface or just one that uses random ip`s. Also, class <em>ApiRequest</em> has a list of user agents which it uses randomly for each performed request.</p>
<p>Pastie: <a href="http://pastie.org/private/j19j3hbebte9bjqaydslmg">http://pastie.org/private/j19j3hbebte9bjqaydslmg</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.sosedoff.com/2010/06/13/handy-http-requests-with-curb-and-ruby/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Making HTTP requests from different network interfaces with Ruby and Curb</title>
		<link>http://blog.sosedoff.com/2010/06/09/making-http-requests-from-different-network-interfaces-with-ruby-and-curb/</link>
		<comments>http://blog.sosedoff.com/2010/06/09/making-http-requests-from-different-network-interfaces-with-ruby-and-curb/#comments</comments>
		<pubDate>Thu, 10 Jun 2010 04:31:17 +0000</pubDate>
		<dc:creator>Dan Sosedoff</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[Web Services]]></category>
		<category><![CDATA[curb]]></category>
		<category><![CDATA[curl]]></category>
		<category><![CDATA[get]]></category>
		<category><![CDATA[http]]></category>
		<category><![CDATA[net]]></category>
		<category><![CDATA[requests]]></category>

		<guid isPermaLink="false">http://blog.sosedoff.com/?p=228</guid>
		<description><![CDATA[At some point you will find that you have reached requests per IP limit while using some API or crawling resources. And if you`re doing it via standard Net::HTTP you`ll face the problem that you cannot assign request class to specified network interface (or IP). Bummer? No. Even if you cant do it with core [...]]]></description>
			<content:encoded><![CDATA[<p>At some point you will find that you have reached requests per IP limit while using some API or crawling resources. And if you`re doing it via standard <a href="http://ruby-doc.org/core/classes/Net/HTTP.html">Net::HTTP</a> you`ll face the problem that you cannot assign request class to specified network interface (or IP). Bummer? No. Even if you cant do it with core class you might take a look on <a href="http://curb.rubyforge.org/">Curb</a> &#8211; libcurl ruby binding. It has everything that you need to make regular get/post/etc requests. And of course &#8211; easy.</p>
<p>A simple example (real ip`s are changed):</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'rubygems'</span>
<span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'curb'</span>
&nbsp;
ip_addresses = <span style="color:#006600; font-weight:bold;">&#91;</span>
  <span style="color:#996600;">'1.1.1.1'</span>,
  <span style="color:#996600;">'2.2.2.2'</span>,
  <span style="color:#996600;">'3.3.3.3'</span>,
  <span style="color:#996600;">'4.4.4.4'</span>,
  <span style="color:#996600;">'5.5.5.5'</span>
<span style="color:#006600; font-weight:bold;">&#93;</span>
&nbsp;
ip_addresses.<span style="color:#9900CC;">each</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>ip<span style="color:#006600; font-weight:bold;">|</span>
  req = <span style="color:#6666ff; font-weight:bold;">Curl::Easy</span>.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'http://www.ip-adress.com/'</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  req.<span style="color:#9900CC;">interface</span> = ip
  req.<span style="color:#9900CC;">perform</span>
  result_ip = req.<span style="color:#9900CC;">body_str</span>.<span style="color:#9900CC;">scan</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">/&lt;</span>h2<span style="color:#006600; font-weight:bold;">&gt;</span>My IP address is: <span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#91;</span>\d\.<span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#123;</span><span style="color:#006666;">1</span>,<span style="color:#006600; font-weight:bold;">&#125;</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&lt;</span>\<span style="color:#006600; font-weight:bold;">/</span>h2<span style="color:#006600; font-weight:bold;">&gt;/</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">first</span>
  <span style="color:#CC0066; font-weight:bold;">puts</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;for #{ip} got response: #{result_ip}&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>Output (ip`s are changed):</p>
<pre>
for 1.1.1.1 got response: 1.1.1.1
for 2.2.2.2 got response: 2.2.2.2
for 3.3.3.3 got response: 3.3.3.3
for 4.4.4.4 got response: 4.4.4.4
for 5.5.5.5 got response: 5.5.5.5
</pre>
<p>At least its working. Havent done any performance tests.<br />
Sample on pastie: <a href="http://pastie.org/private/afxlcuk1npwjov3wer5hw">http://pastie.org/private/afxlcuk1npwjov3wer5hw</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.sosedoff.com/2010/06/09/making-http-requests-from-different-network-interfaces-with-ruby-and-curb/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>WebDAV client in ruby</title>
		<link>http://blog.sosedoff.com/2009/05/02/webdav-client-in-ruby/</link>
		<comments>http://blog.sosedoff.com/2009/05/02/webdav-client-in-ruby/#comments</comments>
		<pubDate>Sat, 02 May 2009 05:03:30 +0000</pubDate>
		<dc:creator>Dan Sosedoff</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Web Services]]></category>
		<category><![CDATA[client]]></category>
		<category><![CDATA[Nginx]]></category>
		<category><![CDATA[sockets]]></category>
		<category><![CDATA[webdav]]></category>

		<guid isPermaLink="false">http://blog.sosedoff.com/?p=125</guid>
		<description><![CDATA[Here is a simple example how to make native WebDAV client with Ruby sockets. No additional gems or extensions needed &#8211; just all basic classes.

class WebDAV
	attr_reader :host, :port, :protocol, :chunk_size
	@socket = nil
&#160;
	def initialize&#40;host,port=80,protocol='HTTP/1.1',chunk=8096&#41;
		@host = host.to_s
		@port = port.to_i
		@protocol = protocol
		@chunk_size = chunk.to_i
	end
&#160;
	def build_header&#40;method, path, content_length=nil&#41;
		header = &#34;#{method} #{path} #{@protocol} \r\n&#34;
		header += &#34;Content-Length: #{content_length}\r\n&#34; if !content_length.nil?
		header += [...]]]></description>
			<content:encoded><![CDATA[<p>Here is a simple example how to make native WebDAV client with Ruby sockets. No additional gems or extensions needed &#8211; just all basic classes.</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">class</span> WebDAV
	attr_reader <span style="color:#ff3333; font-weight:bold;">:host</span>, <span style="color:#ff3333; font-weight:bold;">:port</span>, <span style="color:#ff3333; font-weight:bold;">:protocol</span>, <span style="color:#ff3333; font-weight:bold;">:chunk_size</span>
	<span style="color:#0066ff; font-weight:bold;">@socket</span> = <span style="color:#0000FF; font-weight:bold;">nil</span>
&nbsp;
	<span style="color:#9966CC; font-weight:bold;">def</span> initialize<span style="color:#006600; font-weight:bold;">&#40;</span>host,port=<span style="color:#006666;">80</span>,protocol=<span style="color:#996600;">'HTTP/1.1'</span>,chunk=<span style="color:#006666;">8096</span><span style="color:#006600; font-weight:bold;">&#41;</span>
		<span style="color:#0066ff; font-weight:bold;">@host</span> = host.<span style="color:#9900CC;">to_s</span>
		<span style="color:#0066ff; font-weight:bold;">@port</span> = port.<span style="color:#9900CC;">to_i</span>
		<span style="color:#0066ff; font-weight:bold;">@protocol</span> = protocol
		<span style="color:#0066ff; font-weight:bold;">@chunk_size</span> = chunk.<span style="color:#9900CC;">to_i</span>
	<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
	<span style="color:#9966CC; font-weight:bold;">def</span> build_header<span style="color:#006600; font-weight:bold;">&#40;</span>method, path, content_length=<span style="color:#0000FF; font-weight:bold;">nil</span><span style="color:#006600; font-weight:bold;">&#41;</span>
		header = <span style="color:#996600;">&quot;#{method} #{path} #{@protocol} <span style="color:#000099;">\r</span><span style="color:#000099;">\n</span>&quot;</span>
		header <span style="color:#006600; font-weight:bold;">+</span>= <span style="color:#996600;">&quot;Content-Length: #{content_length}<span style="color:#000099;">\r</span><span style="color:#000099;">\n</span>&quot;</span> <span style="color:#9966CC; font-weight:bold;">if</span> !content_length.<span style="color:#0000FF; font-weight:bold;">nil</span>?
		header <span style="color:#006600; font-weight:bold;">+</span>= <span style="color:#996600;">&quot;Host: #{@host}<span style="color:#000099;">\r</span><span style="color:#000099;">\n</span>&quot;</span>
		header <span style="color:#006600; font-weight:bold;">+</span>= <span style="color:#996600;">&quot;Connection: close<span style="color:#000099;">\r</span><span style="color:#000099;">\n</span><span style="color:#000099;">\r</span><span style="color:#000099;">\n</span>&quot;</span>
		<span style="color:#0000FF; font-weight:bold;">return</span> header
	<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
	<span style="color:#9966CC; font-weight:bold;">def</span> request<span style="color:#006600; font-weight:bold;">&#40;</span>method, path<span style="color:#006600; font-weight:bold;">&#41;</span>
		<span style="color:#CC0066; font-weight:bold;">open</span>
		header = build_header<span style="color:#006600; font-weight:bold;">&#40;</span>method, path<span style="color:#006600; font-weight:bold;">&#41;</span>
		<span style="color:#9966CC; font-weight:bold;">if</span> <span style="color:#0066ff; font-weight:bold;">@socket</span>.<span style="color:#9900CC;">write</span><span style="color:#006600; font-weight:bold;">&#40;</span>header<span style="color:#006600; font-weight:bold;">&#41;</span> == header.<span style="color:#9900CC;">length</span> <span style="color:#9966CC; font-weight:bold;">then</span>
			<span style="color:#0000FF; font-weight:bold;">return</span> <span style="color:#0066ff; font-weight:bold;">@socket</span>.<span style="color:#CC0066; font-weight:bold;">gets</span>.<span style="color:#CC0066; font-weight:bold;">split</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#93;</span>
		<span style="color:#9966CC; font-weight:bold;">end</span>
	<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
	<span style="color:#9966CC; font-weight:bold;">def</span> delete<span style="color:#006600; font-weight:bold;">&#40;</span>path<span style="color:#006600; font-weight:bold;">&#41;</span>
		request<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'DELETE'</span>, path<span style="color:#006600; font-weight:bold;">&#41;</span>
	<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
	<span style="color:#9966CC; font-weight:bold;">def</span> head<span style="color:#006600; font-weight:bold;">&#40;</span>path<span style="color:#006600; font-weight:bold;">&#41;</span>
		request<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'HEAD'</span>, path<span style="color:#006600; font-weight:bold;">&#41;</span>
	<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
	<span style="color:#9966CC; font-weight:bold;">def</span> mkcol<span style="color:#006600; font-weight:bold;">&#40;</span>path<span style="color:#006600; font-weight:bold;">&#41;</span>
		request<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'MKCOL'</span>, path<span style="color:#006600; font-weight:bold;">&#41;</span>
	<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
	<span style="color:#9966CC; font-weight:bold;">def</span> put<span style="color:#006600; font-weight:bold;">&#40;</span>path, localfile, auto_head=<span style="color:#0000FF; font-weight:bold;">true</span><span style="color:#006600; font-weight:bold;">&#41;</span>
		<span style="color:#9966CC; font-weight:bold;">if</span> !<span style="color:#CC00FF; font-weight:bold;">File</span>.<span style="color:#9900CC;">exists</span>?<span style="color:#006600; font-weight:bold;">&#40;</span>localfile<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">||</span> !<span style="color:#CC00FF; font-weight:bold;">File</span>.<span style="color:#9900CC;">readable</span>?<span style="color:#006600; font-weight:bold;">&#40;</span>localfile<span style="color:#006600; font-weight:bold;">&#41;</span>
			<span style="color:#CC0066; font-weight:bold;">raise</span> <span style="color:#996600;">&quot;File not exists or not accessible for reading!&quot;</span>
		<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
		<span style="color:#CC0066; font-weight:bold;">open</span>
&nbsp;
		datalen = <span style="color:#CC00FF; font-weight:bold;">File</span>.<span style="color:#9900CC;">size</span><span style="color:#006600; font-weight:bold;">&#40;</span>localfile<span style="color:#006600; font-weight:bold;">&#41;</span>
		header = build_header<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'PUT'</span>, path, datalen<span style="color:#006600; font-weight:bold;">&#41;</span>
&nbsp;
		<span style="color:#9966CC; font-weight:bold;">begin</span>
			<span style="color:#9966CC; font-weight:bold;">if</span> <span style="color:#0066ff; font-weight:bold;">@socket</span>.<span style="color:#9900CC;">write</span><span style="color:#006600; font-weight:bold;">&#40;</span>header<span style="color:#006600; font-weight:bold;">&#41;</span> == header.<span style="color:#9900CC;">length</span> <span style="color:#9966CC; font-weight:bold;">then</span>
				written = <span style="color:#006666;">0</span>
				<span style="color:#CC00FF; font-weight:bold;">File</span>.<span style="color:#CC0066; font-weight:bold;">open</span><span style="color:#006600; font-weight:bold;">&#40;</span>localfile,<span style="color:#996600;">'r'</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>f<span style="color:#006600; font-weight:bold;">|</span> 
					<span style="color:#9966CC; font-weight:bold;">until</span> f.<span style="color:#9900CC;">eof</span>? <span style="color:#9966CC; font-weight:bold;">do</span>
						written <span style="color:#006600; font-weight:bold;">+</span>= <span style="color:#0066ff; font-weight:bold;">@socket</span>.<span style="color:#9900CC;">write</span><span style="color:#006600; font-weight:bold;">&#40;</span>f.<span style="color:#9900CC;">read</span><span style="color:#006600; font-weight:bold;">&#40;</span>@chunk_size<span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
					<span style="color:#9966CC; font-weight:bold;">end</span>
				<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
				<span style="color:#9966CC; font-weight:bold;">if</span> written == datalen
					close
					<span style="color:#9966CC; font-weight:bold;">if</span> !auto_head
						<span style="color:#0000FF; font-weight:bold;">return</span> <span style="color:#0000FF; font-weight:bold;">true</span>
					<span style="color:#9966CC; font-weight:bold;">else</span>
						<span style="color:#0000FF; font-weight:bold;">return</span> head<span style="color:#006600; font-weight:bold;">&#40;</span>path<span style="color:#006600; font-weight:bold;">&#41;</span>
					<span style="color:#9966CC; font-weight:bold;">end</span>
				<span style="color:#9966CC; font-weight:bold;">end</span>
			<span style="color:#9966CC; font-weight:bold;">end</span>
		<span style="color:#9966CC; font-weight:bold;">rescue</span> <span style="color:#CC00FF; font-weight:bold;">Exception</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> e
			<span style="color:#CC0066; font-weight:bold;">puts</span> e
			<span style="color:#0000FF; font-weight:bold;">return</span> <span style="color:#0000FF; font-weight:bold;">false</span>
		<span style="color:#9966CC; font-weight:bold;">end</span>
	<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
	<span style="color:#9966CC; font-weight:bold;">def</span> <span style="color:#CC0066; font-weight:bold;">open</span>
		<span style="color:#9966CC; font-weight:bold;">begin</span> 
			<span style="color:#0066ff; font-weight:bold;">@socket</span> = TCPSocket.<span style="color:#CC0066; font-weight:bold;">open</span><span style="color:#006600; font-weight:bold;">&#40;</span>@host,@port<span style="color:#006600; font-weight:bold;">&#41;</span>
			<span style="color:#0000FF; font-weight:bold;">return</span> <span style="color:#0000FF; font-weight:bold;">true</span>
		<span style="color:#9966CC; font-weight:bold;">rescue</span> <span style="color:#CC00FF; font-weight:bold;">Exception</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> e
			<span style="color:#CC0066; font-weight:bold;">puts</span> e
			<span style="color:#0000FF; font-weight:bold;">return</span> <span style="color:#0000FF; font-weight:bold;">false</span>
		<span style="color:#9966CC; font-weight:bold;">end</span>
	<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
	<span style="color:#9966CC; font-weight:bold;">def</span> close
		<span style="color:#9966CC; font-weight:bold;">begin</span>
			<span style="color:#0000FF; font-weight:bold;">return</span> <span style="color:#0066ff; font-weight:bold;">@socket</span>.<span style="color:#9900CC;">close</span>
		<span style="color:#9966CC; font-weight:bold;">rescue</span> 
			<span style="color:#0000FF; font-weight:bold;">return</span> <span style="color:#0000FF; font-weight:bold;">false</span>
		<span style="color:#9966CC; font-weight:bold;">end</span>
	<span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>This class supports only basic http/dav methods (PUT, DELETE, MKCOL, HEAD) and can be extended very easily and designed to work with all files, reading them by small chunks (default is 8096 bytes).<br />
Im using this class sometimes with nginx.  </p>
<p>Deps:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'socket'</span>
<span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'digest'</span></pre></div></div>

<p>Usage:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#008000; font-style:italic;"># create connection</span>
conn = WebDAV.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'your.host.com'</span><span style="color:#006600; font-weight:bold;">&#41;</span>
&nbsp;
<span style="color:#008000; font-style:italic;"># upload file (without autocheck), return true/false value</span>
result = conn.<span style="color:#9900CC;">put</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'/test.mp3'</span>,<span style="color:#996600;">'/home/.../..../..../file.mp3'</span>, <span style="color:#0000FF; font-weight:bold;">false</span><span style="color:#006600; font-weight:bold;">&#41;</span>
&nbsp;
<span style="color:#008000; font-style:italic;"># upload file with autocheck, returns http response code (201, 404, ... ) so you`ll know what exactly happened</span>
result = conn.<span style="color:#9900CC;">put</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'/test2.mp3'</span>,<span style="color:#996600;">'/home/.../file.mp3'</span><span style="color:#006600; font-weight:bold;">&#41;</span></pre></div></div>

<p>Also, here is a wrapper class to produce MD5, SHA1 file hashes that supports big files.</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">class</span> FileHash 
	<span style="color:#9966CC; font-weight:bold;">def</span> <span style="color:#0000FF; font-weight:bold;">self</span>.<span style="color:#9900CC;">md5</span><span style="color:#006600; font-weight:bold;">&#40;</span>path<span style="color:#006600; font-weight:bold;">&#41;</span>
		d = <span style="color:#6666ff; font-weight:bold;">Digest::MD5</span>.<span style="color:#9900CC;">new</span>
		<span style="color:#CC00FF; font-weight:bold;">File</span>.<span style="color:#CC0066; font-weight:bold;">open</span><span style="color:#006600; font-weight:bold;">&#40;</span>path,<span style="color:#996600;">'r'</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>f<span style="color:#006600; font-weight:bold;">|</span> 
			d.<span style="color:#9900CC;">update</span><span style="color:#006600; font-weight:bold;">&#40;</span>f.<span style="color:#9900CC;">read</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006666;">8192</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">until</span> f.<span style="color:#9900CC;">eof</span>?
		<span style="color:#9966CC; font-weight:bold;">end</span>
		<span style="color:#0000FF; font-weight:bold;">return</span> d.<span style="color:#9900CC;">hexdigest</span>
	<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
	<span style="color:#9966CC; font-weight:bold;">def</span> <span style="color:#0000FF; font-weight:bold;">self</span>.<span style="color:#9900CC;">sha1</span><span style="color:#006600; font-weight:bold;">&#40;</span>path<span style="color:#006600; font-weight:bold;">&#41;</span>
		d = <span style="color:#6666ff; font-weight:bold;">Digest::SHA1</span>.<span style="color:#9900CC;">new</span>
		<span style="color:#CC00FF; font-weight:bold;">File</span>.<span style="color:#CC0066; font-weight:bold;">open</span><span style="color:#006600; font-weight:bold;">&#40;</span>path,<span style="color:#996600;">'r'</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>f<span style="color:#006600; font-weight:bold;">|</span> 
			d.<span style="color:#9900CC;">update</span><span style="color:#006600; font-weight:bold;">&#40;</span>f.<span style="color:#9900CC;">read</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006666;">8192</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">until</span> f.<span style="color:#9900CC;">eof</span>?
		<span style="color:#9966CC; font-weight:bold;">end</span>
		<span style="color:#0000FF; font-weight:bold;">return</span> d.<span style="color:#9900CC;">hexdigest</span>
	<span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>Usage:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">FileHash.<span style="color:#9900CC;">md5</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'/path/to/file'</span><span style="color:#006600; font-weight:bold;">&#41;</span>
FileHash.<span style="color:#9900CC;">sha1</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'/path/to/file'</span><span style="color:#006600; font-weight:bold;">&#41;</span></pre></div></div>

<p>This webdav class not pretending to be stable in production environment, but can be useful for some &#8220;one-time&#8221; tasks with less code. </p>
]]></content:encoded>
			<wfw:commentRss>http://blog.sosedoff.com/2009/05/02/webdav-client-in-ruby/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Simple file uploader to Amazon S3 Service</title>
		<link>http://blog.sosedoff.com/2009/03/22/simple-file-uploader-to-amazon-s3-service/</link>
		<comments>http://blog.sosedoff.com/2009/03/22/simple-file-uploader-to-amazon-s3-service/#comments</comments>
		<pubDate>Sun, 22 Mar 2009 04:59:18 +0000</pubDate>
		<dc:creator>Dan Sosedoff</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Web Services]]></category>
		<category><![CDATA[amazon]]></category>
		<category><![CDATA[s3]]></category>
		<category><![CDATA[simple]]></category>
		<category><![CDATA[uploader]]></category>

		<guid isPermaLink="false">http://blog.sosedoff.com/?p=115</guid>
		<description><![CDATA[For a long time i was thinking that Amazon`s Simple Storage Service (S3) is very complicated thing. But, it was before i tried it. Couple days ago, i got account to S3 and started exploring API`s and architecture. Now i see how stupid i was   It`s really easy to handle all operations with [...]]]></description>
			<content:encoded><![CDATA[<p>For a long time i was thinking that <a href="http://aws.amazon.com/s3/">Amazon`s Simple Storage Service (S3)</a> is very complicated thing. But, it was before i tried it. Couple days ago, i got account to S3 and started exploring API`s and architecture. Now i see how stupid i was <img src='http://blog.sosedoff.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  It`s really easy to handle all operations with files and buckets. Pricing also comfortable.</p>
<p>Welcome to cloud computing! <img src='http://blog.sosedoff.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  I started using it with Ruby. Regular gem and docs can be found at <a href="http://amazon.rubyforge.org/">http://amazon.rubyforge.org/</a></p>
<p>So, the first useful tool i decided to created &#8211; simple uploader of local files to amazons server.<br />
First, we need to create bucket and make it public:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">Bucket.<span style="color:#9900CC;">create</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'NAME_HERE'</span>,:access <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#ff3333; font-weight:bold;">:public_read</span><span style="color:#006600; font-weight:bold;">&#41;</span></pre></div></div>

<p>Here`s the client ruby script:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#008000; font-style:italic;">#!/usr/bin/ruby</span>
&nbsp;
<span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'rubygems'</span>
<span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'aws/s3'</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">include</span> <span style="color:#6666ff; font-weight:bold;">AWS::S3</span>
&nbsp;
<span style="color:#ff6633; font-weight:bold;">$s3_bucket</span> = <span style="color:#996600;">&quot;BUCKET_NAME&quot;</span>
<span style="color:#ff6633; font-weight:bold;">$s3_key</span> = <span style="color:#996600;">&quot;API_KEY&quot;</span>
<span style="color:#ff6633; font-weight:bold;">$s3_secret</span> = <span style="color:#996600;">&quot;API_SECRET&quot;</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">def</span> s3_store<span style="color:#006600; font-weight:bold;">&#40;</span>localfile<span style="color:#006600; font-weight:bold;">&#41;</span>
	<span style="color:#9966CC; font-weight:bold;">if</span> <span style="color:#CC00FF; font-weight:bold;">File</span>.<span style="color:#9900CC;">exists</span>?<span style="color:#006600; font-weight:bold;">&#40;</span>localfile<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&amp;</span>amp;<span style="color:#006600; font-weight:bold;">&amp;</span>amp; <span style="color:#CC00FF; font-weight:bold;">File</span>.<span style="color:#9900CC;">readable</span>?<span style="color:#006600; font-weight:bold;">&#40;</span>localfile<span style="color:#006600; font-weight:bold;">&#41;</span>
		<span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#996600;">&quot;Uploading file [#{localfile}]. Size: #{File.size(localfile)} bytes.&quot;</span>
		name = <span style="color:#CC00FF; font-weight:bold;">File</span>.<span style="color:#9900CC;">basename</span><span style="color:#006600; font-weight:bold;">&#40;</span>localfile<span style="color:#006600; font-weight:bold;">&#41;</span>
		Base.<span style="color:#9900CC;">establish_connection</span>!<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:access_key_id</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#ff6633; font-weight:bold;">$s3_key</span>, <span style="color:#ff3333; font-weight:bold;">:secret_access_key</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#ff6633; font-weight:bold;">$s3_secret</span><span style="color:#006600; font-weight:bold;">&#41;</span>
		S3Object.<span style="color:#9900CC;">store</span><span style="color:#006600; font-weight:bold;">&#40;</span>name, <span style="color:#CC0066; font-weight:bold;">open</span><span style="color:#006600; font-weight:bold;">&#40;</span>localfile<span style="color:#006600; font-weight:bold;">&#41;</span>, <span style="color:#ff6633; font-weight:bold;">$s3_bucket</span>, <span style="color:#ff3333; font-weight:bold;">:access</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#ff3333; font-weight:bold;">:public_read</span><span style="color:#006600; font-weight:bold;">&#41;</span>
		<span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#996600;">&quot;Download link: http://s3.amazonaws.com/#{$s3_bucket}/#{name}&quot;</span>
	<span style="color:#9966CC; font-weight:bold;">else</span>
		<span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#996600;">&quot;File not exists or not accessible. Please check file and try again!&quot;</span>
	<span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
path = ARGV<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">0</span><span style="color:#006600; font-weight:bold;">&#93;</span>
<span style="color:#9966CC; font-weight:bold;">if</span> !path
	<span style="color:#996600;">&quot;Please specify the file to upload.&quot;</span>
<span style="color:#9966CC; font-weight:bold;">else</span>
	s3_store<span style="color:#006600; font-weight:bold;">&#40;</span>path<span style="color:#006600; font-weight:bold;">&#41;</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p><strong>Download script: </strong> <a href="http://files.sosedoff.com/036cfedd/">http://files.sosedoff.com/036cfedd/</a></p>
<p>BTW, I found cool firefox add-on to manage S3 objects/files. It`s pretty easy.<br />
Link to extension &#8211; <a href="http://www.s3fox.net">http://www.s3fox.net</a><br />
Screenshot:<br />
<img class="alignnone" title="S3 Firefox Extension" src="http://www.omniuploader.com/s3fox/features/s3fox_main.gif" alt="" width="500" height="309" /></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.sosedoff.com/2009/03/22/simple-file-uploader-to-amazon-s3-service/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Fetching album covers from Last.Fm API</title>
		<link>http://blog.sosedoff.com/2009/02/15/fetching-album-covers-from-lastfm-api/</link>
		<comments>http://blog.sosedoff.com/2009/02/15/fetching-album-covers-from-lastfm-api/#comments</comments>
		<pubDate>Sun, 15 Feb 2009 05:25:48 +0000</pubDate>
		<dc:creator>Dan Sosedoff</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Web Services]]></category>
		<category><![CDATA[covers]]></category>
		<category><![CDATA[fetch]]></category>
		<category><![CDATA[last.fm]]></category>
		<category><![CDATA[webservice]]></category>

		<guid isPermaLink="false">http://blog.sosedoff.com/?p=69</guid>
		<description><![CDATA[As previous post was about fetching covers media from Amazon Web Services, this post will be about fetching covers from popular music site &#8211; Last.fm. API documentation page

#!/usr/bin/ruby
&#160;
require 'rubygems'
require 'net/http'
require 'cgi'
require 'xmlsimple'
&#160;
# key from API documentation
$lastfm_key = &#34;b25b959554ed76058ac220b7b2e0a026&#34; 
$lastfm_host = &#34;ws.audioscrobbler.com&#34;
&#160;
def fetch_cover&#40;artist, album&#41;
	artist = CGI.escape&#40;artist&#41;
	album = CGI.escape&#40;album&#41;
&#160;
	path = &#34;/2.0/?method=album.getinfo&#38;api_key=#{$lastfm_key}&#38;artist=#{artist}&#38;album=#{album}&#34;
	data = Net::HTTP.get&#40;$lastfm_host, path&#41;
	xml = XmlSimple.xml_in&#40;data&#41;
	if xml&#91;'status'&#93; [...]]]></description>
			<content:encoded><![CDATA[<p>As<a href="http://blog.sosedoff.com/2009/02/15/fetching-album-covers-from-amazon-web-service/"> previous post</a> was about fetching covers media from Amazon Web Services, this post will be about fetching covers from popular music site &#8211; Last.fm. API <a href="http://www.last.fm/api/show?service=290">documentation</a> page</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#008000; font-style:italic;">#!/usr/bin/ruby</span>
&nbsp;
<span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'rubygems'</span>
<span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'net/http'</span>
<span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'cgi'</span>
<span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'xmlsimple'</span>
&nbsp;
<span style="color:#008000; font-style:italic;"># key from API documentation</span>
<span style="color:#ff6633; font-weight:bold;">$lastfm_key</span> = <span style="color:#996600;">&quot;b25b959554ed76058ac220b7b2e0a026&quot;</span> 
<span style="color:#ff6633; font-weight:bold;">$lastfm_host</span> = <span style="color:#996600;">&quot;ws.audioscrobbler.com&quot;</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">def</span> fetch_cover<span style="color:#006600; font-weight:bold;">&#40;</span>artist, album<span style="color:#006600; font-weight:bold;">&#41;</span>
	artist = <span style="color:#CC00FF; font-weight:bold;">CGI</span>.<span style="color:#9900CC;">escape</span><span style="color:#006600; font-weight:bold;">&#40;</span>artist<span style="color:#006600; font-weight:bold;">&#41;</span>
	album = <span style="color:#CC00FF; font-weight:bold;">CGI</span>.<span style="color:#9900CC;">escape</span><span style="color:#006600; font-weight:bold;">&#40;</span>album<span style="color:#006600; font-weight:bold;">&#41;</span>
&nbsp;
	path = <span style="color:#996600;">&quot;/2.0/?method=album.getinfo&amp;api_key=#{$lastfm_key}&amp;artist=#{artist}&amp;album=#{album}&quot;</span>
	data = <span style="color:#6666ff; font-weight:bold;">Net::HTTP</span>.<span style="color:#9900CC;">get</span><span style="color:#006600; font-weight:bold;">&#40;</span>$lastfm_host, path<span style="color:#006600; font-weight:bold;">&#41;</span>
	xml = <span style="color:#CC00FF; font-weight:bold;">XmlSimple</span>.<span style="color:#9900CC;">xml_in</span><span style="color:#006600; font-weight:bold;">&#40;</span>data<span style="color:#006600; font-weight:bold;">&#41;</span>
	<span style="color:#9966CC; font-weight:bold;">if</span> xml<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'status'</span><span style="color:#006600; font-weight:bold;">&#93;</span> == <span style="color:#996600;">'ok'</span> <span style="color:#9966CC; font-weight:bold;">then</span>
		album = xml<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'album'</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">0</span><span style="color:#006600; font-weight:bold;">&#93;</span>
&nbsp;
		cover = <span style="color:#006600; font-weight:bold;">&#123;</span>
			<span style="color:#ff3333; font-weight:bold;">:small</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> album<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'image'</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'content'</span><span style="color:#006600; font-weight:bold;">&#93;</span>,
			<span style="color:#ff3333; font-weight:bold;">:medium</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> album<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'image'</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">2</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'content'</span><span style="color:#006600; font-weight:bold;">&#93;</span>,
			<span style="color:#ff3333; font-weight:bold;">:big</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> album<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'image'</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">3</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'content'</span><span style="color:#006600; font-weight:bold;">&#93;</span>
		<span style="color:#006600; font-weight:bold;">&#125;</span>
&nbsp;
		<span style="color:#0000FF; font-weight:bold;">return</span> cover
	<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
	<span style="color:#0000FF; font-weight:bold;">return</span> <span style="color:#0000FF; font-weight:bold;">nil</span>
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
<span style="color:#CC0066; font-weight:bold;">puts</span> fetch_cover<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'Nickelback'</span>, <span style="color:#996600;">'Dark Horse'</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">inspect</span></pre></div></div>

<p><a href="http://files.sosedoff.com/e15a3354/">Download</a> ruby script</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.sosedoff.com/2009/02/15/fetching-album-covers-from-lastfm-api/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Fetching album covers from Amazon Web Service</title>
		<link>http://blog.sosedoff.com/2009/02/15/fetching-album-covers-from-amazon-web-service/</link>
		<comments>http://blog.sosedoff.com/2009/02/15/fetching-album-covers-from-amazon-web-service/#comments</comments>
		<pubDate>Sun, 15 Feb 2009 05:05:29 +0000</pubDate>
		<dc:creator>Dan Sosedoff</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Web Services]]></category>
		<category><![CDATA[amazon]]></category>
		<category><![CDATA[covers]]></category>
		<category><![CDATA[fetch]]></category>

		<guid isPermaLink="false">http://blog.sosedoff.com/?p=66</guid>
		<description><![CDATA[On my small project i was looking for web service to get media covers from. I found that i can use Amazon Web Services API. The documentation for this ECommerce Service is pretty old, but it still works.
More detailed information about API you can find here

#!/usr/bin/ruby
&#160;
require 'rubygems'
require 'net/http'
require 'cgi'
require 'xmlsimple'
&#160;
$amazon_key = &#34;12DR2PGAQT303YTEWP02&#34; # NOT MY [...]]]></description>
			<content:encoded><![CDATA[<p>On my small project i was looking for web service to get media covers from. I found that i can use Amazon Web Services API. The documentation for this ECommerce Service is pretty old, but it still works.<br />
More detailed information about API you can find <a href="http://docs.amazonwebservices.com/AWSEcommerceService/2005-02-23/">here</a></p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#008000; font-style:italic;">#!/usr/bin/ruby</span>
&nbsp;
<span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'rubygems'</span>
<span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'net/http'</span>
<span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'cgi'</span>
<span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'xmlsimple'</span>
&nbsp;
<span style="color:#ff6633; font-weight:bold;">$amazon_key</span> = <span style="color:#996600;">&quot;12DR2PGAQT303YTEWP02&quot;</span> <span style="color:#008000; font-style:italic;"># NOT MY KEY (FOUND ON INTERNET)</span>
<span style="color:#ff6633; font-weight:bold;">$amazon_host</span> = <span style="color:#996600;">&quot;webservices.amazon.com&quot;</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">def</span> fetch_cover<span style="color:#006600; font-weight:bold;">&#40;</span>artist, album<span style="color:#006600; font-weight:bold;">&#41;</span>
	artist = <span style="color:#CC00FF; font-weight:bold;">CGI</span>.<span style="color:#9900CC;">escape</span><span style="color:#006600; font-weight:bold;">&#40;</span>artist<span style="color:#006600; font-weight:bold;">&#41;</span>
	album = <span style="color:#CC00FF; font-weight:bold;">CGI</span>.<span style="color:#9900CC;">escape</span><span style="color:#006600; font-weight:bold;">&#40;</span>album<span style="color:#006600; font-weight:bold;">&#41;</span>
&nbsp;
	path = <span style="color:#996600;">&quot;/onca/xml?Service=AWSECommerceService&amp;AWSAccessKeyId=#{$amazon_key}&amp;Operation=ItemSearch&amp;SearchIndex=Music&amp;Artist=#{artist}&amp;ResponseGroup=Images&amp;Keywords=#{album}&quot;</span>
	data = <span style="color:#6666ff; font-weight:bold;">Net::HTTP</span>.<span style="color:#9900CC;">get</span><span style="color:#006600; font-weight:bold;">&#40;</span>$amazon_host, path<span style="color:#006600; font-weight:bold;">&#41;</span>
	xml = <span style="color:#CC00FF; font-weight:bold;">XmlSimple</span>.<span style="color:#9900CC;">xml_in</span><span style="color:#006600; font-weight:bold;">&#40;</span>data<span style="color:#006600; font-weight:bold;">&#41;</span>
	<span style="color:#9966CC; font-weight:bold;">if</span> xml<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'Items'</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">0</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'TotalResults'</span><span style="color:#006600; font-weight:bold;">&#93;</span>.<span style="color:#9900CC;">to_s</span>.<span style="color:#9900CC;">to_i</span> <span style="color:#9966CC; font-weight:bold;">then</span>
		cover = <span style="color:#006600; font-weight:bold;">&#123;</span>
			<span style="color:#ff3333; font-weight:bold;">:small</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> xml<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'Items'</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">0</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'Item'</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">0</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'SmallImage'</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">0</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'URL'</span><span style="color:#006600; font-weight:bold;">&#93;</span>,
			<span style="color:#ff3333; font-weight:bold;">:medium</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> xml<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'Items'</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">0</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'Item'</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">0</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'MediumImage'</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">0</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'URL'</span><span style="color:#006600; font-weight:bold;">&#93;</span>,
			<span style="color:#ff3333; font-weight:bold;">:big</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> xml<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'Items'</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">0</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'Item'</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">0</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'LargeImage'</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">0</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'URL'</span><span style="color:#006600; font-weight:bold;">&#93;</span>
		<span style="color:#006600; font-weight:bold;">&#125;</span>
		<span style="color:#0000FF; font-weight:bold;">return</span> cover
	<span style="color:#9966CC; font-weight:bold;">end</span>
	<span style="color:#0000FF; font-weight:bold;">return</span> <span style="color:#0000FF; font-weight:bold;">nil</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>So, after execution of this function you will get array with 3 different images (small, medium, big).<br />
I use XML-Simple gem for ruby. Can be installed this way</p>
<pre>sudo gem install xml-simple</pre>
<p>That`s it. <a href="http://files.sosedoff.com/bace6a22/">Download script</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.sosedoff.com/2009/02/15/fetching-album-covers-from-amazon-web-service/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

