Efficiently finding large (size and dimension) images

I needed to efficiently find large images (those with dimensions greater than x). Here’s what I came up with:

First, find images whose file size is greater than 3M:

find . -name '*jpg' -size 3M > /tmp/big-receipts.txt

Now, get the dimensions of each of those images using imagemagick’s identify command line utility. The key to using this thing efficiently is to include the “-ping” flag (believe it or not that took me quite a while to figure out):

identify -ping filename.jpg

displays this type of output:

/tmp/big.jpg JPEG 10200x13200 10200x13200+0+0 8-bit DirectClass 5.54MB 0.000u 0:00.000

Now we can put the two together:

for fname in `cat /tmp/big-receipts.txt`; do identify -ping $fname; done

Hands On With the BlackBerry Playbook: Actually Quite Nice

Over the weekend I attended the Blackberry hackathon with the hopes of creating an Xpenser blackberry app. The RIM folks were nice enough to give away a Playbook to everyone who presented, so I ended up with one.

Blackberry Playbook

I was skeptical, to say the least. I expected a sluggish, ugly interface with a dearth of applications.

What I got is quite nice. The blackberry has a very usable interface – it’s fast and responsive, and some of the gestures (eg. closing and switching apps) are the best I’ve seen on a tablet.

It comes with a nice car racing game (I surprised myself by spending a few hours playing it), and the browser is quite excellent, probably the best I’ve seen on a tablet.

The development environment is also rich: you can use HTML or flash as well as native SDKs.

It doesn’t seem to come with a built-in email app (or if it does I’ve missed it), which is very surprising given the Blackberry pedigree.

It’s also lacking apps and games – the app world feels a bit empty.

I’m surprised at how much I like the device. I just wish it had more apps.

SFTP: Specifying Port, SSH key

This page is helpful.

Specifying port:


sftp  -v -oPort=6636 -o IdentityFile=keys/my-key.ssh [email protected]

Student Loans Are Killing Entrepreneurship

If you know me you know I’m a huge fan of entrepreneurship – instead of renting yourself out to someone else, start a business that scales. Be your own pimp.

I gave a guest lecture at UCSD recently espousing this viewpoint. You are cheap right now, I told them, so take advantage. If you wait 10 years to start a company you’ll have much higher earning power and much higher personal costs (spouse, mortgage, …) and therefore a much higher opportunity cost when starting a company.

What about our student loans? asked one of the students.

Good question. I don’t have a good answer.

When I went to school I was able to pay my way from the third year onward. I left school with savings instead of debt. I was able to start a company immediately.

Today students graduate with an average debt of about $27,000 dollars.

That’s just awful. That means they are bound to a job for at least the first part of their career. We’re removing the option of starting a company, of producing explosive value, of growing the economy to the benefit of the whole country, for more than 60% of our graduates.

Think of all of the companies with billions in value created by college students. Think Facebook, Dropbox. We need these. We want these created in the US.

We have to get education costs under control. We can screw the young generation over to put a few extra bucks in our pockets now, but we’ll all end up paying for it when we fall behind other countries who encourage their creative young to be entrepreneurs.

How To Dynamically Import Python Modules

Here’s how you import a python module dynamically: say your module is called “mysettings” and it’s in the directory “config”. Make sure you have a __init__.py in your “config” directory and use:


mysettings = __import__("config.mysettings", fromlist=["config"])

This is equivalent to


from config import mysetings

How To Scan Multiple Pages Into a Single PDF on OS X

My new printer has a document feeder which makes scanning of multiple pages easy, but I didn’t know how to kick off the scan on OS X. Turns out it’s quite easy:

  • Open the OS X Preview app
  • Go to the File menu and select Import From Scanner
  • Select your printer
  • Look for the “Format” option on the right hand page and set it to PDF
  • Select the “Create single document” option
  • Hit the Scan button

This will produce a single PDF file with all of the pages of your document, scanned into the location of your choice.

Titanium Studio: How To View Android Log Messages

Apparently with Titanium Studio it’s not possible to see log messages in the Titanium console.

Here’s how you see your log messages:

adb logcat | grep "TiAPI"

adb is in the tools directory of your Android sdk.

Easy way to view cookies in Chrome

Here’s an easy way to see the cookies for the current site in Chrome:


javascript:void(document.cookie=prompt(document.cookie,document.cookie));

Via stackoveflow.

Django: Checking If A User Is In A Group

Adding to my earlier post on the django permission system:

You can check if a user is part of a group using this simple snippet. It will allow you to check if a user is in a group with the following template syntax:


