Recent Articles

Subscribe

I’ve had to compile the pre-release version of Gnupg a few times lately to test some changes.
While it’s not particularly difficult, it can be a bit persnickety to get right..
To that end, I thought I’d share the build script I’ve been using.

If it’s useful to anyone else, that’s awesome! At the very least, it’ll be easy for me to find it next time I want to play around again ;)

Please note – This isn’t necessarily the right way to do anything. I’m not a GPG dev. These changes worked for me.

Also note – As of 5/25/14, I needed to patch GPG to make it compile.
I’ve linked the patch as part of the steps below.
Hopefully there’s a better way that’s added to git-master soon ;)

After encountering this error, the OSX installer dutifully quits, leaving me scratching my head.
Since I was installing using a USB stick, at first I assumed the image or hardware were bad, and tried several variations on replacing drives and re-making the install image.

Eventually, I realized that the problem was particular to the destination system, rather than my USB stick.

One thing that can cause this error is if the time is off on the destination system.
Since the machines I was installing to had been sitting for quite some time, their batteries had depleted fully, and the clock had reset back to 2000.

Once I figured this out, and stopped wasting time on install media, this is pretty straightforward to fix.

On the Destination machine, once it’s booted into the install media – Go to the Utilities menu, and choose Terminal.

If you run the command

date

you can see the system time, and confirm it’s wildly incorrect.

To fix it, we just need to find the correct time/date from another system.
On another machine, fire up the Terminal, and run

TZ=US/Pacific date +%s

This will output the current unix timestamp in the PDT timezone. We want the PDT timezone, since that’s what OSX defaults to when the clock is reset.

Once we have this timestamp, we can enter it back into the Destination machine.
In the terminal, run

date -f %s TIMESTAMP

(Replacing TIMESTAMP with the timestamp from the last step, such as “date +f %s 1401065468″)

After this, close out of the terminal, and the install should proceed normally ;)

I always find it fun to test new gadgets, and play with different ways of reaching the world.
I enjoy swapping phone platforms, OS, but mail clients and web-browsers are particularly susceptible to this, since they’re in that special fit of frequently used, but low cost-of switching.

Most recently, I’ve switched back to using a browser I used to love 10 years ago – Mozilla, or as it’s known now, Seamonkey [1]

Seamonkey is the new name for what used to be called the Mozilla Application Suite, or, more commonly, Mozilla.
Like it’s predecessor Netscape 4, Seamonkey combines a Browser, Email client, and Newsreader into one svelt package. Even though the Mozilla Foundation quasi-abandoned Seamonkey back in 2005, volunteers around the world have kept it up to date.. Since it shares the engine with Firefox, it supports all major web features, and gives a really nice experience.

I had a lot of fun playing nostalgically with various Throbbers , before getting down to the business of making it a mean, lean, modern web-browser.
Amusingly, with the resurgence of minimalism, the theme that was used during the beta looks perfectly at home.

Modifying Extensions

As much fun as I was having, if I wanted to stay with Seamonkey for a primary browser, I couldn’t use it without extensions.
I’ve become far too accustomed to storing pages to read offline, using separate passwords for every site, and other things that aren’t built into any browser directly.

While quite a few extensions run out-of-the-box on Seamonkey, it’s often ignored compared to it’s vulpine cousin.
Luckily, they both use the same underlying engine, as well as the same UI framework, so porting them isn’t that bad.

Evernote

The first addon I ported over was the Evernote Web Clipper – It’s a cute little extension which lets me download webpages, and store them to read later.

Since it isn’t designed to run in Seamonkey, Mozilla (understandably) tries to discourage downloading the extension, but thankfully they do provide an override.

Once an extension is downloaded, it’s very straightforward to edit.
xpi extensions can be thought of as .zip files. [2]

By default, the files will unzip into your working directory, rather than a subdir (aka, a tarbomb)
This means that we should create a new subdirectory to work in

unzip evernote_web_clipper-*.xpi -d evernote-tmp/

The layout of modern extensions is pretty straightforward – The first file we care about is ‘install.rdf’
This file gives browsers the details of the extension – What browsers it’s compatible with, which languages it supports, etc.

