26 Jan 2012, 12:12pm
/dev/random
by

leave a comment

Paying vs. Pirating

Over in the Ottawa Citizen, Kate Heartfield writes in “Please, let me pay for that movie”, a poignant op-ed piece, that quite a lot of people who might be inclined to pirate content would really rather pay for it. I concur.

As they say, “the plural of anecdote is not data”, so take this for what you will, but here’s a small illustration from my perspective:

The other night my girlfriend and I were browsing on iTunes for a movie to watch. Rather flippantly she mentioned she’d never seen 300 before. This, to me, is unthinkable. 300 is an awesome film, faithful to the graphic novel, beautifully shot, and thoroughly enjoyable.

I actually own 300. The very DVD was sitting on a shelf in the other room, not five meters away, probably unwatched since the day I bought it.

“Get the DVD”, I thought as I started to rise from the couch. But then it occurred to me: watching that plastic platter would mean turning on the Xbox, switching the TV context, sitting through all the anti-piracy crap and ads at the beginning of it and, perhaps least-appealing of all, actually getting off the couch to go fetch the thing itself. The DVD was in another room, nowhere near the kitchen or bathroom. It would be a journey of singular utility, marginal utility.

I sat back, I clicked “Purchase” in iTunes, we started watching it immediately. And it was good.

Some might infer from this tale that I’m so lazy I’ll pay for something I already own instead of exerting additional effort. They would be correct, but that’s beside the point so let’s just… nothing to see there, move along. My real point is this: when payment is the easiest, most friction-free approach to acquisition, payment is often the preferred approach. During the day I trade my time and knowledge for money, and at night I’ll happily trade my money for convenience and entertainment.

Finding pirated content is a pain in the ass. Downloading torrents is a pain in the ass. Re-encoding the resulting MKV or AVI files for iTunes is a pain in the ass. Compared to iTunes and Netflix, piracy in general is a pain the ass. But piracy is often less a pain in the ass than almost every other form of legitimate entertainment purchase. To wit: I don’t think I know anyone who still buys DVDs, simply because they’re so encumbered with bullshit, restrictions, ads and threats that it’s just not worth the bother.

Apple, Netflix, and Y Combinator have figured it out, this is very obvious. The MPAA and entertainment industry, they have not. Here’s hoping one subsumes the other, and quickly.


When a man’s paycheck depends on his not understanding something, you can depend upon his not understanding it. – Upton Sinclair

23 Jan 2012, 1:44pm
/dev/random
by

leave a comment

Blocking Facebook

While I do have a Facebook account (because it’s damned near impossible to delete one; it certainly isn’t possible via the Facebook site itself), for the most part I try to run invisible to Facebook. This is not as easy as it seems so below is my process for doing so.

I make no claims that this is bulletproof; if you have better suggestions, please share.

First, I installed the FacebookBlocker blocker browser extension. It seems to work well.

Then I installed the Ghostery browser plugin. Where FacebookBlocker is a scalpel, Ghostery is a big, heavy club… and every website is a juicy watermelon. I like Ghostery.

Perhaps most dramatically I’ve added the following to my /etc/hosts file:

# Kill all the facebook
127.0.0.1 static.ak.fbcdn.net
127.0.0.1 www.facebook.com
127.0.0.1 facebook.com
127.0.0.1 www.static.ak.fbcdn.net
127.0.0.1 login.facebook.com
127.0.0.1 www.login.facebook.com
127.0.0.1 fbcdn.net
127.0.0.1 www.fbcdn.net
127.0.0.1 fbcdn.com
127.0.0.1 www.fbcdn.com
127.0.0.1 static.ak.connect.facebook.com
127.0.0.1 www.static.ak.connect.facebook.com
127.0.0.1 m.facebook.com
127.0.0.1 touch.facebook.com
127.0.0.1 connect.facebook.net
127.0.0.1 api-read.facebook.com

It effectively routes all HTTP calls to Facebook-owned domains that I’m aware of to localhost, which means Facebook content doesn’t even get loaded.

It has the added effect of making Facebook hard to get to for me, personally. If I want to browse Facebook via a browser on my laptop then I have to actively launch the terminal, comment out those lines, and then reload the site. That’s usually enough of a PITA to curb any incentive I might have had to go visit.

Finally, I’ve deleted Facebook’s apps off of all my devices except one. And it’s very slow on that one.

Net result: I go onto Facebook perhaps once a week and whenever I see the Facebook sharing icon on another website, it’s always one hosted locally to that site instead of being served from Facebook’s CDN.

22 Nov 2011, 12:01pm
/dev/random /dev/ruby
by

leave a comment

Stubbing Geocode with FactoryGirl

Google doesn’t seem to like it when our geocoded models hammer their geocoding API during our test runs so we should stub out the geocoding call. To do so:

FactoryGirl.define do
  factory :place do
    name         { Randgen.name }
    kind         'city'
    timezone     'Mountain Time (US & Canada)'
    enabled      true

    after_build  { |place| place.stub!( :geocode ).and_return( [1,1] ) }
    after_create { |place| place.stub!( :geocode ).and_return( [1,1] ) }
  end
