Saturday, December 8, 2012

How to get Artist from a Youtube Video in Ruby

I've not seen a good answer for this so far, but I discovered one, and I think you'll agree it's quite clever! I considered making this into a gem, but it's so simple, one is not required.

First, use whatever youtube gem you want to grab the title of the youtube video.

Second, get this gem: https://github.com/wiseleyb/google_custom_search_api

Follow instructions there on how to setup your Google Custom Search account and a Custom Search Engine(CSE) that searches all websites. Put the gem into your app as per their instructions, get it working.

Then use this code:

query = video_title
first_entry = "no artist found"

results = GoogleCustomSearchApi.search(query)
results.items.each do |item|
  if item["htmlSnippet"] and m = item["htmlSnippet"].match(/by.*<b>([\w\s]*)<\/b>/)
    first_entry = m[1]
   end
end

first_entry has your artist after you run this. What it does is it scans every Google result snippet for the html "by ...some more useless words... <b>BandName</b>. There is almost ALWAYS a page on the search results that has this pattern, and we isolate the band name by using the fact these pages ALWAYS turn band names into links going to pages about them.

I've tried these videos and gotten it to work:

Shakira - Give it up to me
Linkin park - in the end
Imagine Dragons - it's time

etc. It relies on the fact too that most youtube videos include the band name in the title. The problem is for us coders that it's not often very standard, sometimes it will be linkin park in the end, or in the end - linkin park, or linkin park "in the end", etc. Instead of trying to puzzle it out, let Google do it!

Hope this helped you, certainly helped me.



Tuesday, December 4, 2012

Delete route not showing up in rails 3

I wanted to add a destroy action to my rails controller. My routes file looked like so:
match "applications/:id" => 'applications#show'
delete "applications/:id" => "applications#destroy"

But no matter what I did, the destroy action never got called. This is because match is above delete, overriding it. You must switch the order in which you call them in routes or else delete will get superseded.

delete "applications/:id" => "applications#destroy"
 match "applications/:id" => 'applications#show'

Works.

Can't activate rack-, already activated rack- (Gem:::LoadError)

Encountered this one when I was trying to run my sinatra app on my work machine. Worked just fine at home, but when I ran

rackup config.ru -E development here I got:

/usr/lib/ruby/1.9.1/rubygems/specification.rb:1603:in `raise_if_conflicts': can't activate rack-1.2.5, already activated rack-1.4.1 (Gem::LoadError)
    from /usr/lib/ruby/1.9.1/rubygems/specification.rb:738:in `activate'
    from /usr/lib/ruby/1.9.1/rubygems/custom_require.rb:51:in `block in require'
    from /usr/lib/ruby/1.9.1/rubygems/custom_require.rb:50:in `each'
    from /usr/lib/ruby/1.9.1/rubygems/custom_require.rb:50:in `require'
    from /var/lib/gems/1.9.1/gems/backports-2.6.5/lib/backports/tools.rb:314:in `require_with_

Crap.

So then I did

 gem list | grep rack
crack (0.3.1)
rack (1.4.1, 1.4.0, 1.3.2, 1.2.5)
rack-cache (1.2, 1.0.3)
rack-mount (0.8.3, 0.6.14)
rack-oauth2 (1.0.0)
rack-pjax (0.6.0, 0.5.9)
rack-protection (1.2.0)
rack-proxy (0.3.7)
rack-ssl (1.3.2)
rack-test (0.6.2, 0.6.1, 0.5.7)

Look at all those rack versions. I read somewhere that bundle may be getting confused. So I did

sudo gem uninstall rack

And killed them all off.

Then I did sudo gem install rack, it installed 1.4.1, and magically, the command worked again.