Categories
Ruby Web 2.0

Updating FaceBook status from Twitter

I’ve recently jumped on the Facebook bandwagon. I can’t be bothered to update two statuses (I rarely get round to it with one), so I was looking for a way to update my FaceBook status from Twitter. I installed the Twitter application in FaceBook, but that just displays the Twitter status separately.

It seemed that the only way to do it was to write a script to regularly check Twitter, and update FaceBook when it found a new Twitter message. I found a partial solution in PHP, but decided to roll my own in Ruby anyway.

It took a few hours longer than I expected (the documentation for Net::HTTP could be better), but I got there in the end. I now have the script below installed on my DreamHost account, and set to fire every minute via cron. It’s not the prettiest code I’ve ever written, but it does the job. Feel free to borrow it if you think it’ll be useful.

Andrew ‘Boz’ Bosworth
11:29pm September 6th

I’m an engineer at facebook and I’m writing to ask if you would be willing to take down the link to your facebook/twitter status sync utility (located on your website kerrybuckley.com). Based on your comment on TechCrunch I suspect you anticipated this would be coming at some point. Even if your intended use of such a script is noble (as I’m sure it is), the simple script you have posted on your site is (and has always been) against our terms of service. Said more shortly, we just can’t let people automate aginst our site outside of the platform; it’s a slippery slope.

We’d obviously like to resolve this without disabling your account or getting the lawyers involved if possible, so please let me know as soon as you’ve taken the script down so that our legal department doesn’t get all fired up about this.

thanks,
Andrew Bosworth
Facebook Engineer

My reply:

Andrew,

As you’ll probably expect, I’m not particularly impressed with Facebook’s current stance on openness in general, or on this issue in particular. I hope that at some point you add an API to allow remote updating of status, in the same way that you recently added an RSS feed to allow tracking of friends’ statuses.

For the record, I don’t believe that posting the script on an external site constitutes a violation of the terms of service, although I accept that using it would be. Also, when you say “we can’t just let people automate”, I assume you really mean “we won’t just let people automate”. This is a shame, as it goes against the grain of the Internet, and reinforces the impression that you’re trying to lock people into your site.