Almost all extensions will need that fix. There are some other similar tweaks that other extensions might need, but it’s rare.
With that change in place, the extension should work fine in Seamonkey – It just needs to be turned back into an xpi file.

zip -r ~/Downloads/Evernote-for-Seamonkey.xpi *

Once this is an xpi file, it can be loaded like any other Extension that we downloaded from Mozilla.org.
This adds the extension to Seamonkey, but by default doesn’t add it to the active toolbar.
It can be added by right-click the menu bar, choosing customize, and dragging the new button into the toolbar.

Once that’s done, we’re good to go – The extension is in place, and we can properly save articles for reading later on.

1Password

Another extension I rely heavily on is 1Password. It lets me generate unique passwords for each site I visit, so if they’re hacked, and my password is leaked, it can’t be used to break into my other accounts.
Converting it to work with Seamonkey is very similar to the procedure for Evernote –

The 1Password extension has a few other places it’s looking for Firefox specifically that need to be tweaked.
It ships with a config file, ‘harness-options.json’, which sets various options.
One option, ‘is-sdk-bundled’ should be around line 4 – It chooses if the extension should use the version that’s built into firefox, or the one that ships with the plugin.

Setting this to true will ensure we load the version we’re about to modify.

"is-sdk-bundled": true,

One of the files in the extension, ‘resources/addon-sdk/lib/sdk/loader/cuddlefish.js’ does another compatibility check.
Around line 50, there is a line that starts with ‘function incompatibility(module)’.
This can be bypassed in the terminal

Once that’s fixed, it can be bundled up as an xpi, and installed via the gear icon in the admin menu, just like Evernote.

zip -r ~/Downloads/1Pass-for-Seamonkey.xpi *

While this loads, it’s not quite smooth sailing yet –

In Version 4 of 1Password, Agilebits added a new security feature.
The app checks the gatekeeper signature of the browser that loads it, to ensure that it’s an approved browser.
The feature makes some sense – 1Password works by communicating with the browser over a socket, so adding some security to ensure we know who we’re talking to is reasonable.
Unfortunately, Seamonkey isn’t currently signed, so even if Agilebits wanted to, they couldn’t include it’s signature.

Of course, that’s no reason to give up ;)
I dug around in the app a bit – While I’m not really very talented at reverse-engineering apps, it looked to be fairly simple.
1Password runs in the background, listening on a socket, which the extension then connect to – When a connection comes in, 1Password looks up the Process that is talking to it.
This information is readily available in the system normally, such as with a lsof

Once it has the PID, it can lookup the gatekeeper signature. Since all the major browsers are signed, it’s straightforward to compare against those signatures.

I can see where they’re going with this, and it’s an interesting idea, but the feature does make it a bit more difficult to use unsupported browsers.
Luckily, before I went too far down the rabbit hole of trying to patch the binary, I found an much easier way.
The new beta version has a bypass option built in.

Success!
Seamonkey runs really well, and porting over a few plugins, even if you need to smash them around a bit, makes a great everyday experience.
I certainly wouldn’t recommend it for everyone, but it’s become my browser of choice — At least for this week.

Footnotes

1 – I know that Mozilla prefers to refer to the suite as SeaMonkey, with both words capitalized. Personally, I find this a bit ugly, so I’ll be using the variant Seamonkey here.2 – Technically, these are Jar files, but the distinction isn’t meaningful here.

I’m a big 1Password fan, and it’s one of the things which kept me from using Opera 12.15 and below.
The new Opera is based on Chromium however, so it’s sorta-kinda compatible with Chrome extensions ;)

Note- I was able to install the extension using the instructions I’ve written up below.
I can’t guarantee it’ll work for you. It might very well corrupt your 1Password file, or do nasty things.
It will also be overwritten (and need to be run again) once Agilebits updates their Extension.
In Short – YMMV.

1Password extension for Opera 15

First off, we’ll need to download the 1Password Chrome Plugin, from Agile Bit’s site

Make sure you click the “Allow beta extensions” button.
Then, click the download button next to “Google Chrome”.

Opera will say *”Extension was disabled because it is from unknown source. Go to the Extension Manager to enable it.”*, click “OK”.

