Uploading (’Putting’) binary files to Amazon S3 in C#

So I’ve had a technology crush on S3 since it came out but I’ve only recently started to explore it. After downloading the C# S3 SOAP sample code, the first thing I tried to do was upload a jpeg. The upload was pretty easy, but upon trying to access the file via the s3 url, I only received an unintelligible string sequence. Opening it in a hex editor proved that the file didn’t get uploaded as a byte sequence, but as one long string. The reason, it turns out, was that I was using the wrong api call (duh), the call that accepts a string parameter:

public PutObjectResult put(string bucket, string key, string obj, MetadataEntry[] metadata, Grant[] accessControlList)
{
DateTime timestamp = AWSDateFormatter.GetCurrentTimeResolvedToMillis();
string signature = makeSignature(”PutObjectInline”, timestamp);
ASCIIEncoding ae = new ASCIIEncoding();
return s3.PutObjectInline(bucket, key, metadata, ae.GetBytes( obj ), obj.Length, accessControlList, StorageClass.STANDARD, false, awsAccessKeyId, timestamp, true, signature, null);
}

To use this call, I had to convert my byte sequence into a string, which was then converted to another byte sequence using an ascii encoding. That process corrupts your original byte sequence because not all bytes fit into the ascii spectrum. But where was the correct method signature? It turns out it was omitted, at least in version dated 2006-10-13. Adding the following method to AwsConnection.cs fixed my upload woes:

public PutObjectResult put(string bucket, string key, byte[] objBytes, MetadataEntry[] metadata, Grant[] accessControlList)
{
DateTime timestamp = AWSDateFormatter.GetCurrentTimeResolvedToMillis();
string signature = makeSignature(”PutObjectInline”, timestamp);
return s3.PutObjectInline(bucket, key, metadata, objBytes, objBytes.Length, accessControlList, StorageClass.STANDARD, false, awsAccessKeyId, timestamp, true, signature, null);
}

Seneca Hawk in hard-copy form.

So we got a mention in the calendar section of the LA Times. It’s just a listing, but what’s exciting is that it made the print edition. I can’t remember the last time I actually touched physical paper, but I’ll definitely have to pick up a copy. Did they solve that whole ink-on-the-hands problem when reading a newspaper? I guess that’s a lesser evil than carpal tunnel syndrome. You can check out the online blurb here:

http://www.calendarlive.com/search/457870,0,7409163.event

Tranferring your iTunes library from Windows XP to Mac OS X

The only reason I keep using my aging PC is because it has my entire music collection on it. Meanwhile, my MacBook has been collecting dust. So I finally got around to transferring my collection this weekend. This is how I did it:

  1. Sync your entire music library and playlists to an iPod of sufficient capacity. This is known as the auto-sync feature that basically mirrors your library onto your iPod.
  2. Download iPodRip and install it on your Mac
  3. Connect your iPod to your Mac. Let iTunes start up and recognize it, but just cancel when it asks you if you want to erase your iPod. You clearly don’t want to do that. Or do you?
  4. Start iPodRip. It will recognize your iPod collection.
  5. Click “Recover iPod”. Use the default options. “Recover iPod” is a two-part process. The first part transfers the audio files from your iPod to a temp directory on your Mac. The second part reads the meta data from your iPod and imports the songs into iTunes. This second part is why you need to leave iTunes running during this process.

iPodRip may crash during this process. That’s ok. Just eject your iPod from iTunes, close down iPodRip and iTunes, and then reconnect your iPod. Basically you’re going to repeat steps 3 - 5. iPodRip will start from where it left off.
Once you successfully import your library, you can disconnect your iPod and reconnect to your Mac. After you reconnect, you can now perform an “erase and sync”. It’ll be like you were never had your library on Windows to begin with.

searchmash search plugin for Firefox 2.0, IE 7

I’m going to start using searchmash.com as my primary search interface. It’s basically an unbranded testbed that google uses to try out search source aggregation and ajax features such as autocomplete and dynamic results retrieval. My favorite feature is the Wikipedia search, which is an example of search source aggregation. I guess it’s sort of like dogpile, except that it’s useful.
Here’s the OpenSearch source for the plugin: http://ankur.org/xml/searchmash.opensearch.xml

Click here to install the plugin.

Configuring ActionMailer to send email using Dreamhost

This is for all those dreamhosters out there. It took me a couple of tries to set up ActionMailer to send emails through my dreamhost account. Hopefully this will save someone some time. This is what I have in my environments/development.rb config file:

# ActionMailer settings for dreamhost
config.action_mailer.delivery_method = :smtp
config.action_mailer.server_settings = {
:domain => "mail.ankur.org",
:address => "mail.ankur.org",
:port => 25,
:user_name => "m0000000",
:password => "password",
:authentication => :login
}
config.action_mailer.raise_delivery_errors = true
config.action_mailer.default_charset = "utf-8"
The are two things to note.

1. your username is your mailbox name. This is that weird number that dreamhost generates for you and starts with an “m”

2. The domain and address had to be the same, and set to the outgoing mailserver, e.g. mail.yourserver.com. In theory, this should not have to be, but these are the settings that worked for me.

I lofe rails.

So I had a table called loves. The problem with naming a table loves is that rails will do this in the scaffolding:

“loves”.singularize

Guess what that is? Yes, the singular for loves is lofe. Don’t ask me what a lofe is, but I don’t lofe it. It turned out to be not such a big deal, because you can usually specify the :singular_name if you have to.
Btw, I am not creating a dating site. It’s more of a del.icio.us sort of love.

Routing the root of the site in rails

This is rails 101 but that’s the class I’m in right now. When you first set up rails, it generates an index.html file that responds to the root index of the application. So going to http://localhost:3001/ takes you to this index.html file. So how do you set up rails so that you can bind this default request to a controller? The index.html actually gives you some hints. Step 3 says:

Set up a default route and remove or rename this file. Routes are setup in config/routes.rb.

It’s a true statement but doesn’t say exactly how to do it. But routes.rb does:

# You can have the root of your site routed by hooking up ”
# — just remember to delete public/index.html.
# map.connect ”, :controller => “welcome”

I made it:

map.connect ”, :controller => ‘home’, :action => ‘index’