inet_ntoa and inet_aton in Ruby

Posted by Dan Sosedoff on April 16, 2009

Here is two small functions to convert IP addresses from string representation to integer and vice versa.

def inet_aton(ip)
    ip.split(/\./).map{|c| c.to_i}.pack("C*").unpack("N").first
end
 
def inet_ntoa(n)
    [n].pack("N").unpack("C*").join "."
end

Simple file uploader to Amazon S3 Service 1

Posted by Dan Sosedoff on March 22, 2009

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 files and buckets. Pricing also comfortable.

Welcome to cloud computing! :) I started using it with Ruby. Regular gem and docs can be found at http://amazon.rubyforge.org/

So, the first useful tool i decided to created – simple uploader of local files to amazons server.
First, we need to create bucket and make it public:

Bucket.create('NAME_HERE',:access => :public_read)

Here`s the client ruby script:

#!/usr/bin/ruby
 
require 'rubygems'
require 'aws/s3'
 
include AWS::S3
 
$s3_bucket = "BUCKET_NAME"
$s3_key = "API_KEY"
$s3_secret = "API_SECRET"
 
def s3_store(localfile)
	if File.exists?(localfile) && File.readable?(localfile)
		puts "Uploading file [#{localfile}]. Size: #{File.size(localfile)} bytes."
		name = File.basename(localfile)
		Base.establish_connection!(:access_key_id => $s3_key, :secret_access_key => $s3_secret)
		S3Object.store(name, open(localfile), $s3_bucket, :access => :public_read)
		puts "Download link: http://s3.amazonaws.com/#{$s3_bucket}/#{name}"
	else
		puts "File not exists or not accessible. Please check file and try again!"
	end
end
 
path = ARGV[0]
if !path
	"Please specify the file to upload."
else
	s3_store(path)
end

Download script: http://files.sosedoff.com/036cfedd/

BTW, I found cool firefox add-on to manage S3 objects/files. It`s pretty easy.
Link to extension – http://www.s3fox.net
Screenshot:

Scaling images with ImageMagick and PHP 1

Posted by Dan Sosedoff on March 20, 2009

Here is php version of ruby class that i made a long time ago. The same functionality and results.

<?
class ImageScale {
 
	private function changeGeometry($sz,$value) {
		if ($sz['width'] > $sz['height']) { // horizontal image
			$newsz['width'] = $value;
			$newsz['height'] = ceil(($newsz['width'] * $sz['height']) / $sz['width']);
		}
		else { // vertical image
			$newsz['height'] = $value;
			$newsz['width'] = ceil(($newsz['height'] * $sz['width']) / $sz['height']);
		}
		return $newsz;	
	}
 
	private function changeGeometry2($sz,$value) {
		$newsz['width'] = $value;
		$newsz['height'] = ceil(($newsz['width'] * $sz['height']) / $sz['width']);
		return $newsz;
	}
 
	/**
	 * 	Make thumbnail of specified maximum side size
	 */
	public function processThumb($source_path, $dest_path, $sidesize, $quality=85, $scale_method=1) {
		if (file_exists($source_path) && is_readable($source_path)) {
			$image = new Imagick($source_path);
 
			$geometry = $image->getImageGeometry(); // ['width', 'height']
			if ($geometry['width'] > $sidesize) {
				if ($scale_method == 1) $geometry = $this->changeGeometry($geometry,$sidesize);
				if ($scale_method == 2) $geometry = $this->changeGeometry2($geometry,$sidesize);
			}
			$image->cropThumbnailImage($geometry['width'],$geometry['height']);
			$image->setCompression(Imagick::COMPRESSION_JPEG);
			$image->setCompressionQuality($quality);
			return $image->writeImage($dest_path);
		}
		return false;
	}	
 
	/**
	 * 	Make square thumbnail
	 */
	public function processRectThumb($source_path, $dest_path, $size=150, $quality=85) {
		if (file_exists($source_path) && is_readable($source_path)) {
			$image = new Imagick($source_path);
 
			if ($image) {
				$image->cropThumbnailImage($size,$size);
				$image->setCompression(Imagick::COMPRESSION_JPEG);
				$image->setCompressionQuality($quality);
				return $image->writeImage($dest_path);
			}
		}
		return false;
	}
}
?>

Download file – http://files.sosedoff.com/1167c8db/

Scaling images with RMagick

Posted by Dan Sosedoff on March 14, 2009

Simple class that providing scaling (rectangle and thumbnails) for images using RMagick and Ruby.
Code:

class ImageScale
    def change_geometry(sz,value)
        w = sz[0] ; h = sz[1]
            if w > h
                sz[0] = value
                sz[1] = ((value * h) / w).floor
            else
                sz[1] = value
                sz[0] = ((value * w) / h).floor
            end
            return sz
    end
 
    def make_rect(file_in,file_out, width, quality=85, sharp=false) 
        if FileTest.exists?(file_in)
            begin
                img = Magick::Image.read(file_in).first
                img.crop_resized!(width,width, Magick::CenterGravity)
                img = img.sharpen(0.5, 0.5) if sharp
                img.write(file_out) { self.quality = quality }
                return true if FileTest.exists?(file_out)
            rescue Magick::ImageMagickError
                return false
            end
        end
        return false
    end
 
    def make_thumb(file_in,file_out, width_to, quality=85, sharp=false) 
        if FileTest.exists?(file_in)
            begin
                img = Magick::Image.read(file_in).first
                info = [img.columns,img.rows]
                sz = change_geometry(info, width_to)
                img = img.resize(sz[0],sz[1])
                img = img.sharpen(0.5, 0.5) if sharp
                img.write(file_out) { self.quality = quality }
                return true if FileTest.exists?(file_out)
            rescue Magick::ImageMagickError
                return false
            end
        end
        return false
    end
end

Ok, let`s see how this class working. For example, we have source image:
Source Image

Function ImageScale.make_rect(src,dest,64) will produce such image:
Rectangle Image

Function ImageScale.make_thumb(src,dest,200) will produce thumbnail:
Thumbnail Image

There is optional parameter sharp to use sharping. Optional parameter quality is set to 85% compression value.

Fetching album covers from Last.Fm API 3

Posted by Dan Sosedoff on February 15, 2009

As previous post was about fetching covers media from Amazon Web Services, this post will be about fetching covers from popular music site – Last.fm. API documentation page

#!/usr/bin/ruby
 
require 'rubygems'
require 'net/http'
require 'cgi'
require 'xmlsimple'
 
# key from API documentation
$lastfm_key = "b25b959554ed76058ac220b7b2e0a026" 
$lastfm_host = "ws.audioscrobbler.com"
 
def fetch_cover(artist, album)
	artist = CGI.escape(artist)
	album = CGI.escape(album)
 
	path = "/2.0/?method=album.getinfo&api_key=#{$lastfm_key}&artist=#{artist}&album=#{album}"
	data = Net::HTTP.get($lastfm_host, path)
	xml = XmlSimple.xml_in(data)
	if xml['status'] == 'ok' then
		album = xml['album'][0]
 
		cover = {
			:small => album['image'][1]['content'],
			:medium => album['image'][2]['content'],
			:big => album['image'][3]['content']
		}
 
		return cover
	end
 
	return nil
end
 
puts fetch_cover('Nickelback', 'Dark Horse').inspect

Download ruby script

Fetching album covers from Amazon Web Service 1

Posted by Dan Sosedoff on February 15, 2009

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
 
require 'rubygems'
require 'net/http'
require 'cgi'
require 'xmlsimple'
 
$amazon_key = "12DR2PGAQT303YTEWP02" # NOT MY KEY (FOUND ON INTERNET)
$amazon_host = "webservices.amazon.com"
 
def fetch_cover(artist, album)
	artist = CGI.escape(artist)
	album = CGI.escape(album)
 
	path = "/onca/xml?Service=AWSECommerceService&AWSAccessKeyId=#{$amazon_key}&Operation=ItemSearch&SearchIndex=Music&Artist=#{artist}&ResponseGroup=Images&Keywords=#{album}"
	data = Net::HTTP.get($amazon_host, path)
	xml = XmlSimple.xml_in(data)
	if xml['Items'][0]['TotalResults'].to_s.to_i then
		cover = {
			:small => xml['Items'][0]['Item'][0]['SmallImage'][0]['URL'],
			:medium => xml['Items'][0]['Item'][0]['MediumImage'][0]['URL'],
			:big => xml['Items'][0]['Item'][0]['LargeImage'][0]['URL']
		}
		return cover
	end
	return nil
end

So, after execution of this function you will get array with 3 different images (small, medium, big).
I use XML-Simple gem for ruby. Can be installed this way

sudo gem install xml-simple

That`s it. Download script

Writing simple daemons in C

Posted by Dan Sosedoff on February 13, 2009

Since i started writing simple manuals about how to make system daemons i found bunch of interesting documents. For today, i just want to publish one of them instead of writing source code. This is manual originally written by Devin Watson, can be very useful for those how have no idea how to develop such system daemons. It`s only a basic information.

http://www.netzmafia.de/skripten/unix/linux-daemon-howto.html