Go to Window, then select Extensions, to open the Extension Manager.

One there, the 1Password extension will be greyed out.
Press Install.

It will prompt you again in a little pop-up. Press install again.

Make a note of the version- In the case of our screenshot, it’s such as 3.9.20.2
If the plugin updates later, and this version has changed, you’ll need to re-run these steps.

Close both the Opera Extensions window, and the Agilebits “Extension Setup” Tab.
Go to File, and choose “Close Tab” for both tabs.
If you do not do this step, when Opera re-opens it will re-open the Agilebits Extension installer , and re-install the default version of the extension.

This would undo the changes we make below, so make sure you close this ;)

Quit Opera. Make sure you go to the Opera menu, and choose Quit, even if no webpages are showing.

Open the Terminal (It’s in Applications, Utilities)
This will allow us to perform the additional steps necessary to load the extension.
You can also open the terminal through Spotlight if that’s easier ;)

Move to the directory where your Opera Extensions are installed.
Enter the following command into the Terminal, and press enter.

Next we need to locate the 1Password extension we just installed.
The exact name changes, so we want to look for it in the “Info.plist” file that is distributed with the Extension.
The following “Find” command will search for it, then move to it’s directory.

Chrome has an “Omnibox” which combines the URL bar with Search.
Opera has something similar, but doesn’t let extensions talk to it yet – So we need to remove this code from the Extension, so it can load in Opera.
Run the two commands below in the Terminal.

Re-open Opera.
You should be all set at this point – The extension will need to sync, which might take a minute or two after clicking on the icon.
You might also find you have luck opening or closing the window which loads the extension.

Notes-

I had initially thought that it would be a lot more complicated to port the extension, but Opera does not seem to have changed the internals as much as I thought.
For instance, 1Password uses tests such as

if("object"==typeof chrome) { alert("foo")}

These work with “chrome”, not “opera”.
The most complicated part is that Chrome 15 does not have the Omnibar property.

I’m not an expert, but there appears to be a few other cases where the extension could be updated to use more recent methods, such as moving sendRequest -> sendMessage, or chrome.tabs.getSelected -> chrome.tabs.query.In all, it appears to work, however.

It works using Divs laid out with CSS, and generally works really well.

It even loads well on older version of Netscape, properly degrading to run, even if it’s not as pretty.

The more I look at it, though, the more I wonder if there is more I could do.
If dropping support for ancient browsers is really necessary at all.

Given that it’s a simple 3 column site, my initial thought was to experiment with frames. While these work, dataURI+frames aren’t as well supported as I’d like, and the experience of frames on lynx is not ideal.

What about Tables?

Tables have gotten a bad rap in recent years.
It is generally recommended that we avoid tables, and use divs for layout. But why?

There are few traditional arguments that are given against tables:

HTML should be semantic

It’s often argued that HTML should be semantic where possible, and to split the presentation (CSS) from the layout (HTML). In practice, however, this often doesn’t work out. To make various tricks work right, developers are often creating a wide variety of presentational divs anyway, for wrappers and other non-semantic content.

You could certainly argue that we’re moving in a more semantic direction, and HTML5 certainly moves in that direction, but we’re still a long way away from there.
Combine that with other work arounds that are being done to support non-performant browsers

[if IE 6]>

and it’s hard to justify that a simple table is much worse.

Screen Readers can’t handle Tables

Modern screen readers are actually fairly decently at handling tables. They’ve improved in the last 10 years since we started using CSS.

Additionally, you can mark a table as presentational, so that it can be interpreted as such using role=”presentation”.

JAWS, WindowEyes, and NVDA will all do the right thing.

CSS lets you just change the one CSS file, rather than every page

If I were manually editing 100s of files, this might be a valid concern – But like many modern developers, I’m writing web applications designed to run with a templating system – Python, Ruby, even PHP have libraries which make this trivial. I can change my structure in a single location, and have it automatically apply on every pageload.

Table Layouts are only used by people who can’t do divs properly

