Friday, January 19, 2007

Rflickr and Google maps mashup

So you've started with rails and now your looking for something else to do after all you didn't think that the book was to hard easy right? Gems are an awesome part of ruby they can add a good deal of functionality to your project. In this tutorials we are going to be using the rflickr gem not to be confused with the flickr gem; These two are complete polar opposites. Getting started you can use Maxx Dunn's tutorial for installing and activating the rflickr gem (if you don't have it installed already). Now that you have all that done lets begin to write some code. Since the rflickr gem doesn't have any built in geo functions we'll have to construct them ourselves. First we need create a new rails project so that we can start off with a nice clean canvas.

rails mynewproject


Now change directories to the mynewproject and create a new controller with an index page.


cd mynewproject

script/generate controller View index


Alright now that we have that completed, start writing some code after all that's what we came to do. Open up the view.rb file found in app/controller directory. We'll get the peliminaries out of the way first. Declare you variables which are API_KEY and SHARED_SECRET these are just so we don't have to write them over and over again. Then we set the flickr gem to required.


require 'flickr'

API_KEY = "your_api_key"

SHARED_SECRET = "your_secret"


Now we need to create the index actions. For the index we need to load in a flickr instance and get the proper authorizations.


flickr = Flickr.new("/tmp/flickr.cache", API_KEY, SHARED_SECRET)

flickr.auth.token


Now we get to write our own custom function using the xml and rflickr libraries not really too complicated. I'll try to explain what each line does. First lets define a new function that way everything is separated.


def GetLocation(photo)

end


Then we start adding more code in this function.


flickr = Flickr.new("/tmp/flickr.cache", API_KEY, SHARED_SECRET)

photo = photo.id if photo.class == Flickr::Photo


Now what we've done is made another instance to use just for this function then we added the photo.class to make sure we get a photo after all that's what we wanted right?



res = flickr.call_method('flickr.photos.geo.getLocation',

'photo_id'=>photo)


What we just did is added the method that we want to call and believe it or not it is that easy. Now that method will return an xml response which we can use. Which would look something like this.


<rsp stat="ok">

<photo id="269619243">

<location latitude="36.675303" longitude="-82.816829" accuracy="16"/>

</photo>

</rsp>


Now add the last bit of code.


lat = [ ]

res.elements['/photo'].each_element do |location|

att = location.attributes

lat << att['latitude'] + ", " + att['longitude']

end

return lat


And now that's the last bit of code we have to add. First we made a variable to contain the data then we have to put data into or it is useless. The att variable just makes our program look at the attributes instead of the content because with these xml files we don't have any content that's useful. So after we pick off the lat and lng we end it and return the lat variable which has now got our geo data in it. Lets add that function we just created into our index function. For now we'll just hard code the id in. To make this really functional we would load the id# from a text box on the page or something like that but I'm sure that you can figure out how to do that.


@loc = GetLocation('269619243')


Now go to the app/views/view/ directory and open up the index.rhtml. Delete all of the content inside of it. I prefer starting with a clean slate. I don't really need to explain all of this code just the ruby parts the google maps documentation does a pretty good job of explaining everything.


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"

"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">

<head>

<meta http-equiv="content-type" content="text/html; charset=utf-8"/>

<title>View</title>

<script src="http://maps.google.com/maps?file=api&amp;v=2&amp;key=ABQIAAAAUzR0Te-MXqdOV0HHbLuZzxTJQa0g3IQ9GZqIMmInSLzwtGDKaBQCm9xJHrKAuzvUhpgFvwlPeNxPnw"

type="text/javascript"></script>

<script type="text/javascript">

//<![CDATA[


function load() {

if (GBrowserIsCompatible()) {

var map = new GMap2(document.getElementById("map"));



<% for location in @loc %>

map.setCenter(new GLatLng(<%= location %>), 13);

map.addOverlay(new GMarker(<%= location %>));

<% end %>

}

}


//]]>

</script>

</head>

<body onload="load()" onunload="GUnload()">

<div id="map" style="width: 500px; height: 300px"></div>

<br />

<% for location in @loc %>

<%= location %> <br />

<% end %>

</body>

</html>


Ok I know if we were loading multiple locations we would want something fancier than what I've got but this tutorial is just to get you started by no means is it all you can do with it. So basically all our ruby does is set the map center to the location we gave it and put a marker there (I'm trying to keep this simple so you can follow that's why I just did one image at a time.). We'll boot up web brick and watch this thing run.


