eigendaddy

May 29th, 2008 by rickbradley 0 comments »

From the #railsconf irc channel:


olabini: so there are two different constructs that are commonly (apparently incorrectly) called metaclass:
dchelimsky: 1. the current object's singleton class
dchelimsky: 2. the current object's class's singleton class
olabini: yeah
dchelimsky: eigenclass is the name for 1, iirc
dchelimsky: so what's 2/
dchelimsky: ?
olabini: and 2 is the class's eigenclass
dchelimsky: LOL
rickbradley: eigendaddy
dchelimsky: I want *one* word
olabini: hahaha
miloops: lol
rickbradley: ;-)
dchelimsky: eigendaddy it is

Just one more OGC value-added service for the Rails community.

who's calling?

May 24th, 2008 by rickbradley 0 comments »

This is an almost silly/trivial enough thing to not warrant a post, but since I didn’t see a trivial way to do this publicized on the internets, I should probably write it up.

So I have an asterisk box set up on my home phone line, primarily to hassle law-breaking telemarketers and debt collectors (I don’t have any debts that need collecting, but that doesn’t mean I don’t get the occasional debt collector calling the wrong person and refusing to accept the truth).

With the arrival of a sister-in-law and another house guest, the number of inbound phone calls has jumped noticeably. The unifying trait of these calls: in nearly all cases, they’re not for me. That doesn’t mean I don’t often find myself getting up to look at the caller ID, i.e., distracting myself from whatever it was that was doing when the phone rang.

So, I tried setting up app_notify which promised to be the simplest path to asterisk -> growl caller ID notification to my Mac laptop. 30 minutes, a few install errors, some hand attempts with getting the C happy on OS X, etc., I said “screw that.” I’ve written large-scale AGI apps (some have have been running continuously for upwards of 3 years now under heavy call load). Hopefully I can write an AGI that pings my laptop with a growl message when the phone rings.

So, I installed one of the various Ruby AGI libraries (batphone), installed ruby-growl, hacked around a bit and came up with this tiny script:


#!/usr/bin/env ruby

require 'rubygems'
require 'agi'
require 'ruby-growl'

thing = ''
begin
  agi = AGI.new
  thing << [ agi.env['callerid'], agi.env['calleridname']].join("\n")
rescue Exception => e
  thing << "Error: #{e.inspect}" 
end

['192.168.1.148','192.168.1.104'].each do |host|
  g = Growl.new host, 'incoming phone call', ["incoming phone call"]
  g.notify "incoming phone call", "incoming phone call", thing
end

exit

Granted, the list of IP addresses is hardwired, so it’s highly inelegant. This is also the first script I’ve written in a long while that wasn’t done test-first. My rule (excuse) for not writing tests first in an instance like this is, if it’s completely an exploratory spike I will sometimes not bother. If I want to package it, redistribute it, reuse it, put it into production, etc., then I rewrite it after the spike test-first from scratch. Publishing this script is serving as an example for anyone who wants to know how to do this, but recommending that if it’s useful you or I rewrite something better test-first. I also recommend looking into Adhearsion if you want to do more sophisticated Ruby + Asterisk work.

Anyway, to turn this on, save it in /var/lib/asterisk/agi-bin/announce_callerid.agi, make sure to make it executable (chmod +x), then put the following in your /etc/asterisk/extensions.conf:


exten => s,1,AGI(announce_callerid.agi)

Finally, “asterisk -r” and type “restart when convenient” to update everything. I had to update growl versions on one of the laptops and make sure that network announcements are enabled. I skyped our home phone and bing there’s the callerid notice on both laptops.

Daddy hasn't got a brand new bag

May 13th, 2008 by ymendel 2 comments »

That title sucks. Sorry.

First and foremost, a shout-out goes to “Intense” Chris Bailey for being, as far as I know, one of the few people who care about and use Object Daddy, or at least he talks about it. Thanks to his interest, some problems got shaken out and some behavior tightened up.

Thanks to GitHub’s social networking-ness, Chris probably already knows about this, but it’s worth telling the whole world (as I refer to blogicx readership): Object Daddy has some updates to talk about.

I. generate/generate! no longer have this weird difference of one just making the object and the other saving as well as raising an exception if something went wrong. A new method, spawn, was made to handle the case of making a new object (analogous to new) and generate/generate! are now like create/create!.