I can sympathize with this view- There’s a lot of people who get stuck in CSS land, and resort to a “Screw it, I’ll use a table” attitude, so I can see where it comes from. But Google and Twitter are using tables as part of their layouts, and I’m sure they have someone there who knows what they’re doing ;)
In my case, I have the layout working properly in CSS, but I’m deliberately redoing it, spending extra time, to gain the broad-compatibility that a table-based layout brings. Some things are easier, some things are harder, but it’s a valid choice in designing a site.

But CSS is really useful!

It sure is! And I’m in favor of using CSS, all over the place!
Gradients are better than images, rotation is amazing, and changing elements through properties is useful.
CSS has it’s warts (Templating would be nice..), but it’s a great way to explain how elements should look. And divs are often useful for layout, too.
But non-tabular use of a tables is probably OK, as part of a well-balanced breakfast.

Earlier this year, I wanted to add the ability to generate and display barcodes as part the Savingstar iPhone app, similar to Loyalty card wallets.
We’re already storing loyalty card numbers of over a million users in order to process their coupons – It seemed like regenerating these into scannable barcodes should be simple enough.
For stores with a scanner that can read a phone (an increasing number), this is a lot more convenient.

Looking over the various card ranges, they fell into a few formats- EAN-13, UPC, etc.

Luckily, there is a library which can easily write these, and easy to use python bindings in order to use them.

After a few trials however, I ran into a small issue-

The numbers in the barcode don’t always match up with the printed card number!

Often there is a prefix/postfix on the number, in addition to the checkdigits for UPCs.
After thinking about it for a while, I realized I could reverse engineer the formats, but I’d need cards. Lots of cards.

Getting Cards

I posted several jobs, each time asking people to mail me loyalty cards.
Because I needed to match the cards to a something digital to approve/deny them on Mechanical Turk, generated hundreds of random strings, and assigned one to each user.
I then asked each user to then write their particular random string on the envelope; When I received the envelope, I could match it up and give them credit for the job.

And we got cards! Hundreds of beautiful cards, dozens of cards in each of the ranges I needed.
People from around the US and Canada send cards from every major chain in the US.

The biggest downsize to this method is that there is a built in lag.. So even after I had enough cards for each certain chains, and pulled the listing, I still received loads of cards that had already been mailed ;)

A friend of mine from the Java world has been trying to get into JS lately.

He understood the basics of how JS works – Functions look (on the outside) superficially similar to Java, it has standard loops/variables, etc.
Canvas functions are very straight forward- The part that confused him was “How do I create a game loop”, and “How do I update the page based on JSON responses from my server?”

Luckily, both of those are REALLY easy in Javascript!

I’m certainly not a Javascript expert, but I put together a simple demonstration, with an over-the-top number of comments.

We’ll start with our very simple HTML page.
Anyone who’s done even “Hello World” should understand most of what we’re doing here.

We’re loading our JS, then three divs – Header, Game, and Footer.

<html>
<head>
<title>This is an example</title>
<!--
Include are our JS scripts. The "defer" line just tells it to run this after the page loads.
It's not actually needed, but it makes the initial load faster
We're loading in jQuery via a CDN, but copying it locally would work just as well.
This is just one less file to deal with.
-->
<script defer src="http://code.jquery.com/jquery.js"></script>
<script defer src="exampleCode.js"></script>
</head>
<!--
In the body (below), define the game however you want it to look.
I'm using 3 divs, just for the sake of showing we're only showing/changing the game div.
There's nothing special about this setup.
-->
<body>
<div id="Intro">
This is the beginning of the game.
</div>
<div id="Game">
The GAME GOES HERE.
</div>
<div id="Footer">
This is the bottom.
</div>
</body>

Now this is calling our JS, exampleCode.js –
That’s also very simple. We’re just going to do two “game loops” to update the page.
One of which updates the color, and the other uses an AJAX request