{% if user|in_group:"Friends,Enemies" %}

Uniforms

I went to a school that required uniforms (private school in England). We were forced to be uniform.

This afternoon driving by the high school near my house I was amused to see uniforms everywhere – here a patch of girls all wearing the same types of shorts, with hair pulled back, there a group of emo kids all wearing shades of near identical clothes.

It’s lovely. We all need to be different in our uniform ways.

Future of Work and New Dial Tones

My friend Paul Kedrosky’s post on one of his main investment theses, the application of currently consumer oriented technologies to business (DropBox, Twitter, FaceBook, Yelp, …), got me thinking about how the future of work will look.

I’ve made a career of working far from where I live. I’ve generally considered this a significant pain – there are disadvantages and inefficiencies in being geographically separated from coworkers. Hence I’ve endured horrible commutes and frequent travel.

Lately, however, I’ve been reconsidering. My office is about 30 minutes from my house, but I end up not going in more and more these days. The 1 hour roundtrip is simply wasted time, and the traditional 9-5 is an artificial constraint on both work and non-work activities.

The turning point, not surprisingly, was technology driven – earlier this year I was working on a shared presentation and document with 2 colleagues. We met in person twice, and the third time we used Google Wave (rip) for shared document editing and iChat for voice and video communication.

I was shocked at how much more efficient the third session was. I despise video calls, but in this case it was background, mainly to see who was paying attention and who was tuned out. The shared document with real-time edits worked fabulously well – one could write stream of consciousness thoughts, and before finishing the paragraph have his work edited and polished by the other two.

These days I find my most efficient working relationships require little in-person interaction. What they do require is a host of enabling technologies we take for granted.

I’m still a huge believer in the value of in-person interactions – the best ideas generally pop up over lunch or other informal settings. But in-person interaction doesn’t require the traditional office setting and trappings.

The work style adopted by startups today will make its way to large business, and the services that are the lifeline of that style will become the dial-tone of business. As Paul points out this will drive the creation of a number of significant companies to provide those dial-tones. And with any luck I’ll have an opportunity to invest if a few of them ;-)

Generating static html from markdown in python

Note to self, for future reference.

Generating static html:


import markdown2
file('classification.html','w').write( markdown2.markdown_path('classification.md', extras=["code-friendly"]) )

Retention Bonuses Don’t Work

Retention bonuses don’t work because they only motivate presence, not contribution.

mo.com Interviews Me

The lovely folks at mo.com recently asked me about my experiences at Yahoo, the background and business model for Xpenser, and thoughts on funding and raising VC money. The interview has been published here, drop by and take a gander.

How To Run A Command On Multiple Linux Boxes

Here’s a handy way of running a command on multiple boxes. In this case I wanted to check disk space on a series of machines.

Assuming you’re using bash as your shell, the following will list the hostname and run df on machines racb13 through racb28 and spit out the results.

for i in {13..28}; do ssh racb$i 'echo `hostname`; df -h | grep /data'; done

Note that ssh has to be setup to allow password-less login and so forth, but I’m assuming you’re smart enough to know how to do that or can look it up.

Installing OSQA on OS X and Linux

OSQA is a python/django based StackOverflow clone with a lot of nice capabilities. You might’ve seen me mention it on twitter.

Hernâni and Rick were tremendously helpful on IRC to help get past some of the things not covered in the installation documentation. Here are my notes on how to get OSQA working on OS X with SQLite (something very similar should work for Linux and mysql):

My OS X setup is: OS X 10.6.3, Python 2.6.4, Django 1.1.1.

First, install the pre-requisites:


sudo easy_install south
sudo easy_install markdown
sudo easy_install html5lib

Now create your local settings file:


cp settings_local.py.dist settings_local.py
vi settings_local.py

Setup your database settings in settings_local.py. Here are mine with sqlite:


DATABASE_NAME = '/Users/darugar/Packages/OSQA/db/osqa.sqlite3'
DATABASE_USER = ''
DATABASE_PASSWORD = ''
DATABASE_ENGINE = 'sqlite3'
DATABASE_HOST = ''
DATABASE_PORT = ''

Now it’s time to create the database:


python manage.py syncdb --all
python manage.py south --fake

That should do it, now you can run your server:


py manage.py runserver 0.0.0.0:9876

Once you’re up and running you should be able to go to http://localhost:9876/ and see OSQA in action.

Art

I don’t know why but I’m seriously in love with this drawing from the six year old; it seems to have a real style. Better than anything I could draw, methinks.
Desert Scene by Kamran

