Downtime

Looks like one of Facebook’s webservers took a nap yesterday.

When they designed this error page, I wonder if they realised that both the ‘Help’ and ‘Go back’ links give you the same error again.

Pyrocket and Ubuntu

I have a great USB rocket launcher, it’s more useful than a computer mouse most of the time actually. I spotted a moth on the roof the other day, and hadn’t installed pyrocket on this computer yet.

A quick apt-get install pyrocket is all it takes to solve that though, right? No such luck.

Apparently, the quality control in the Ubuntu repos are such that this package has been broken for several months now, despite the dependency issue being fixed by an upstream fork.

So this is the error you get at the moment anyway:

Traceback (most recent call last):
  File "/usr/bin/pyrocket", line 17, in 
    from rocket_frontend import RocketWindow
  File "/usr/lib/pymodules/python2.7/rocket_frontend.py", line 11, in <module>
    from rocket_webcam import VideoWindow
  File "/usr/lib/pymodules/python2.7/rocket_webcam.py", line 2, in <module>
    from opencv import cv, highgui
ImportError: No module named opencv

The solution, beyond complaining about it, is to read the bug report here and do this:

git clone https://github.com/stadler/pyrocket
cd pyrocket/src
./pyrocket.py

But the moth had escaped by then.

Chromium B.S.U.

I was looking for the Chromium web browser and installed this mysterious chromium-bsu package at the suggestion of the package manager:

mike@mikebox:~$ sudo apt-get install chromium
...
Package chromium is not available, but is referred to by another package.
...
However the following packages replace it:
  chromium-bsu

All the most important discoveries were made by accident — including penicillin, teflon, coke, and what turned out to be a really cool space-shooter game.

Chromium B.S.U. screenshot

About an hour of clicking later— back to work. Installing the wrong package is a real time sink!

Changing the IP address on a Cisco switch

Cisco switches are a bit cryptic, but well documented. You can generally do just about anything with enough patience and Googling, but even simple configuration tasks can be difficult if you’re not familiar with the interface.

These are my 3 tips to configuring Cisco devices:

1. telnet
Always telnet or SSH to the switch to log on. Don’t use configuration utilities or a web interface, because everything that turns up on Google refers to the command-line interface.
2. enable
All of the fun options are hidden by default. Make liberal use of enable to do the serious work.
3. ?
Pressing ? pops up a list of ways you can finish off the current command.

For example: IP settings

The first step when moving around a used switch is to set it up for a different network. Here is where you will find the IP config:/p>

Log in:

telnet 10.1.x.x

Now enable the admin options:

example-switch>enable
Password: (type in your password)

Note that the prompt has changed from < to #. We can now change the IP and subnet mask of the switch:

example-switch#
interface vlan 1
ip address 10.1.x.x 255.255.x.x

Weird bug in iPad mail app

If you use the iPad mail app with Gmail, set up as an exchange account, you get a folder labelled [Gmail] which has your spam and starred mail folders.

But it turns out that an undocumented feature turns up if you also create a label called [Gmail]:

Labels and these special folders are different, so why are they getting mixed up? Or if they’re meant to be mixed- why are their two [Gmail] headings?

It seems to have slipped through the developers’ minds when they stored them in the same place, because the app behaves very inconsistently with this setup (variously duplicating labels and headings, and then leaving one list out of sync when changes are made).

Workaround: rename your labels:

I hope the developers are paying more attention next release- I’m only blogging this because there’s nothing much that google turned up about it.

Re-arranging columns on JTables

As I’m only new to Java UI work, I was surprised to see how easy it is to work with tables. A few things I’ve learnt:

  • JTables only show column headers if the table is placed inside a JScrollPane
  • It’s really annoying to drag-and-drop narrow, resizable columns, so turn off resizing.

I ended up with this user-rearrangeable table:

Basic code for this, thanks to Google Windowbuilder:

import java.awt.EventQueue;

import javax.swing.JFrame;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;
import javax.swing.JScrollPane;

public class TableTestWindow {
	private JFrame frame;
	private JTable table;

	/**
	 * Launch the application.
	 */
	public static void main(String[] args) {
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				try {
					TableTestWindow window = new TableTestWindow();
					window.frame.setVisible(true);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}

	/**
	 * Create the application.
	 */
	public TableTestWindow() {
		initialize();
	}

	/**
	 * Initialize the contents of the frame.
	 */
	private void initialize() {
		frame = new JFrame();
		frame.setBounds(100, 100, 525, 520);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.getContentPane().setLayout(null);

		JScrollPane scrollPane = new JScrollPane();
		scrollPane.setBounds(12, 12, 460, 440);
		frame.getContentPane().add(scrollPane);

		table = new JTable();
		table.setFillsViewportHeight(true);
		scrollPane.setViewportView(table);
		table.setRowSelectionAllowed(false);
		table.setColumnSelectionAllowed(true);
		table.setModel(new DefaultTableModel(
			new Object[][] {
				{null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null},
				{null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null},
				{null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null},
				{null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null},
				{null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null},
				{null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null},
				{null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null},
				{null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null},
				{null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null},
				{null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null},
				{null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null},
				{null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null},
				{null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null},
				{null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null},
				{null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null},
				{null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null},
				{null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null},
				{null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null},
				{null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null},
				{null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null},
				{null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null},
				{null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null},
				{null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null},
				{null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null},
				{null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null},
				{null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null},
			},
			new String[] {
				"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"
			}
		) {
			/**
			 * Java coughs up warnings if we dont do this
			 */
			private static final long serialVersionUID = 1L;

			public Class getColumnClass(int columnIndex) {
				return String.class;
			}

			public boolean isCellEditable(int row, int column) {
				return false;
			}
		});

		for(int i = 0; i < 26; i++) {
			table.getColumnModel().getColumn(i).setResizable(false);
			table.getColumnModel().getColumn(i).setPreferredWidth(20);
		}

	}
}

Moodlification

Moodle is an alright piece of software, but if you ever try to discuss code, it will mangle it and create a horrible mess.

To mitigate this, write your posts in HTML view, and paste your code as it appears after running it through this moodlify.php script:

#!/usr/bin/php
<?php
/* moodlify.php -- whitespace fixes for code to post on moodle */
if(!isset($argv[1])) {
    echo "Usage: " . $argv[0] . " [file]\n";
    exit(0);
}
$file = $argv[1];
if(!file_exists($file) || !$code = file_get_contents($file)) {
    echo "Could not open file: ".$argv[1]."\n";
    exit(1);
}

/* Series of find-replaces to strip whitespace */
$code = htmlentities($code); /* < > " ' etc */
$code = str_replace("\t", "    ", $code); /* Tabs (4 spaces)*/

$code = str_replace("  ", "&nbsp;&nbsp;", $code); /* Double-spaces */
$code = str_replace("\n", "<br />", $code); /* Newlines */
$code = "<div style=\"padding-left:4em;\"><code>".$code."</code></div>\n";

/* Output options */
if(isset($argv[2])) {
    file_put_contents($argv[2], $code);
} else {
    echo $code;
}?>

And moodle will never mangle your code again!

Update 2012-09-05 Corrected the above code due to out own CMS mangling the code, due to a workaround for this horrible (now deprecated) anti-feature.