Inspired by two posts _Why's 'so create' and GitHub's Start a Side Project I decided that I needed to do a quick side project. After our demo day we were taking the weekend easy and I had some extra time on Sunday. I decided that I should find a really quick project something I could really just do in one day. Since I was partly inspired by _why, I decided to take some time to learn Shoes.
"Shoes is a very informal graphics and windowing toolkit. It's for making regular old apps that run on Windows, Mac OS X and Linux. It's a blend of my favorite things from the Web, some Ruby style, and a sprinkling of cross-platform widgets."
I tried to think of a simple Shoes app that I could contribute to The Shoebox (a collection of Ruby Shoes apps). I saw a couple Shoe's Twitter apps, but didn't see any Shoes AIM apps. Since I knew a good AIM protocol library for Ruby existed (Net-Toc), I thought it would be a nice simple app.
I ran into a few problems with Shoes (getting it to work with Gems) and it seemed to have problems loading YAML files. Besides the mentioned problems it was a breeze to work with. I looked at a few different example apps from the Shoebox. I ended up using Gentle Reminder as a template of sorts for my app. So basically in couple hours on Sunday I read a bunch about Shoes, read the source code of a couple Shoes apps, and I created a very small but functional GUI for AIM. It was a great little side project that reminded me how much fun it can be to code little things once in awhile.
If you have a day off go try to write some code and contribute to one of your favorite projects. Or finally go learn a new library or framework that looks really cool and try to give something back to that community. Then write up a post and share your experience with others. The best way to learn is to go do something, quoting _why, "so create."
So I proudly present my tiny day project IMShoes.
# A small gui for basic AIM messaging
# Author:: Dan Mayer (mailto:dan<@t>devver.net)
# Site:: http://devver.net/blog
# Copyright:: Copyright (c) 2008 Dan Mayer
# License:: revised BSD license
# (http://www.opensource.org/licenses/bsd-license.php)
# Version:: 0.0.1 (AKA a "alpha it sucks" version)
# Thanks::
# Ian Henderson for creating TOC, _why for Shoes, and
# Oliver for Gentle Reminder which I used to learn (as my template).
#You need to install net-toc with gem install net-toc
#then copy toc.rb into shoes/contents/ruby/lib/net for this to work in shoes
require 'net/toc'
Shoes.app :title => "Shoes AIM",
:width => 370, :height => 560, :resizable => false do
#ADD your own user and password here, should allow you to do this via GUI
@user = 'urUser'
@password = 'urPass'
background green, :height => 40
caption "IM Shoes", :margin => 8, :stroke => white
stack :margin => 10, :margin_top => 10 do
para "Buddies", :stroke => red, :fill => yellow
stack :margin_left => 5, :width => 1.0, :height => 200 do
background white
border white, :strokewidth => 3
@gui_buddies = para
end
flow :margin_top => 10 do
para "To"
@send_to = edit_line(:margin_left => 10, :width => 180)
end
flow :margin_top => 10 do
para "Message"
@add = edit_line(:margin_left => 10, :width => 180)
button("Send", :margin_left => 5) do
send_msg(@send_to.text, @add.text);
@send_to.text = '';
@add.text = '';
end
end
end
stack :margin_top => 10 do
background darkgray
para strong('Messages'), :stroke => white
end
@gui_messages = stack :width => 1.0, :height => 207
def refresh_buddies
@buddies = []
@client.buddy_list.each_group { |g, b| @buddies = @buddies + b }
@gui_buddies.replace *(
@buddies.map { |buddy|
[ buddy.screen_name, ' ' ] +
[ link('Message') { set_to buddy.screen_name } ] +
[ ' ' ] + [ "\n" ]
}.flatten
)
end
def refresh
refresh_buddies
refresh_msgs
end
def refresh_msgs
@gui_messages.clear
@gui_messages.append do
background white
@messages.keys.sort.reverse.each { |day|
stack do
background lightgrey
para strong(day.strftime('%B %d, %Y')), :stroke => white
end
stack do
inscription *(
([@messages[day][0].to_s]+
[" "]+
[@messages[day][1].to_s]+
[" "]+
[link('Reply') { set_to(@messages[day][0].to_s) }]).flatten
)
end
}
end
end
def set_to(screen_name)
@send_to.text = screen_name;
refresh
end
def send_msg(to_name, msg)
msg = msg.strip
to_name = to_name.strip
return if msg == ''
return if to_name == ''
to_buddy = @client.buddy_list.buddy_named(to_name )
if to_buddy.available?
to_buddy.send_im(msg)
@messages[Time.now]=[to_name,msg]
end
refresh_msgs
end
def load
@client = Net::TOC.new(@user, @password)
@client.connect
sleep 3
@messages = {}
@buddies = []
@client.buddy_list.each_group { |g, b| @buddies = @buddies + b }
@client.on_im() do |message, buddy, auto_response|
@messages[Time.now]=[buddy.screen_name, message.gsub(/<\/?[^>]*>/, "")]
#buddy.send_im("#{message} responce")
refresh_msgs
end
refresh
end
load
end