Using Python-Oauth2 To Access OAuth Protected Resources

Most of the examples I found for python-oauth2 show how to use the library to request and approve tokens, but not how to use the access token to access a protected resource (ie. how to actually make a call to the service you’re trying to access). Here’s an example:


import oauth2 as oauth
consumer = oauth.Consumer('consumer-key-here','consumer-secret-here')
token = oauth.Token('access-key-here','access-key-secret-here')
client = oauth.Client(consumer, token)
response = client.request('http://someservice.com/api/something/')

And here’s how you make a POST call:


import urllib
response, content = myclient.request("http://someservice.com/api/something/", \
    method="POST", body=urllib.urlencode({'name': 'value', 'another_name': 'another value'}) )

AndBot: The Best Android App Catalog

AndBot, recently featured in Mashable, is about the best source for Android news and reviews out there. If you do anything Android you definitely need to check it out.

To boot, its creator Courtney is a good buddy of mine, a fantastically smart and good guy.

I had a good laugh when I saw Mashable describe it as “one of the best-looking sites when it comes to researching Android apps” though, as I was recently giving Courtney a hard time about the design. Turns out it’s plenty good I guess :-)

Understanding OAuth: An Overview

The scenario: user Alice wants to allow SimpleService to access Twitter on her behalf.

Before OAuth this would be done by having Alice give SimpleService her login credentials for Twitter. She would type in her Twitter username and password into SimpleService, and SimpleService would use those credentials to access Twitter on her behalf. This was bad because SimpleService now knew Alice’s credentials, and could do malicious things or carelessly leak her credentials to malicious people.

With OAuth Alice doesn’t have to give SimpleService her Twitter credentials. Instead she goes through a process wherein she tells Twitter that SimpleService is allowed to act on her behalf.

The flow is:

First, before Alice is involved, Twitter and SimpleService exchange secret information: SimpleService requests Twitter to provide it with a consumer token and a secret. The consumer token will be used to identify SimpleService to Twitter, and the secret will be used to secure the communications to prevent others from pretending to be SimpleService.

This is setup once, allowing SimpleService and Twitter to communicate in general.

Once setup, for each user that wants to allow SimpleService to access Twitter on their behalf, the following happens:

  • The user Alice goes to the SimpleService website and requests SimpleService to access her Twitter account.
  • SimpleService calls Twitter with a request_token call. This tells Twitter SimpleService is about to have a conversation with it regarding authorization.
  • Twitter responds with a request_token.
  • SimpleService, having received the token from Twitter, redirects the user’s browser to a Twitter authorize page, passing the along the request_token as part of the url.
  • Twitter grabs the token (along with various signatures and timestamps to verify the request is not forged).
  • Twitter displays a page to the user asking her if she wants to give SimpleService access to her Twitter account.
  • If the user says no the game is over, and the token is not authorized.
  • If the user says yes, Twitter redirects the user back to SimpleService, passing along an authorization token, letting SimpleService know the user authorized access.
  • SimpleService now exchanges the authorization token for an access token: it calls Twitter with the authorization token, and requests Twitter to give it an access token.
  • Twitter examines the token SimpleService sent it, verifies that it’s not forged and that the user Alice had earlier authorized that token for access. It now believes that Alice wants to grant SimpleService access to her Twitter account. Twitter responds to SimpleService with an Access token.
  • SimpleService grabs the access token and stores it, associating it with the user Alice.

Now the initial authorization dance is done: SimpleService has an access token that allows it to access Twitter on behalf of Alice.

To actually access Twitter on behalf of Alice, SimpleService includes the access token with each call it makes to Twitter on behalf of Alice. Twitter checks the token, verifies that is valid, and allows SimpleService to access Alice’s resources.

To be an OAuth service provider (that is, play the part of Twitter), you need to:

  • Have a way to exchange consumer tokens and secret keys with third parties (eg. SimpleService) that want to access your APIs.
  • Provide a request_token service that provides tokens that start the conversation for each authorization.
  • Provide an authorization page that tells the user that a third party (eg. SimpleService) is requesting access to her resources, and allows her to accept or reject the request.
  • Make a callback to the service (eg. SimpleService), informing it that the request has been authorized.
  • Provide an access_token service that accepts a request token that’s been authorized and provides an access token to the third party (eg. SimpleService).
  • Store the access token for the user that authorized it.
  • Accept access tokens as an authentication mechanism for API calls, verifying the token’s validity and authenticating the user associated with that token.

Next Page »