A. It was mentioned before that STI and inheritance work nicely with generators, subclasses inheriting generators from parent classes but being able to define their own overrides. Well, that had a bug that relied on the classes being loaded in a certain order. That’s been fixed.

א. Generating an object through an association now works as expected. Take the following Category and Item models.

class Category < ActiveRecord::Base
  has_many :items
end

class Item < ActiveRecord::Base
  belongs_to :category
  validates_presence_of :category
end

No longer will some_category.items.generate create a new item that belongs to a new category. No, that item will belong to some_category.

Kudos and cheers all around, and keep on, uh, Daddying.

Or whatever.

The most opportune gem ever?

May 8th, 2008 by ymendel 0 comments »

We can all agree that most development stems from people wanting to make something easier, right? I’m not just talking about programming, but that’s what I do, something I know well, and what I’m specifically talking about here. And it comes from wanting to make something easier.

And sometimes that comes in the form of wanting to stamp out an annoyance.

The past couple of days saw me working a lot with trying to get specific times on specific dates, cleaning up code that originally looked like

day_time = Time.local(date.year, date.month, date.day, input[:day_hour], input[:day_minute])
night_time = Time.local(date.year, date.month, date.day-1, input[:day_hour], input[:day_minute])

And while I knew it worked, I really hated that date.day-1 thing. Maybe I’m just a tight-ass, but it looks and feels so wrong, especially in Ruby. I preferred to be specific, which meant instead making the code look like

day_time = Time.local(date.year, date.month, date.day, input[:day_hour], input[:day_minute])
prev_date = date - 1
night_time = Time.local(prev_date.year, prev_date.month, prev_date.day, input[:day_hour], input[:day_minute])

That soothed one (slight) annoyance, but the major one was still there. What I really wanted to do was have something like

Time.local(date, hour, minute)

I did a little homework, looking through documentation, searching around, asking around, but there didn’t seem to be anything like this in Ruby. It surprised me, and when I realized even Facets didn’t have it I felt kind of worried and dirty. Was I heading into the dark side where even Trans dared not tread?

I cast my worries aside and pushed on, knowing what I wanted and that it’d be fairly easy to create. Really, the longest and hardest work came in doing research to see if there was already a wheel out there I was going to reinvent, and after that I had to think of a name.

So I give you timely. I already did this once today, so here I’ll just paste a section of the README.

require 'timely'

some_date = Date.today - 5      # => 2008-05-03
some_date.at_time(3, 5, 13)     # => Sat May 03 03:05:13 -0500 2008

# arguments are optional
some_date.at_time(13)           # => Sat May 03 13:00:00 -0500 2008

some_time = Time.now - 345678   # => Sun May 04 13:40:22 -0500 2008
some_time.on_date(2001, 6, 18)  # => Mon Jun 18 13:40:22 -0500 2001

# if you have objects corresponding to the times/dates you want
some_time.on_date(some_date)    # => Sat May 03 13:40:22 -0500 2008
some_date.at_time(some_time)    # => Sat May 03 13:40:22 -0500 2008

# if you like typing less
some_time.on(some_date)         # => Sat May 03 13:40:22 -0500 2008
some_date.at(some_time)         # => Sat May 03 13:40:22 -0500 2008

Obligatory github link: http://github.com/flogic/timely/tree/master
Obligatory tracking link: http://tasks.ogconsultin.gs/projects/show/timely

git + bash + awk = crazy delicious*

May 5th, 2008 by vinbarnes 4 comments »

This is mainly for the benefit of Wilkes. I'm sure there are better ways, but here's what I have in my bash profile for knowing when your git branch is dirty.

function git_current_branch {
        git branch 2>/dev/null | awk '/^\* /{print " on " $2}'
}

function git_dirty {
        git st 2>/dev/null | wc -l | awk '{if ($1 > 2) print "*"}'
}

export PS1="[\u@\h:\W\$(git_current_branch)\$(git_dirty)]$ "

I've noticed a problem in one or two cases where it advertises The Dirty but nothing really is. But those cases are so rare that I ignore them. I think I remember some people talking about coloring the output as well. I like it simple so I'll stick with this, but if there are better ways then show me the way -- I may take the leap.