When your done your source for the view.rb file should look like this:


class ActivateController < ApplicationController


require 'flickr'


API_KEY = "7483873a88574d1ec1cdb94ee3ccf0b1"

SHARED_SECRET = "b08a4090e6b235a3"


def index

flickr = Flickr.new("/tmp/flickr.cache", API_KEY, SHARED_SECRET)

flickr.auth.token

@loc = GetLocation('269619243')

end


def GetLocation(photo)

flickr = Flickr.new("/tmp/flickr.cache", API_KEY, SHARED_SECRET)

photo = photo.id if photo.class == Flickr::Photo

res = flickr.call_method('flickr.photos.geo.getLocation',

'photo_id'=>photo)

lat = []

res.elements['/photo'].each_element do |location|

att = location.attributes

lat << att['latitude'] + ", " + att['longitude']

end

return lat

end


and the index.rhtml should look like this:


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">

<head>

<meta http-equiv="content-type" content="text/html; charset=utf-8"/>

<title>View</title>

<script src="http://maps.google.com/maps?file=api&amp;v=2&amp;key=your_api_key_here" type="text/javascript"></script>

<script type="text/javascript">


function load() {

if (GBrowserIsCompatible()) {

var map = new GMap2(document.getElementById("map"));



<% for location in @loc %>

map.setCenter(new GLatLng(<%= location %>), 13);

map.addOverlay(new GMarker(<%= location %>));

<% end %>

}

}


</script>

</head>

<body onload="load()" onunload="GUnload()">

<div id="map" style="width: 500px; height: 300px"></div>

<br />

<% for location in @loc %>

<%= location %> <br />

<% end %>

</body>

</html>


I hope you've enjoyed this tutorial and I look forward to writing more. Please send all of your feedback to chrisprayingmantis@yahoo.com.

Saturday, January 13, 2007

The real guide for getting up and running with rflickr

OK so a project I'm working on now is using the flickr api to get pictures, so my team looked around the web for a good library for ruby and at last we found rflickr. Rflickr has very little documentation except for Max Dunn's tutorial witch I borrowed some from so here's how I did it

First create a new rails project:

%> rails myapp
%> cd myapp

Now lets make sure we have the latest version of the gem installed

%> sudo gem install rflickr

Make sure you install all of the required dependencies
Now we're ready to get started open the ruby console

%> script/console
Loading development environment.

now we make sure we require the flickr library

>> require 'flickr'

now set your api key and your shared secret

>>API_KEY = "your_api_key_here"
>>SHARED_SECRET = "your_secret_here"

now we start flickr up don't forget to include the path to flickr.cache

>>flickr = Flickr.new ("/tmp/flickr.cache", API_KEY, SHARED_SECRET)

now we get the frob,

>>flickr.auth.getFrob

and generate the login link.

>>flickr.auth.login_link('write')

now copy that link into your browser and allow it
Now all that's left to do is to get the token and cache the token

>>flickr.auth.getToken
>>flickr.auth.cache_token

Rock on now we're up and running...so we got this flickr think so ummm what can we do with it. Well lets try it on something simple shall we? First restart the console, then we just have a few steps instead of all of those steps all over again.

Set your api key and your secret
>>API_KEY = "your_api_key_here"
>>SHARED_SECRET = "your_secret_here"

Then load your environment and the token.

>>flickr = Flickr.new("/tmp/flickr.cache", API_KEY, SHARED_SECRET)
>>flickr.auth.token

Lets try a simple function first. Let's get a users tags.

>>flickr.tags.getListPhoto('269619243')

The rest of the api is straight forward. It's just like the flickr api. If you have any topics that you find interesting or want to learn about and I'll try to post them here. As always you can contact me at chrisprayingmantis@yahoo.com. I would love to hear from anyone who is reading this blog.

Sunday, January 07, 2007

Happy New Year

Well this a new year time for new beginnings new software and more learning. Its more so a new beginning for me because I got a new Macbook Pro over the holidays and I'll have to say that I am now an Apple fanboy. Also over the Holidays Adobe released their new CS3 which is awesome. Finally over the holidays I learned about the new D programming language that's aimed at taking ruby and C and using the best of both to create a new language. I have to say I like what I've seen from D so far it looks to be far easier to learn than C or C++ . Well I'll be signing off for this week see y'all later.