• My Day Project: IMShoes

    by Dan

    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



    Screenshot:

    IM Shoes Screenshot

    Devver Caliper: Hosted metric_fu for your Ruby project.
    Get set up in under a minute

    Posted on August 29th, 2008 by Dan in Development, Hacking, Ruby.