Entries Tagged 'RubyOSA' ↓

A time to revisit old gunk

Steven Bristol noted that the posted version of my “Change IM Status” script doesn’t work in Leopard. That may be as I’ve tweaked the heck out of it over the past several months but never posted the updates.

Hell, this is the first that I’ve heard of anyone else using the little beast. Cool!

What I really want to do with my IM/messaging apps is selectively block contacts programatically. This would let me build an “I’m Working” state where I could block out the world except for my immediate colleagues, for instance. Being somewhat ADD-ish (show me a developer who isn’t!) and a nearly-compulsive checker of incoming e-mail/IMs, this would be huge for me. I’m DYING for this.

Sadly, neither app seems to provide that level of event to OSA such that I could “veto” an incoming chat. I’m probably SoL regarding Skype but perhaps not so with Adium. I taught myself Objective-C for shits and giggles a few months ago after a chat with uber-hacker Marcel Molina. Maybe the Adium folks would be amenable to a new feature?

I’d still prefer for an event-based architecture where I could register my app for OSA events from Skype/Adium and use them to effect Skype/Adium.

Hrm. I wonder if iChat provides a more robust OSA model? Worth a looksy.

P.S. I’m ticked that the “Current Application” -> “Show Menu Items” feature of Quicksilver seems to be broken in Leopard. I loved this feature for blog posting from TextMate…

RubyOSA presentation to Northern Virginia Ruby Users Group

This evening’s NoVaRUG was a good time. Rodney Degracia spoke first about RubyCLR, which provides a dynamically generated bridge between a Ruby VM and the RubyCLR. If I ever need to get at .NET internals again, now I know how I’m going to do it. In fact, I dropped an e-mail to a colleague in the office about it — except that his assembly is executed from Python. A quick Google turned up “Python for .NET” as an option.

Then it was my turn to talk to RubyOSA and RB-AppScript. Admittedly, after using both, I’m strongly biased toward RubyOSA. I have the distinct feeling that, after my presentation, the audience felt the same way.

Well, the Mac users in the audience.

Out of twenty or so people in the room, it turned out that I was really presenting to perhaps five or six Mac users. I suppose that RailsConf is in no way representative of your average Right Coast Ruby developer. However, oddly, nearly everyone stayed for my presentation. I even fielded several good questions. All in all, I had a blast.

When Xandy asked for topics for next time, I asked if someone would present on RSpec. His next words were, “Thanks for volunteering, Evan.”

Time to learn RSpec…

Slides available here: OS X Scripting with Ruby

Return values in RubyOSA

While holding the Ruby Hoedown BoF about RubyOSA and AppScript, I mentioned how I’ve never gotten a return value out of RubyOSA — which is why I used AppScript when I needed a return value.

Shoot me now.

A quick google of “rubyosa applescript return value” yielded this post to ruby-talk-google. Woops…

It’s this simple:

require 'rubygems'
require 'rbosa'
skype = OSA.app('Skype')
OSA.wait_reply = true
call = skype.send2 "call echo123"

And call is non-nil.

Admittedly, I’m somewhat at a loss as to why wait_reply is defaulted to nil…

Update 8/11/04 1609: Laurent tells me that, if the Applescript definition is correct, RubyOSA should correctly provide return values. Chalk that up as yet another bug in the Skype Applescript API. I’ll report it soon (it’s going into iGTD now…).

– Thanks, Laurent!

Introducing rb-skypemac

Since I discovered rubyosa, I’ve made it one of my side projects to improve the accessibility of my wife’s iMac. She loves to use Skype to video chat with her mother in Maryland and her brother in New York. However, the tiny buttons in Skype cause the UI to be problematic for her.

What to do?

I planned (and still do) to write a simple UI for Skype with larger buttons and fonts. However, in order to do so, I needed an interface that would allow me to do more than merely send commands to Skype. Sadly, rubyosa falls down here.

But then I found rb-appscript or just appscript. Appscript seems to provide a more direct connection to the Applescript Event layer and it provides return values from Applescript unlike the current 0.4.0 version of rubyosa.

All said, I implemented a small subset of the Skype API as a gem. I’ve submitted it to RubyForge for addition as a project. Until then, I give you rb-skypemac-0.1.0.

I have yet to decide if I will take this gem further. If it proves adequate for my needs, I may just move on to my next project: a more feature complete version of rb-itunes than what has been submitted to RubyForge.

[Get it here: rb-skypemac]

Controlling IM app statuses in one place

For my next trick, I was going to sling together a UI to help my wife manage Skype. But then I found that the Skype API is a little more painful than just RubyOSA.

I discovered that RubyOSA comes with a built in script to generate RDoc for any AppleScript-supporting application that has a defined AppleScript definition. How handy! “rdoc –name Skype” and off I went. Or so I thought. Skype’s AppleScript API is simple: they give you one command that accepts commands using their protocol.

