Removing duplicate messages from Outlook

Posted September 20th 2012 by Matt Berther

I recently learned that Outlook for Mac had been uploading multiple copies of the same message to the Exchange server. At final count, I had approximately 280,000 email messages sitting in my “Archive” folder on the server. As you can imagine, this caused tremendous download times for resynchronizing my folders.

I looked for tools that could purge the duplicates for me, but had a tough time getting most of them to work on Microsoft Outlook 2010. I set out to try and solve this problem by creating a simple C# app that would iterate through my archive folder and identify and remove duplicate items.

I chose to parse the messages in two different ways to make sure that I was able to remove as many duplicates as possible. The first scan removed every message that had a duplicate message id. The second scan removed every message that had the same sender email, subject, and sent time.

This technique worked remarkably well. My archive folder now has less than 70,000 messages in it, which means that approximately 75% of the messages in that folder were deleted as duplicates.

I’ve made my source code available at github for anyone that is interested in using and/or forking the project.

Please keep in mind that there are no warranties with the code. It worked well for me; your mileage may vary.

Chrome extension for instapaper

Posted September 14th 2012 by Matt Berther

I use instapaper.com as my read later service. I have installed the Chrome add-on to allow me to quickly tag an article to read later. Also, I have configured it as my read later service in Tweetbot, which allows me to quickly send articles to it for later reading.

The one thing that has always bugged me about the instapaper website is that it does not open links in a new tab/window. To get around this, I set out to create a Chrome extension. This is what I came up with.

// ==UserScript==
// @name        Instapaper New Windows
// @namespace   http://mattberther.com
// @description Open Instapaper links in a new window
// @include     http://www.instapaper.com/*
// @require     http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js
// ==/UserScript==

(function() {
    function loadJQuery(callback) {
        var script = document.createElement("script");
        script.setAttribute("src", "http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js");
        script.addEventListener('load', function() {
                var script = document.createElement("script");
                script.textContent = "(" + callback.toString() + ")();";
                document.body.appendChild(script);
            }, false);
        document.body.appendChild(script);
    }

    function main() {
        $("a.tableViewCellTitleLink").attr('target', '_blank');
    }

    loadJQuery(main);
})();

Copy the code above and save it to a location on your computer; I called mine instapaper.js. The latest versions of Google Chrome no longer allow you to add extensions from a third party source (like your own computer) by simply clicking on the javascript file. To install the extension, open the extensions window in Chrome and then dragging the file you created onto the window.

Once the extension is activated, any links from your unread list in instapaper.com will open in a new window.

Validating HABTM relationships with Rails 3.x

Posted September 9th 2012 by Matt Berther

There comes a time as you build up a rails application that you end up using the has_and_belongs_to_many (HABTM) macro. This macro is an easy way to create a many-to-many relationship between two of your ActiveRecord models.

In some cases you may want to validate that association. However, the traditional methods for validating rails models do not work.

The unit tests below described how I wanted the relationship to function.

class ProjectTest < ActiveSupport::TestCase
  setup do
    @project = Project.new()
  end

  test "may have many developers" do
    4.times { @project.developers << FactoryGirl.create(:developer) }
    assert @project.save
  end

  test "must have at least one developer" do
    @project.save

    assert_equal 1, @project.errors.count
    assert_not_nil @project.errors[:developers]
  end
end

In my case, I was hoping to validate that each project had at least one developer associated to it. Initially, I coded my models to make the first test pass.

class Developer < ActiveRecord::Base
end

class Project < ActiveRecord::Base
  has_and_belongs_to_many :developers
end

To make the second test pass, I tried to implement a custom active record validator.

class Project < ActiveRecord::Base
  has_and_belongs_to_many :developers

  validate :minimum_number_of_developers

private
  def minimum_number_of_developers
    errors.add(:developers, "must have at least on developer") if developers.count < 1
  end
end

This, however, does NOT work with HABTM relationships. The way that these relationships work is that the associated property is not available until after the record is saved.

To get around this, we can validate as part of the after_save callback. Validating here and returning false from the callback will rollback the entire transaction.

class Project < ActiveRecord::Base
  has_and_belongs_to_many :developers

  after_save :validate_minimum_number_of_developers

private
  def validate_minimum_number_of_developers
    if developers.count < 1
      errors.add(:developers, "must have at least on developer")
      return false
    end
  end
end

The test passes with the code above.

Fixed Position Footers

Posted December 8th 2011 by Matt Berther

Posting mostly for my own reference…

One thing I find that I need to do a lot is position a footer bar across the bottom of the page. The most common way to do this is to set a fixed position on the element and anchor it to the bottom using this css:

 #footer {
      width: 100%;
      position: fixed;
      bottom: 0;
      height: 75px;
 }

Unfortunately, this doesnt work quite right in IE. When using this style definition in IE, the footer gets locked into a specific position in the viewport and when you resize from the corner anchor the footer does not move with the window.

The proper cross-browser way to declare a fixed position footer is to use negative margins, like this:

 #footer {
      width: 100%;
      position: fixed;
      top: 100%;
      margin-top: -75px;
      height: 75px;
 }

This appears to function properly in every browser I’ve looked at so far.

The Software Behind the Site

Posted December 6th 2011 by Matt Berther

Several times over the past months, I’ve received questions about the software and setup that I use to run the mattberther.com blog and related pages. Since the site recently underwent a dramatic change in tooling, I want to detail what I chose and why.

Before the change, the site was powered by wordpress. I had my own rackspace virtual server that I was using to host the apache and mysql server servers required by wordpress. Wordpress is not a bad piece of software, but what I realized is that it tries very hard to be all things to all people.

Enter the blog engine Im using now: toto

Toto’s philosophy is akin to mine: use the best tool for the job. Toto’s website states that “everything that can be done better with another tool should be”. To that end, toto doesn’t use complicated web frameworks. It doesn’t use a database. There’s no built-in commenting support. If you want comments, you’ll use disqus. It also relies on git for version control. When you combine toto with a Heroku account, you also use git to deploy the site. Its designed to be used with a proxy cache for high availability and fast response times.

Migrating the posts from the mysql database to the text files proved to be relatively straightforward, using a simple ruby script to iterate over the rows and format a text file that matched toto’s expectations. Importing the comments into the disqus platform was equally straightforward using their JSON API.

I much prefer the simplicity of this new setup. The entire blog engine weighs in at about 300 lines of code. If running a blog without putting your hands on the metal and being able to control every nuance of your blog platform appeals to you, then certainly take a look at the toto/heroku combination. If not, then I believe that wordpress is a fine solution.