Archive for the 'Ruby' Category

I saw Archive Flagged Items from NetNewsWire into Yojimbo (via) and found it a really neat tool. I've started using it to keep a more permanent record of interesting new articles.

I have lots of news articles flagged and I've had the import crash on me before for various reasons which has resulted in some duplicate web archives being created. The reason for the duplicates is usually because there was a redirect to the actual article that Yojimbo followed, so the URL in NetNewsWire doesn't match the Yojimbo URL and checking for existing items on load doesn't work.

This was a great opportunity for me to explore RubyOSA and continue learning Ruby so I wrote a script to detect duplicate web archives based on name and mark them with a "Duplicate" label.

RUBY:
  1. #!/usr/local/bin/ruby
  2.  
  3. require 'rubygems'
  4. require 'rbosa'
  5.  
  6. yojimbo = OSA.app('Yojimbo')
  7.  
  8. seen = Hash.new(false)
  9.  
  10. # Duplicate label details
  11. duplicateLabelName = 'Duplicate'
  12. # An almost painful red
  13. duplicateLabelColor = [65535, 1536, 4628]
  14. duplicateLabel = nil
  15.  
  16. # See if we already have a label named 'Duplicate' and save it
  17. yojimbo.labels.map  { |l| l.name == duplicateLabelName && duplicateLabel = l }
  18.  
  19. # Make a label if we don't have it already
  20. if (duplicateLabel.nil?)
  21.   duplicateLabel = yojimbo.make(OSA::Yojimbo::Label,
  22.                                 nil,
  23.                                 :color => duplicateLabelColor,
  24.                                 :name => duplicateLabelName)
  25. end
  26.  
  27. yojimbo.web_archive_items.each do |f|
  28.   if (seen.include?(f.name))
  29.     puts "Found a duplicate: #{f.name}"
  30.     f.label= duplicateLabel
  31.     seen[f.name].label= duplicateLabel
  32.   else
  33.     seen[f.name] = f
  34.   end
  35. end

I'm working on a Rails app using RJS and Prototype Window Class. I needed to be able to return an anonymous JavaScript function in my RJS template but when passing it in a string to page.call it kept getting quoted and didn't work right (as you would expect).

I solved it by creating a JavaScriptFunction class and helpers so that it's easily usable in an RJS template. Browse the plugin or install it:

# With subversion
./script/plugin install -x http://svn.vanderbrew.com/svn/repos/plugins/javascript_function/

# Without subversion
./script/plugin install http://svn.vanderbrew.com/svn/repos/plugins/javascript_function/

To use it, just do:

page.call 'Dialog.confirm', "New Thing - do you want to add it?",
            { :windowParameters => { :width => 300 },
              :sokLabel => 'Yes',
              :cancelLabel => 'No',
              :buttonClass => 'myButtonClass',
              :id => 'myDialogId',
              :cancel => anonymous_javascript_function(:parameters => ["win"],
                         :body => "$('#{@element_id}').innerHTML = '#{escape_javascript @thing.name}'"),
              :sok => anonymous_javascript_function(:parameters => ["win"],
                         :body => "return true;")
            }

It's my first plugin so I'm open to any feedback you have about it. Please use the Contact form to reach me.

Note - the keys :sokLabel and :sok shouldn't have an 's' in the front for real implementation with the JS library - I did that to prevent an emoticon from appearing thanks to WordPress.

I've spent a fair chunk of time this morning trying to get my functional tests on my rails app working with the login component. Here's the result of my time, presented in the hopes that it will help someone else who's stuck on the same thing.

I'm using ModelSecurity for the user login component because I'd also like to use the model security bits. Since I've got a before_filter to verify a user is logged in in my controller, I need to log in the user before I can test anything. Logging in the user is easy, right - I just post to the login action of the user controller. Here it is, wrapped in a function because I'll have to call it multiple times:


  def login_Neo
    post :login, :user=>{:login=>users(:neo).login, :password=>NEO_PASSWORD}
  end

  def test_list
    login_Neo
    get :list
    assert_response :success
    assert_template 'list'
    assert_not_nil assigns(:recipes)
  end

Ok, I'm sure that I've got a problem because my controller doesn't have a login action, but I decided to run it and see what happens.

Expected response to be a <:success>, but was <302>

Yep, I'm being redirected to the user controller because of my before_filter.

Now, I know that I need to make it post to the user controller, not the recipedex controller. Much googling, reading and thinking later, I discover that the post method being used here is defined in ActionPack from Rails. And, once I dig up the source for that, I discovered that post simply uses the @controller instance variable.

Aha! One simple change and I'm on my way:


  def login_Neo
    controller_bak = @controller
    @controller = UserController.new
    post :login, :user=>{:login=>users(:neo).login, :password=>NEO_PASSWORD}
    @controller = controller_bak
  end

Now, it posts where I want it to, sets User.current as I expect and everything works!