Not entirely dissuaded, I started my campaign to create a script to change the status of my iChat, Adium, and Skype (yes, I need all three — don’t you???) simultaneously.

To automate things further, I deposited the script in ~/Library/Application Support/Quicksilver/Actions. I then input the command (on, off, or away) via Quicksilver using ‘.’ to let me enter a command and then my script shows up as a target. I then created Quicksilver hotkeys for online (CTRL-CMD-UP), offline (CTRL-CMD-DOWN), and away (CTRL-CMD-LEFT or “exit stage left” as I see it). So, finally, my IM status should reasonably reflect when I’m actually on or off.

If you want to use this script:

  • Bear in mind, your Ruby binary is probably installed somewhere other than /usr/local/bin/ruby so you’ll need to tweak that line.
  • You’ll need rubygems installed
  • You’ll need the RubyOSA gem installed

No, Steve, I was not up all night working on this.

[Download] (right click “Save Link As”)

Update (3/12/07): Since made some minor tweaks to support custom away messages for Adium and iTunes. Of course, to make this “sexy” (extensible), I’d scan a subdirectory for “plugins” that would manage the status per IM application allowing for you Mac users who use Fire instead of Adium, for example.

#!/usr/local/bin/ruby

require 'rubygems'
require 'rbosa'

def get_app(app_name)
  app = OSA.app(app_name)
  if app.nil?
    puts "#{app} does not exist"
    exit
  end
  app
end

$Adium = get_app "Adium"
$iChat = get_app "iChat"

$MESSAGE = {
  :on => "Available",
  :away => "Away",
  :off => "" # moot anyway
}

$STATUS = {
  :Skype => {
    :off => "OFFLINE",
    :on => "ONLINE",
    :away => "AWAY"
  },
  :Adium => {
    :off => OSA::Adium::ASST::OFFLINE,
    :on => OSA::Adium::ASST::AVAILABLE,
    :away => OSA::Adium::ASST::AWAY    
  },
  :iChat => {
    :off => OSA::IChat::MSTA::OFFLINE,
    :on => OSA::IChat::MSTA::AVAILABLE,
    :away => OSA::IChat::MSTA::AWAY
  }
}

def is_known_status?(app, status)
  $STATUS[app].has_key? status
end    

def set_Skype_status_to(status)
  if not is_known_status? :Skype, status
    # No custom statuses with Skype, sorry!
    status = :away
  end
  app = get_app “Skype”
  request = “SET USERSTATUS #{$STATUS[:Skype][status]}”
  app.send2 request, “”
end

def set_Adium_status_to(status)
  if is_known_status? :Adium, status
    $Adium.adium_controller.my_status_type = $STATUS[:Adium][status]
    $Adium.adium_controller.my_status_message = $MESSAGE[status]
  else
    $Adium.adium_controller.my_status_type = $STATUS[:Adium][:away]
    $Adium.adium_controller.my_status_message = status.to_s
  end    
  if status == :on
    $Adium.adium_controller.accounts.each { |a| a.connect }
  end
end

def set_iChat_status_to(status)
  if is_known_status? :iChat, status 
    $iChat.status = $STATUS[:iChat][status]    
    $iChat.status_message = $MESSAGE[status]
  else
    $iChat.status = $STATUS[:iChat][:away]
    $iChat.status_message = status
  end
end

status = ARGV[0].intern
set_Skype_status_to status
set_Adium_status_to status
set_iChat_status_to status  

Ruby + RubyOSA = No more hand-jamming metadata in iTunes!

Having a Mac and a lot of DVDs, I happen to be quite fond of Handbrake. However, how is one supposed to organize all of this video within iTunes for inevitable use on an AppleTV, I ask you?

Videos imported into iTunes 7 automatically register as “Movies”. So how do you handle TVShows? By changing/adding metadata to each of the populated fields on these screens:

video.png

info.png

That’s a whole lot of metadata! Sure, you can update all of the metadata by hand but, really, who has the time?

So I wrote some code.

With RubyOSA, the world of AppleScript is now available to Ruby developers — without the trama of learning AppleScript!

If you can understand the code below, you should be able to figure out how to tweak it ever so slightly as necessary to have it manipulate your media of choice.

require 'rubygems'
require 'rbosa'

$show = “Babylon 5″ $year = 1994 $itunessearchstr = “B5″

app = OSA.app(’iTunes’) exit unless not app.nil?

movies = app.sources[0].playlists.find { |p| p.name == “Movies” }

tracks = movies.search $itunessearchstr tracks.each do |track|

puts track.name

track.name.match /B5\s-\s(\d+)\s(.*)/ track.name = $2 track.tracknumber = $1.toi track.artist = $show track.album_artist = $show track.album = $show

track.show = $show track.episodeid = $1.toi track.episodenumber = $1.toi track.year = $year track.season_number = 1

track.videokind = OSA::ITunes::EVDK::TVSHOW end