// This function does the logic of updating our game div.
// Obviously, in a real game, this would be more interesting.
function ChangeColor()
{
// in jQuery, the $ character gives you the root jQuery object.
// You can use the $(FOO) notation gives you a reference to any element
// Any element you want. It's just like a CSS selector.
// So-
// $('#foo') gives you a HTML element with id="foo"
// $('.foo') gives you every element with the class="foo" (loop through them)
// The next line creates an array of random colors.
bgcolorlist= Array("#DFDFFF", "#FFFFBF", "#80FF80", "#EAEAFF", "#C9FFA8", "#F7F7F7", "#FFFFFF", "#DDDD00");
// Now, Randomly choose one, by picking a random number (between 1 and arraysize), and then get that array element.
randombgcolor = bgcolorlist[Math.floor(Math.random()*bgcolorlist.length)];
// Now, in jQuery, you can set a CSS property, by using the .css function.
// I'm using it to set the background for the HTML element #Game.
$("#Game").css('background',randombgcolor);
}
// Let's try a slightly more interesting function. We'll add an external call.
function UpdateTime()
{
// Now, let's do something Ajaxy-
// There is a URL endpoint for Tavern that gives us the server status, including the time.
// We can use that to display the current time on our page.
// The $.ajax() function doesn't return the JSON.. It RUNS the success value as a function.
// That function will save the variable for us.
// Normally, we could use $.get(), or $.getJSON(), but these just call $.ajax() under the hood.
// By calling $.ajax() directly, we can set more options.
// set the result variable ahead of time, so it's scope isn't only inside the function.
var result;
// make the AJAX call
$.ajax({
// async defaults to True- This means that the result will wait for a return before running anything else.
async: false,
// Setting the dataType to JSON is a convenience. It automatically parses it into a JSON object for us.
dataType:"json",
// This is the URL we're pulling from. I set this up to be accessible from any domain.
// Normally, you can only make requests to the SAME DOMAIN as the HTML runs from.
// But you can bypass this with a header (Access-Control-Allow-Origin), which I've set for you.
url: "http://gettavern.com:8090/status",
// This is just our super-simple function that gets called on success.
// ALL it's doing is setting the result back to that variable we declared before.
// Normally, in JS, you'd just do whatever it is you actually needed with your drawing/etc, right in the inline function..
// Or have it call a longer function, that's defined normally (like the one we're in!)
// But in this case, I wanted to a) illustrate Inline functions.
// and b) make it short ;)
success: function(data) {
result = data;
}
});
// Now, make that into something printable. Notice how we pull values out of the JS call as if it were a dictionary/hashmap?
timeStampString = "The current timestamp is " + result['timestamp'] + ".";
// Now, let's DO something with this data-
// create a new javascript Date object based on the timestamp
// multiplied by 1000 so that the argument is in milliseconds, not seconds
var date = new Date(result['timestamp']*1000);
// hours part from the timestamp
var hours = date.getHours();
// minutes part from the timestamp
var minutes = date.getMinutes();
// seconds part from the timestamp
var seconds = date.getSeconds();
// will display time in 10:30:23 format
var formattedTime = " This is equal to " + hours + ":" + minutes + ":" + seconds;
// This redefines the HTML inside the game object to whatever we pass it. In this case, it's the time.
// Get the Game's DOM object
// This gets the instance of the Game, just like we were in the first function.
game = $("#Game");
// Replace the Game's HTML.
// Just like used the background function in the first example (above), here we're overwriting the HTML that's in the Game object.
// Everytime this runs, everthing that is in the game div is erased, and replaced with whatever string we pass.
// In this case, we're passing in our two time-based strings we just created.
game.html(timeStampString + formattedTime);
}
// Run the code above, every 500ms
self.setInterval("ChangeColor()",500);
self.setInterval("UpdateTime()",1000);

For the last few years, I’ve been using a cute little tool called iStat menus to graph my CPU/Memory in my address bar.
It doesn’t do that much, but it works, it stays out of my way, and the UI is better than the nearest free alternative.

I don’t think about the tool very much – Once in a while I’ll glance up when the system is running slow, or use the clock function to see the time in multiple time-zones.

Every so often, there’s a new version available, and the software prompts me to upgrade –

I generally go ahead and agree to the change, and go about my business.

Although my 1999 self would cry to hear me say it, I don’t always read through the changelogs-

iStat is offering upgrade pricing ($9), and the app isn’t that expensive in and of itself, but the entire process felt very sketchy.[1]

