2006-05-23 @ 16:34

Browsing iTunes Networks with Ruby

I’ve been working on my ruby DAAP Client lately, and I ran across a thread on the ruby-talk list about a multicast DNS client. Combining the two of those gave me some pretty neat information about the iTunes servers running on our network.

I could easliy get a list of iTunes servers using only mdns-sd like this:

require 'rubygems'
require 'net/dns/mdns-sd'

DNSSD = Net::DNS::MDNSSD

# Find all iTunes servers
browse_service = DNSSD.browse('_daap._tcp') do |r|
  rservice = DNSSD.resolve(r.name, r.type, r.domain) do |res|
    puts res.target
  end
end

$stdin.gets
browse_service.stop

Once I was able to get a list of iTunes servers, listing all available artists was trivial. I just added the DAAP client in, and it worked:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
require 'rubygems'
require 'net/daap'
require 'net/dns/mdns-sd'

DNSSD = Net::DNS::MDNSSD

# Find all iTunes servers
browse_service = DNSSD.browse('_daap._tcp') do |r|
  rservice = DNSSD.resolve(r.name, r.type, r.domain) do |res|
    daap = Net::DAAP::Client.new(res.target)
    daap.connect do |dsn|
      daap.databases.each { |db|
        db.artists.each { |a| puts "#{res.target} #{a.name}" }
      }
    end
  end
end

$stdin.gets
browse_service.stop

Combine that with the get method on Net::DAAP::Song, and you have a winning combo! A script that will automatically detect iTunes servers, and download the music. This will be great for backing up the music I keep on my Mac. I just plug it in to the network, and this script will automatically sync it up.

read more »

2006-05-24 @ 19:30

A Mechanize Spider

A friend of mine pointed me at the Fear perl module today, and it has inspired me some on Mechanize. I couldn’t believe the size of a spider using the Fear API:

url("google.com");
&$_ >> _self while $_;

That is really amazing! I also can’t read it….. After looking at the Fear innards, I finally understood the code, so I tried to reproduce it with Mechanize. This is what I came up with:

agent = WWW::Mechanize.new
stack = agent.get(ARGV[0]).links
while l = stack.pop
  stack.push(*(agent.click(l).links)) unless agent.visited? l.href
end

To get this to work, I added the “visited?” method to the yet to be release 0.4.6 version of Mechanize. I’ve got a few more lines, but still pretty small. I still don’t like my spider though because it will visit any domain. I don’t really want it to try to read the entire internet, so I added the following line at the top of the while loop:

next unless l.uri.host == agent.history.first.uri.host

Can I make it shorter? I’m not sure yet. Do I want it to be shorter? Not sure about that either.

read more »

2006-05-26 @ 09:49

A Tender Moment or Two

Last night after Kickball practice, we went to sing karaoke at Bush Garden. I’ve never seen the place so empty! I got to sing like four times. Anyway, there were many tender moments to be encoutered. First, there was the girl passed out on the seat with her Mom (I think), and boyfriend (?) tenderly trying to revive her. Thirty minutes later, they somehow got her to stand up and walk out. That scene was very Date Rapey ™.

The next tender moment was the group of recent law school graduates who came to sing. Most of their selections need to go on Ball Deep’s bad music collection for throwing off the other team. The only songs I can remember they sang were Spin Doctors and Crash Test Dummies. I think the Crash Test Dummies one was the worst. First, how hard is it to sing “Mmm mmm mmmm mmm mmm mmm mmm mmmm mmm mmmm mmm ohhh ooohhhhhh oooohhhhh”? And she didn’t even sing in the weird Eddie Vedder type voice. The best song of the evening had to go to Pam and Stacy singing the duet with Pam being Michael McDonald.

Finally at the end of the evening was the most tender moment of all. A moment I like to call “Asian Man Singing Karaoke Tells Girls to Jiggle Those Titties”. This asian man was singing karaoke, and started yelling at Pam, Stacy and Katie to “jiggle those titties”. Luckily the guy was more Rape Junior ™ than Rape Original ™, so it wasn’t too scary.

read more »

2006-05-26 @ 01:24

Mechanize One Liners

I thought I’d try to come up with some useful one liners for Mechanize. Here goes:

Fetch a page and print to stdout:

puts WWW::Mechanize.new.get(ARGV[0]).body

List all links in a page:

WWW::Mechanize.new.get(ARGV[0]).links.each { |l| puts l.text }

Visit all links on a page:

(a = WWW::Mechanize.new).get(ARGV[0]).links.each { |l| puts a.click(l).body }

List all links that match a pattern:

WWW::Mechanize.new.get(ARGV[0]).links.text(/[a-z]/).each { |l| puts l.text }

Visit all links that match a pattern:

(a = WWW::Mechanize.new).get(ARGV[0]).links.text(/[a]/).each { |l| puts a.click(l).body }

Smaller Spider:

(mech = WWW::Mechanize.new).get(ARGV[0])
(a = lambda { |p|
  mech.page.links.each { |l| mech.click(l) && p.call(p) if ! mech.visited? l }
}).call(a)
read more »

2006-05-28 @ 19:39

Beta Brite Signs

Probably a year or two ago, I bought a one of those Beta Brite Signs and made a Perl library to interface with it. My perl library wasn’t very good, so I’ve decided to port it to Ruby, and I’ve been able to get the interface even better in Ruby.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
require 'betabrite'
require 'serialport'

include Sign

obj = SerialPort.new(0, 9600, 8, 1, SerialPort::NONE)

sign = BetaBrite.new

tf = BetaBrite::TextFile.new 
tf.message = "Hello World"
sign.add tf

sign.write { |text|
  obj.write text
}

I still think it can be improved, but I’m getting there. I’ve been able to get all of the colors working, the fonts working, and even draw custom pictures. I’ve submitted a project to RubyForge, and I should be able to release a gem for this soon.

read more »

2006-05-30 @ 12:27

Ball Deep Weekend

</span>

This weekend was basically awesome. Highlights include, kickball practice, multiple karaoke nights, China Gate staying open until 3 AM for us, shooting a kickball training video, manties, looking like Britney Spears, a yoga ball rumble, and much more. I am still trying to recover from having more fun than anyone in the world.

read more »