All that said, I don’t particularly want to be spending my time fending off writs and takedown notices, so the script no longer appears on my site (see http://www.kerrybuckley.com/2007/07/14/updating-facebook-status-from-twitter/).

Kerry

[tags]facebook, twitter, ruby, mashup[/tags]

Categories
Web 2.0

Cool “Web 2.0” introductory videos from the Common Craft Show

There are some great short videos on commoncraft.com explaining some Web 2.0 concepts for non-technical people. The lo-fi style is very clever, too.

So far they’ve done RSS, wikis and social networking (see below).

Categories
Rails

Correct use of the flash in Rails

[Update 9 May 2012]

This seems to work for testing flash.now in Rails 3:

it "puts an error in the flash" do
  post :create
  flash[:error].should == "Sorry, that's wrong."
end

it "does not persist the flash" do
  post :create
  flash.sweep
  flash[:error].should be_nil
end

[Update 20 April 2010]

I recently had problems testing flash.now, and Google kept leading me back to this post. Unfortunately it doesn’t seem to work with the current version of Rails (I’m using 2.3.5 at the moment).

This post from Pluit Solutions gives an alternative approach which seems to work. I haven’t tried it with Rails 3 though.


I don’t know whether this has caught anyone else out, or whether we just didn’t read the documentation properly (it’s covered briefly on p153 of AWDwR), but I thought I’d mention it anyway.

Anyone who’s written a Rails app will know that the ‘flash’ is used to store error and status messages, usually on form submissions. Model validation failure messages automatically get copied into the flash, but you often want to do it manually too.

flash[:notice] = "User Details updated."
redirect_to edit_user_path(@user)

The gotcha comes when you want to display a message and render a page, as opposed to redirecting – for example when errors are preventing a form from being submitted. This is how not to do it:

flash[:error] = "Password doesn't match confirmation." # WRONG!
render :action => 'change_password'

The problem is that the flash is stored for the next request. Because we’re no longer doing a redirect, that means the message may appear wherever the user goes next, not just on the page that we just rendered. To avoid this, use flash.now, which is only used for the current request:

flash.now[:error] = "Password doesn't match confirmation."
render :action => 'change_password'

The rule of thumb is to use flash if you’re redirecting, and flash.now if you’re rendering (either explicitly, or by dropping through to the default view for the action).

All very well, but whatever you put in flash.now is cleared out at the end of the request, so how do you test it? The answer (for RSpec, at least) lies in a comment on this RSpec feature request – basically just add the following to spec_helper.rb:

module ActionController
  module Flash
    class FlashHash 
      def initialize
        @hash = {}
        @now_hash = {}
      end
    
      def [](key)
        @hash[key]
      end
    
      def []=(key, obj)
        @hash[key] = obj
      end
    
      def discard(k = nil)
        initialize
      end
    
      def now
        @now_hash
      end
    
      def update(hash)
        @hash.update(hash)
      end
      
      def sweep
        # do nothing
      end
    end
  end
end

You can now do something like this:

describe "When a user tries to change his password with an invalid verification code" do
  ...

  it "should put an error message in the flash" do
    flash.now[:error].should == "Incorrect verification code or password."
  end
  
  it "should not persist the flash" do
    flash[:error].should be_nil
  end
end

[tags]Ruby,Rails,flash,RSpec[/tags]

Categories
General nonsense

Putting Things Off

As I come to the end of a week off work, with a list of things that need doing around the house that’s little changed since the beginning of the week, it strikes me that it’s about time us procrastinators had our own system. With that in mind, I present the following (with apologies to David Allen).

The Putting Things Off System

The main principles of Putting Things Off can be summarised in four steps:

Collect

Every time you come across something you need to do, put it into a ‘bucket’ (an e-mail folder, a drawer in an old filing cabinet you never look in, or perhaps an actual bucket). Once you get all the things you need to remember out of your head, it’s easier to forget about them.

Once a bucket gets full, move it out of sight somewhere and start a new one. Don’t make the mistake of looking in the buckets – it’ll just be depressing.

Process

When faced with a list of things that need doing, just pick a few at random and try to get rid of them using one of the following strategies:

Two-minute rule

If something looks like it would only take a couple of minutes, you can do it any time, so forget it for now. Don’t distract yourself by trying to do it straight away.

Delegate

Can you think of someone else to blame for the task not getting done? If so, you’re in the clear. Don’t remind them though, otherwise they might remove the obstacle, and with it your excuse for inaction.

Defer

Deferring things is just a more positive way of saying procrastination, so this is a good plan if no other excuse presents itself.

Organise

Organise all your tasks into projects, and allocate a ‘next task’ for each. That way you can ignore all but one item in each project, leaving far fewer things to think of reasons to avoid.

Organising by context can also be a helpful source of excuses. For example, a context might be ‘things I can’t do at home’ or ‘things I can’t do if it’s raining’.

Review

Review all your lists occasionally, to see whether you’ve ignored anything for so long that it’s gone away. One useful technique is the well-known ’43 folders’ – if you split stuff up across that many places, it’s far easier to forget about.

Do[n’t]

Finally, all this hard work will be to no avail if you still end up doing things. If all else fails, remember the words of the Grange Hill cast, and just say no.

[tags]GTD[/tags]

Categories
Agile

The simplest thing that could possibly work

But other times we’d be programming away, and we’d say, “Now, wait a second, what are we working on here?” We’d just get stuck. And if we were stuck more than a minute, I’d stop and say, “Kent, what’s the simplest thing that could possibly work?”
Ward Cunningham

Not a command: “Do the simplest thing that could possibly work!”, but a question: “What’s the simplest thing that could possibly work?”.

Once you think of something really simple that might work, think for a minute – is there an obvious reason why it definitely won’t? If not, try it, and then you’ll know. More importantly, if it didn’t, you’ll know exactly why not. Maybe it was functionally correct, but not fit for purpose – perhaps an algorithm was too slow, or an interface was too confusing or ugly to release to users. The point is, you’ve either got something you can build on, or you’ve got a concrete reason to abandon an idea, rather than a theoretical argument. If you’re lucky, it’ll turn out that the simplest thing did work, and the problem’s solved.

Too often people seem to twist this into some kind of XP Prime Directive, claiming that a particular solution is over-engineered because it wasn’t TSTTCPW. On the other side of the fence, big-picture architect types use it as a straw man to criticise agile methodologies, claiming that they ignore anything that isn’t part of TSTTCPW, leading to simplistic and unscalable solutions.

As Einstein said, “Everything should be made as simple as possible, but no simpler.”

[tags]XP, simplicity, Ward Cunningham[/tags]

Categories
Agile Software

Hoist by my own petard, part two

You’d think I’d have learned my lesson, but apparently not. While the build was finally underway last night, I noticed that my search box made the layout a bit odd when you were logged in, so moved the sign out and edit profile links alongside “Welcome your name” instead of underneath. While I was there, I recklessly changed it to “Welcome, your name” (with a comma). This time it couldn’t possibly break anything, so I checked it in and went home.

Yes, you guessed it.

sign_in 'fred', 'secret'
then_the_protocol_should_be_http
verify_text_present 'Welcome Fred Bloggs'

The really embarassing thing is the checkin comment though.

portal build 565 FAILED
finished at 8:10 AM on 21 June 2007 taking 4 minutes and 34 seconds

Build Changeset
Revision 565 committed by 802285285 on 2007-06-20 16:57:34
Move welcome message to same line as sign out/edit profile, to make room for search. This one will *not* break the build...
M /trunk/app/views/layouts/global.rhtml

Categories
Agile Software

Hoist by my own petard

So, this morning we had our iteration retrospective, and one of the things I brought up under “what should we do differently?” was that we seemed to be breaking the build a lot. We’d got out of the habit of always running the acceptance tests before committing even minor changes, and the build often stayed red for an hour or two while the culprit figured out what had gone wrong and fixed it. We all agreed to take more care in future.

Then this afternoon, I checked in a tiny change, affecting one RHTML file and a CSS stylesheet, just to add a search box to the top of the page layout. No code involved – what could possibly go wrong?

Oops.

Build failure

That’s two thirds of our acceptance test cases failing.

Turns out we had a lot of brittle acceptance tests, which relied on just submitting the first (and only) form in the page. Two-and-a-half hours and 37 modified files later (and long after I’d intended to go home) I’d added IDs to all the submit buttons and fixed the Selenium files to click them explicitly.

That’ll teach me.

Categories
Software

Multiple class attributes in HTML

Here’s a great tip courtesy of Trenton Moss’s Ten CSS tricks you may not know. I certainly didn’t know it, but it’s quite possible everyone else does and this post is going to make me look like an idiot. I can take it.

How many times have you ended up doing something like this?


...



Did you know that you can specify multiple classes on one element, just by separating them with spaces?


...



[tags]html,css,class[/tags]

Categories
Agile BT Ruby Software

A step-by-step BDD example using RSpec

We’ve now got a Ruby focus group at work, and one of the first things to be set up has been a weekly programming exercise [intranet link], in the style of Ruby Quiz. It’s now week two, and the problem is slightly more complex than last week’s gentle FizzBuzz introduction. Here’s the specification:

This time, the challenge is to come up with some Ruby code that converts a positive integer to its English language
equivalent. For example:

1 => one

10 => ten

123 => one hundred and twenty three

10,456 => ten thousand four hundred and fifty six

1,234,123 => one million two hundred thirty four thousand one hundred and twenty three

The code should work from numbers 1 – 10,000,000,000 (ten billion) but if it works for bigger numbers its all good.

For an extra challenge, when the strings for the numbers for 1 – 10,000,000,000 are sorted alphabetically, which is the
first odd number in the list?

I thought it might be interesting (to me, at least!) to record the process I go through to reach the solution, rather than just sharing the finished article. I’m using a behaviour-driven approach, although the process for writing a single method obviously doesn’t touch on a lot of the wider aspects of BDD.

So here it is, warts and all (I’m writing this as I go along, so I have no idea how long this post is going to get, or whether I’ll even arrive at a solution at all!)

Categories
General nonsense

Some people have too much time on their hands

I don’t know whether there’s any camera trickery involved, but this video is pretty cool. Kind of like a DIY version of Honda’s famous Cog advert.