end
7 Jul 2011, 9:18am
/dev/random
by

leave a comment

Measuring Slow Code in Objective-C

A note to myself, because I can never remember how to do this:

    NSTimeInterval start = [NSDate timeIntervalSinceReferenceDate];
    ...operation here...
    NSTimeInterval duration = [NSDate timeIntervalSinceReferenceDate] - start;
    NSLog( @"%f", duration  );
1 Jul 2011, 4:06am
/dev/random
by

leave a comment

Living Code

Long, long ago I posted Better Range Intersection in Ruby, which was Dan’s improved solution to my solution for finding intersections across date ranges.

Two years and 3,100 pageviews later, Montgomery Kosma came across that post, found a bug in it, provided a solution and immediately improved it’s quality. I love it when that happens!

2 Jun 2011, 9:54am
/dev/random
by

1 comment

Rake :needs deprecated

Recently I updated rake on a project and was met with this warning:

WARNING: ‘task :t, arg, :needs => [deps]‘ is deprecated. Please use ‘task :t, [args] => [deps]‘ instead.

It wasn’t immediately obvious to me what exactly the needed change was, and much googling didn’t reveal anything helpful. However blind poking about did. Turns out it means one should change this:

task :staging, :post, :needs => :environment do |t, args|

to this:

task :staging, [:post] => :environment do |t, args|

18 May 2011, 1:53pm
/dev/random
by

1 comment

Menuito: Fixing Broken Sites One Restaurant at a Time

This week a good friend launched Menuito, his company aimed specifically at helping restaurants improve their websites for mobile users. Menuito is pretty damned clever. It effectively routes around the issues most restaurant websites have on mobile devices by providing a completely separate, customizable site to mobile users. And it does so with almost no technical changes to the restaurant’s existing website and servers.

Everyone knows restaurant websites are pretty terrible. Sites like Never Said About Restaurant Websites skewers the industry one soundbite at a time. And they’re easy targets, restaurants are, because it seems so obvious: if you serve the public, and you’re heavily dependent on the public’s personal preferences and ability to find you, you should make critical information as easy as possible to access. But those sites don’t; they employ Flash and PDFs and annoying background music and all the other things that seemed like such a great idea fifteen ten five years ago when the restaurant had it’s brand-new website built by someone who really just sold them a line. Someone who told them they’d be getting something beautiful but instead stuck them with a proprietary, heavy-weight, gimmick-laden turd.

I suspect if you ask restauranteurs about their websites, owners of the types of sites we’re talking about here, very few are happy. They’re not stupid, they know people need to find them, and their hours, and their menu, and can’t. But they’re restauranteurs, not geeks. For them the solution is not simply a technical one but rather one of time and money, of effort and energy, all the things most restauranteurs don’t have an abundance of. And at the end of the day they have no guarantee they won’t simply get burned again.

That’s why Menuito is so beautiful. Menuito effectively says to the restauranteur:

Let’s solve one problem at a time. Your existing site is good enough for people at their computers so let’s just leave that as-is. Instead, we’ll tweak things so that it also works for people on smart phones. And we’ll make that particular user experience perfect.

One just needs to look at Menuito’s demo.menuito.com demo site to see how effective this can be (and do be sure to look at it in both a computer browser and a mobile browser; it’s attention to detail like that that really set the folks who built Menuito apart).

Here’s hoping Menuito catches on because as it stands now, too many restaurants are nigh impossible to use on mobile devices.

16 May 2011, 5:00pm
/dev/random
by

leave a comment

Raw SQL queries and Rails

For some crazy reason you find yourself thinking “it’d be really great right now if I could just run some raw SQL queries against my database in this here Rails app”, but how?

The saner amongst us would simply find a better way to do things but for those times when sanity is not an option*, there’s this stuff, and it works like so:

result = ActiveRecord::Base.connection.select_all( “SELECT * FROM authors_books WHERE 1″ )

In that particular case it returns a hash containing the results of each row in the table. Pure, unadulterated query goodness, no extra filler.

(*like when you’re exporting a join table from MySQL to Sqlite without the weight of the instances it denotes. Oh yeah.)

15 May 2011, 10:05pm
/dev/random
by

leave a comment

Rails, Devise, and InvalidHash

You’re using Rails, you upgrade Devise and suddenly it all stops working with an InvalidHash error. Chances are you just got bit by a change to the default crypto algo. The solution, from Stack Overflow:

1) Remove config.encryptor from your initializer;
2) Add t.encryptable to your old migrations;
3) [Optional] Remove password_salt in a new recent migration. Bcrypt does not require it anymore.

Though in my experience the removal of the password_salt field is not optional since old Devise made it null=false.

2 Apr 2011, 4:10pm
/dev/random:
by

leave a comment

str_2_hex.rb

I was playing around with an interface experiment and wanted to convert arbitrary strings into hex codes for displaying colours in a webpage. I just ported the JS code from this Stack Overflow solution to Ruby, now hosted on Github: str_2_hex.rb. Might be useful to someone else.