Users are used to accepting in-app upgrades, and switching one out for a paid-upgrade feels very disingenuous, regardless of their justifications.
Bjango (the creators) could have handled things differently,by setting the “Remind me Later” Dialog option to be the blue/rightmost option, or even installing as a different name in the Applications folder, so you could still easily fire up v3.

Admittedly, It’s a minor issue, $9 isn’t much, and I don’t begrudge an indie shop trying to raise money for a new version and stand in business, but the sense of fairplay has been violated- It’s one more reason for me to try to avoid buying non App Store applications in the future.

For anyone else who runs into this, You can uninstall iStat 4 using the menu item-
And then reinstall Version 3.

[1]For what it’s worth, I did end up buying the upgrade. The UI is a bit nicer.
This isn’t about the $9. It’s about the process.

But aren’t frames evil?

One of the biggest criticisms of frames is that they aren’t reliably accessed – Their very nature allow search-engines (or users) to link to one specific frame, rather than to the frameset container you’re wrapping them with.

It turns out, we have a weapon against this, which has been around since 1998- The DataURI.

Rather than linking to a specific file, using the datauri, we can embed our frame elements directly INSIDE the original page.
They can be generated at the same time, with the rest of your code, and stored directly.
This eliminates the idea of a separate page that might ever accidentally get linked to.

If your browser supports the “data:text/html;charset=UTF-8,” type (webkit seems to like this better than others) you can make this even easier, and embed your normal HTML, straight into the original page.

This will work somewhat similarly to a resizable-div, but using 1998-level technology.

<frameset cols="30%,*">
<frame src="data:text/html;charset=UTF-8,<html>
<head>
<title>Frame Content</title>
</head>
<body bgcolor='#DDDDDD'>
<p>Here's what it would look likeA good rule of thumb is to call the page which contains this frame information "index.html" because that is typically a site's main page.
<p>A good rule of thumb is to call the page which contains this frame information "index.html" because that is typically a site's main page.</p>
<p>A good rule of thumb is to call the page which contains this frame information "index.html" because that is typically a site's main page.</p>
<p>A good rule of thumb is to call the page which contains this frame information "index.html" because that is typically a site's main page.</p>
<p>A good rule of thumb is to call the page which contains this frame information "index.html" because that is typically a site's main page.</p>
<p>A good rule of thumb is to call the page which contains this frame information "index.html" because that is typically a site's main page.</p>
<p>Here's what it would look likeA good rule of thumb is to call the page which contains this frame information "index.html" because that is typically a site's main page.
<p>A good rule of thumb is to call the page which contains this frame information "index.html" because that is typically a site's main page.</p>
<p>A good rule of thumb is to call the page which contains this frame information "index.html" because that is typically a site's main page.</p>
<p>A good rule of thumb is to call the page which contains this frame information "index.html" because that is typically a site's main page.</p>
<p>A good rule of thumb is to call the page which contains this frame information "index.html" because that is typically a site's main page.</p>
<p>A good rule of thumb is to call the page which contains this frame information "index.html" because that is typically a site's main page.</p>
<p>Here's what it would look likeA good rule of thumb is to call the page which contains this frame information "index.html" because that is typically a site's main page.
<p>A good rule of thumb is to call the page which contains this frame information "index.html" because that is typically a site's main page.</p>
<p>A good rule of thumb is to call the page which contains this frame information "index.html" because that is typically a site's main page.</p>
<p>A good rule of thumb is to call the page which contains this frame information "index.html" because that is typically a site's main page.</p>
<p>A good rule of thumb is to call the page which contains this frame information "index.html" because that is typically a site's main page.</p>
<p>A good rule of thumb is to call the page which contains this frame information "index.html" because that is typically a site's main page.</p>
</body>
</html>">
<frame src="data:text/html;charset=UTF-8,
<html>
<head>
<title>Frame Menu</title>
<base target='content'>
</head>
<body bgcolor='#0099DD'>
<a href='http://www.yahoo.com' class='menu'>Yahoo.com</a><br />
<a href='http://www.google.com' class='menu'>Google.com</a><br />
<hr />
<a href='http://www.ebay.com' class='menu'>Ebay.com</a><br />
<a href='http://www.fandango.com' class='menu'>Fandango.com</a><br />
</body>
</html>">
</frameset>