MetaSkills.net

How To Clean A Campfire Room Of Uploads

Posted On: August 19th, 2010 by kencollins

For us at work, our uploads to campfire are really transitory. Most of the time they are simple screenshots around a current topic. Every now and then vacation photos or even movies. And the end of the day none of it has value to us as the real value of campfire is our textual transcripts.

This morning after 4 years of campfire, we were real close to our 1GB limit of uploads. Time for a clean up. I found no easy way of automating this, so I turned to the Tinder gem. It has a nice way interface to the campfire api using HTTParty as the backend. I found out that there was no easy way to delete uploads too. So after some good ole fashion DOM inspection and knowing rails application conventions, I found my own interface. Below is a little script I used to clean up our room this morning. It basically loops thru a rooms uploads, 5 at a time, and deletes them. Pausing for a quarter of a second between each so I don't freak out the new 37signals administrator :)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45

require 'rubygems'
require 'tinder'

class CampfireUploadCleaner
  
  CF_DOMAIN = 'mydomain'
  CF_ROOM   = 'My Room Name'
  CF_TOKEN  = ENV['MY_CF_TOKEN']
  
  def initialize
    @campfire = Tinder::Campfire.new CF_DOMAIN, :token => CF_TOKEN
  end
  
  def room
    @room ||= @campfire.find_room_by_name(CF_ROOM)
  end
  
  def connection
    room.send(:connection)
  end
  
  def delete_uploads
    uploads = room.send(:get,:uploads)['uploads']
    uploads.each do |upload|
      id = upload['id']
      name = upload['name']
      connection.post "/uploads/delete/#{id}?n=0"
      puts "Deleted: [#{id}] #{name}"
      sleep(0.25)
    end
  end
  
  def sweep_uploads
    while room.files.present?
      delete_uploads
    end
  end
  
end

cleaner = CampfireUploadCleaner.new

cleaner.delete_uploads  # => Deletes the top 5 uploads.
cleaner.sweep_uploads   # => Deletes all uploads.

The upload hash actually contains much more than just the id and name of the upload. There is a timestamp, filetype and other attributes. So if you wanted to extend this script, you could. I did not spent a lot of time with it, but I never figured out how to get more than the top 5 uploads too. I'm sure some param hacking would yield some good results.

Tags: ruby, campfire, tinder

Protip: Exclude Your RVM Install From Time Machine Backups

Posted On: August 6th, 2010 by kencollins

You may not realize it, but that ~/.rvm directory is getting big and may be hurting your Time Machine backups. Especially if you are doing a lot of development. I just checked mine today.

du -skh ~/.rvm/gems
1012M	/Users/kencollins/.rvm/gems

Ouch! That's around 1gig of stuff that is pointless to backup just in the gems directory. I frequently blow away certain rubies and install them again using various rake tasks and just found out today that you have to pass the --gems option to rvm remove to clean those old gemsets out. Either way, that whole rvm directory can just be ignored from Time Machine backups. Here is how, there is really only one tricky part.

First, open up your System Preferences, then open up the Time Machine pref pane. From here click on the "Options...". Within this window you will be able to add a folder to be excluded from backup. Hit the "+" button to add a directory. Now here is the tricky part, your rvm directory is prefixed with a period and hence is invisible to the normal finder windows. Thankfully all Mac file windows can use a keyboard shortcut. Hit Command+Shift G. That will blind down a "Go to the folder:" window. Simply type in ~/.rvm here and hit "Go". Now choose "Exclude" from the main file window. Your done!

A MacPort/RubyODBC Update

Posted On: July 18th, 2010 by kencollins

Quite a while ago I wrote a soup to nuts article on getting the full multi-ruby development stack installed for those using the SQL Server adapter. The base package management system used there was MacPorts. In it I described how to edit the outdated Portfile for the rb-odbc package and exclaimed how important it was to use the +utf8 variant. I was totally wrong about that part.

Tags: ruby, macports, odbc

Bit Fat Legacy Schema Inspection

Posted On: July 7th, 2010 by kencollins

Sometime in rails 2.x the #inspect method for an ActiveRecord class was changed to show you all the column names (attributes) of that class. This is fine when things are small but if your working on a big legacy schema and you want clean terse debugging, all those column names can be noisy. I just set this initializer up today to kill it. Now the class just shows the number of columns.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

module ActiveRecord
  class Base
    class << self
      
      def inspect
        if self == Base
          super
        elsif abstract_class?
          "#{super}(abstract)"
        elsif table_exists?
          "#{super}(#{columns.count} columns)"
        else
          "#{super}(Table doesn't exist)"
        end
      end
      
    end
  end
end

Custom Webrat::Session formatted_error For Rails With Nokogiri

Posted On: July 6th, 2010 by kencollins

I never liked how Webrat shows the complete response body for exceptions when integration testing rails applications. For the longest time I redefined the formatted_error method to simple do nothing. Today I used Nokogiri to parse out the good bits from that page. Here is the result. Not pretty, but it's working fine so far. Got a better example? Please share!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

module Webrat
  class Session
    def formatted_error
      doc = Nokogiri::HTML(response_body)
      exception_name = doc.css('head title').inner_html.squish
      exception_msg = doc.css('body h1').inner_html.squish
      exception_detail1 = "".tap do |detail|
        d = doc.css('body p')[0]
        detail << d.content.strip
        detail << d.next_sibling.content.squish
      end
      exception_detail2 = "".tap do |detail|
        d = doc.css('body p')[1]
        detail << d.content.strip
        detail << d.next_sibling.css('code').first.content.strip
      end
      app_trace = doc.css('#Application-Trace pre code').inner_html
      [exception_name, exception_msg, exception_detail1, exception_detail2, app_trace].join("\n")
    rescue
      "Could not format page exception. Perhaps try to use Nokogiri on this: \n#{response_body}"
    end
  end
end
Tags: ruby, rails, bdd, webrat

Synchronizing Core Data With Rails (3.0.0.pre)

Posted On: February 11th, 2010 by kencollins

This is my presentation to our local @757rb/@757objc users group this past Tuesday. Hope some find it useful. Lessons learned from building HomeMarks native iPhone application to synchronize Core Data with a RESTful backend built using rails 3.0.0.pre. This covers a previous design methodology called the AJAX head pattern which decouples rails applications from the views they present which allowed an easy API foundation for the iPhone application and data sync methods.

Resources

Rails Button Links In Embedded Forms

Posted On: January 5th, 2010 by kencollins

This is one I have had sitting around for almost 3 years now in my toolbox and thought I would share. Have you ever had complicated rails forms and needed simple form buttons that just took you to a simple link? Were you bitten by the button_to helper code because it generates another form inside of a form? If so, here is a simple rails view helper I made that creates simple button links for embedded forms by making an input with a javascript function. Tag soup you ask, hell yeah, but worth if if you need it.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

def button_to_link(name, link, options={})
  confirm_option = options.delete(:confirm)
  popup_option = options.delete(:popup)
  link_function = popup_option ? redirect_function(link,:new_window => true) : redirect_function(link)
  link_function = "if (confirm('#{escape_javascript(confirm_option)}')) { #{link_function}; }" if confirm_option
  button_to_function name, link_function, options
end

def redirect_function(location, options={})
  location = location.is_a?(String) ? location : url_for(location)
  if options[:new_window]
    %|window.open('#{location}')|
  else
    %|{window.location.href='#{location}'}|
  end
end
Tags: ruby, rails, form