Thu Feb 24 16:38:48 PST 2011

AppEngine is pretty cool

Free hosting for webapps... python or Java, sweet.

Thrown up two apps already

I have another app that's used to track my passifox Firefox extension installs (user count and browser version) that takes only a few hundred lines. Delightful.

Wed Jan 28 21:05:51 PST 2009

Hooray Yakima, they've made good

It's been a few months since we lost the Trek 6700WSD (due to a defect in our superjoe rack), but Yakima has made good on the loss and reimbursed us for the cost of a replacement 6700WSD.

Thank you, Yakima. Their customer service is excellent.

Wed Aug 13 10:12:00 PDT 2008

A CHP response

This is a response I just received for my bike search from a CHP officer

Mr. Nguyen-

Thank you for spending the time to inquire about the incident in question. I have contacted the Monterey CHP Communications Center (831-796-2160) and received the following information (log #397).

On August 3, 2008 at approximately 1319 hours, a grey BMW was traveling northbound on US 101 just north of Coyote Creek Golf Drive, in the #1 lane. The vehicle struck a bicycle that had come to rest in the #1 lane and then the vehicle pulled over into the center divide. Upon the arrival of a tow truck, it was determined that a traffic break was necessary to move the vehicle over to the right shoulder. CHP arrived on scene and initiated the traffic break. US 101 was subsequently cleared. There was no police report requested by the involved driver. I am not certain as to where the debris was placed.

Please contact me if you have any further questions. Take care and drive safely!

Sincerely, Chris

California Highway Patrol
Officer Chris Armstrong
Public Affairs Officer
XXX.XXX.XXXX Office
XXX.XXX.XXXX Fax
XXXXXXXX@chp.ca.gov

Sat Aug 09 13:18:01 PDT 2008

Did anyone hit or see a bicycle on the shoulder on 101N (Sunday 8/3, Gilroy/Morgan Hill)

I originally posted this to craigslist on 8/5

A bicycle fell off of my Yakima SuperJoe2 on Sunday, August 3, between 1 and 2pm while heading northbound on 101 in the fast lane somewhere between Leavesley in Gilroy and the 85N junction. It possibly could have fallen off on the carpool bridge to 85N and I didn't really notice until just before Cottle rd. on 85. My best guess is that it fell off somewhere near the Coyote Creek Golf course, maybe around Cochrane or Bailey.

I sincerely hope no one got into an accident because of the bicycle. However, I need evidence of this loss in order to file an insurance claim. If your vehicle was involved, it may be possible to subrogate.

The bike was a 2005 Trek 6700 WSD (silver mountain bike with disc brakes)

Thu Feb 28 09:58:32 PST 2008

Integrating GNU Screen copy/scrollback mode with the local system clipboard

GNU Screen is a great UNIX tool, allowing a single terminal session to multiplex and manage multiple virtual terminal windows. As a long time user of screen, over 10 years, one of the features I frequently use is the copy/scrollback mode. Oftentimes, I wish this mode had better integration with the system clipboard.

Copy/Scrollback mode (CTRL-A ESC) in screen allows you navigate the buffer of screen's virtual terminals using vi-like keybindings (hjkl, etc). An additional feature of this mode is the ability to mark portions of text in the buffer to be copied into screen's internal clipboard. This internal clipboard is only usable for writing to a preconfigured filename (CTRL-A >) or using a screen command to paste (CTRL-A ]) into a virtual terminal.

I recently came across a blog article touting the benefits of using screen on Mac OSX. One of the sections described "Copying to the Mac Clipboard" using OSX's built-in pbcopy command to integrate screen's copy buffer with the Mac's own system clipboard. This inspired me to come up with a similar solution for use on Windows.

My solution is more complex than simply using a command line program as I often will start screen sessions on remote systems and would still like to maintain the integration with the local system clipboard. pbcopy can't do this. X11 users have it easy with the xclip program, using forwarded X11 sessions with ssh, it is trivial to integrate remote screen copy-buffer with the local clipboard. Windows doesn't have any answer to this problem at all.

First, I wrote a small Java program to listen on a TCP port (4573) and forwards all data received into the local system clipboard; the program is called Clipboard Listener and source is available under the GPL. The program can be minimized to the system tray or notification area to be as unobtrusive as possible. It displays a notification bubble whenever new data is received on port 4573.

Next, there is a small shell script (copy-to-clipboard) which invokes netcat (nc), commonly available on Linux systems and easily installed if not found. Replace CLIPBOARDLISTENERHOSTNAME with localhost (in ssh) or the host upon which the clipboard listener is running on.

#!/bin/sh

if [ -z "$1" ]; then
    echo "Usage: copy-to-clipboard <file>"
    exit 1
fi
nc CLIPBOARDLISTENERHOSTNAME 4573 < "$1"

Third, we setup screen to invoke the copytoclipboard script upon our screen selection. Add or edit the following lines into $HOME/.screenrc; replace /PATH/TO/ with the appropriate locations.

# Buffer file is where the screen copy buffer will be saved to.
bufferfile /PATH/TO/screen-copy-buffer
bind y eval "writebuf" "exec /PATH/TO/copy-to-clipboard /PATH/TO/screen-copy-buffer"

Alternatively, instead of using the copy-to-clipboard wrapper, nc can be invoked directly using the following bind. I use the former rather than the latter because I may attach to a certain screen session from more than a single host; I will edit copy-to-clipboard to point to the appropriate host, rather than change the screen keybinding.

bind y eval "writebuf" "exec sh -c 'nc CLIPBOARDLISTENERHOSTNAME 4573 < /PATH/TO/screen-copy-buffer'"

Basically with those steps done, we have completed our integration of screen and the system clipboard. Additional steps have to be taken when integrating remote sessions via ssh (adding the flag -R 4573:localhost:4573). With the integration complete, we can now use the y (named after vi's yank) binding to forward screen's copy buffer into the local system clipboard (CTRL-A y). You can now use your system's paste functionality (such as CTRL-V) into any application which supports it. The clipboard listener application is portable across platforms, you should be able to use this technique on OSX as well if you have a desire to integrate remote screen sessions.

Note: If you use an escape key other than CTRL-A for screen (I use CTRL-O), substitute CTRL-A with your choice of escape key.

Thu Dec 27 18:50:17 PST 2007

My password manager, SCURP

4042

What is it

SCURP (SeCURePassword Manager) is a new password manager application I have written. It is intended to run cross-platform (Windows, Linux, OSX and whatever else that can run Java and, optionally, Firefox), and contain more functionality than what is contained within Firefox's own password manager. SCURP is still undergoing changes and should be considered beta software, at best. It should not lose or corrupt any data, however bugs are inevitable.

It is an open source application, and sources are available.

What it does

SCURP is an application that will allow you to store all of your private information and passwords in a secure, central location. All information is stored within an encrypted file (currently 128bit AES in CBC [cipher-block-chaining] mode) protected by a master password (SHA1 with 40bit RC4 password encryption).

Passwords are never stored as cleartext even while the file is decrypted. They are always stored in memory as ECB-mode ciphertext and only decrypted on-demand for short uses. This gives protection against casual memory analysis. Intensive analysis can reveal the encryption key used to encrypt the database, although I believe this to be quite difficult. The memory location of the encryption key must be discovered and then access to the appropriate pieces of data must be found.

Connectivity

The password manager has multiple methods for interacting with external applications. The most basic interaction is through the system clipboard. Another method of interaction is through the use of AutoType. The most advanced interface is through a custom Web Service.

Fri Nov 30 23:37:06 PST 2007

Some other recent applications

While we're on the topic of tools, I've also written several personal webapps aside from this CMS.

Pastebin

My own pastebin; a tool used to take text and put it up on the web for collaborative debugging efforts. Mine, however, takes it a few steps further: I also have features for laying out Graphviz diagrams, and taking screenshots of your desktop without any additional application requirements (beyond the usual Java plug-in). There's also a convenient command-line interface, written in Python, that can be used to paste text directly from a shell prompt without having to copy into a browser.

You can try it and view the sources

Anonimail

Anonymous one-time email addresses, send an email to somearbitrarystring@anonimail.hanhuy.com and it ends up on a web page at http://www.hanhuy.com/anonimail/somearbitrarystring. It's basically a copy-cat of the mailinator concept. I just thought I'd try and implement it myself. Basically, I setup a single IMAP mailbox that receives all emails for the anonimail.hanhuy.com domain, then there's a webapp that parses the IMAP folders (using JavaMail) and presents the resulting emails to the web.

Check it out -- sources to come sometime in the future.

Poker Hand Paster

I like to play online poker, and I like to revel in reviewing bad beats and the really stupid plays I make. Trying to make myself a better player and all. I've written web interfaces into the PokerOffice and PokerTracker databases. The databases are parsed and hands evaluated to detail a blow-by-blow of the plays.

It's bad in a way that it lets people see what hands I play after-the-fact. Maybe I should restrict access to myself, but that isn't a concern right now.

The pokeroffice and pokertracker databases are currently separate, but I would like to aggregate them into a federated view. The pokeroffice view is still linked directly to MySQL running on my workstation and is often offline. The pokertracker view is running against PostgreSQL on my server and is always online. Source

MMS Relay/Moblog app

Seeing as how everyone's got camera phones these days, and there are sites that let you take pictures from your phone and relay them directly to the web; I thought I would try something similar. I've basically read the WAP MMS specification and created a simple MMSC that is able to accept images.

To use this application, one would need to reconfigure one's phone to use a special MMSC, but it's not a big deal unless one likes to send MMS messages to other phones as well (do people do that often?). I don't use it much, personally, but I'd like to make more frequent use of it. Sources

Fri Nov 30 10:00:14 PST 2007

Simple tools showcase

I've had these written for a long time now, but I guess I'll put a mention in for them now.

  1. A stopwatch, I use this as a cooking timer and for whenever I need a simple watch to keep track of a few minutes or hours with an alarm. Source.

  2. An amortization calculator--I was thinking about buying some property, but disliked the web-based TVM calculators out there, so I went and wrote my own for fun. The calculator can estimate payments, interest rates, and also create a printable chart that details interest paid, principal values over time, etc. Source 3607

  3. The piece-de-resistance, my rich internet application interface to this journal and image gallery (CMS). This program lets you browse, modify, upload, and write to this website from a convenient desktop application using normal desktop semantics such as drag and drop. Like this CMS, the application is an ongoing work-in-progress. Hopefully I'll make a demo site sometime in the future. Source 3603

They are examples of Java Web Start and will require an installed Java (1.5 or newer) run-time in addition to acceptance of my personal certificate.

Thu Aug 16 19:12:13 PDT 2007

Using XUL and GridBagLayout in Java?

Lately, I have been developing an extension for Firefox and I've really taken a liking to how it separates UI design with XUL and CSS. Developing Java UIs feels so cumbersome in comparison.

Now, what if we could somehow meld XUL and GridBagLayout together? I have some thoughts, but no idea how well it would work. Imagine if we could write the following:

ExampleXulLayout.xul:

<layout>
  <hbox>
    <box id="label-1"/>
    <hbox id="textbox-1" flex="1"/>
  </hbox>
  <vbox>
    <box id="label-2"/>
    <box id="textfield" flex="1"/>
  </vbox>
</layout>

This should end up looking something like my poor text rendition below:

+--------------------------------------------+
|                                            |
| Textbox-1's label ________________________ |
|                                            |
| Description:                               |
| +----------------------------------------+ |
| |                                        | |
| |                                        | |
| +----------------------------------------+ |
|                                            |
+--------------------------------------------+

The source code that works with the XUL to produce the above would look like the following:

ExampleXulLayout() {
    JPanel panel = new JPanel();
    panel.setLayout(new XULGridBagLayout("ExampleXulLayout.xul"));

    JLabel label1 = new JLabel("Textbox-1's label");
    panel.add(label1, "label-1");

    JTextField title = new JTextField();
    panel.add(title, "textfield-1");

    JLabel descLabel = new JLabel("Description:");
    panel.add(descLabel, "label-2");

    JEditorPane pane = new JEditorPane();
    panel.add(pane, "textarea");
}

This would be equivalent to the below if we were using GridbagLayout directly:

GridBagConstraints c = new GridBagConstraints();

c.gridx = 0;
c.gridy = 0;
panel.add(label1, c);

c.gridx = 1;
c.gridy = 0;
c.weightx = 1.0;
panel.add(title, c);

c.gridx = 0;
c.gridy = 1;
c.weightx = 0.0;
panel.add(descLabel, c);

c.gridx = 1;
c.gridy = 1;
c.weightx = 1.0;
c.weighty = 1.0;
c.gridwidth = 2;
panel.add(pane, c);

Does this sound like a good idea? Could it be useful or even usable?

Mon Apr 30 11:23:05 PDT 2007

Wow, this works... (A bean property annotation for Java)

Ok, I've added a few more features (the ability to call an external method prior to actually setting the value). I've also found out that there will not be any IDE support available yet. Netbeans will not have JSR269 support until 6.0, and Eclipse will not have the support until 3.3. Bummer.

Right now this works with javac from JDK 6, need to try it in various IDEs to see if it will work as well. (Yes, I understand this is against the specification for JSR269 [no preprocessing annotations]).

[pfnguyen@ares panno]$ ls
A.java  B.java
[pfnguyen@ares panno]$ cat A.java
import com.hanhuy.panno.Property;

import java.sql.SQLException;

public class A {
    private @Property String fool = "I pity the foo!";
    private @Property boolean alwaysRight = false;

    private @Property(useGet = true) boolean booleanWithGet = false;

    // preCallMethod can also point to another object, e.g. "someObject.method"
    @Property(preCallMethod = "genericValidator",
              preCallThrows = "SQLException")
    private int constrainedProperty = 42;

    public A() {
        System.out.println("A<init>: " + getFool());
    }

    private void genericValidator(
            A source, String property, int oldValue, int newValue)
    throws SQLException {

        System.out.println(
                "Attempting to modify '" + property + "' to " + newValue);

        if (newValue != 54)
            throw new SQLException(
                    "This is some arbitrary exception: " + newValue);
    }
}
[pfnguyen@ares panno]$ cat B.java
import java.sql.SQLException;

public class B {
    public static void main(String args[]) {
        A a = new A();
        System.out.println(a.getFool());
        a.setFool("I am not a fool");
        System.out.println(a.getFool());
        System.out.println(a.isAlwaysRight());
        a.setAlwaysRight(true);
        System.out.println(a.isAlwaysRight());
        System.out.println(a.getBooleanWithGet());
        System.out.println(a.getConstrainedProperty());
        try {
            a.setConstrainedProperty(54);
        }
        catch (SQLException e) {
            System.out.println("This should not happen yet!");
        }
        try {
            a.setConstrainedProperty(42);
        }
        catch (SQLException e) {
            System.out.println("Got expected exception: " + e.getMessage());
            e.printStackTrace();
        }
    }
}
[pfnguyen@ares panno]$ javac -cp ~/development/panno/build/hanhuy-panno.jar *.java
[pfnguyen@ares panno]$ java -cp . B
A<init>: I pity the foo!
I pity the foo!
I am not a fool
false
true
false
42
Attempting to modify 'constrainedProperty' to 54
Attempting to modify 'constrainedProperty' to 42
Got expected exception: This is some arbitrary exception: 42
java.sql.SQLException: This is some arbitrary exception: 42
        at A.genericValidator(A.java:28)
        at A.setConstrainedProperty(A.java:13)
        at B.main(B.java:21)
[pfnguyen@ares panno]$ javap A
Compiled from "A.java"
public class A extends java.lang.Object{
    public A();
    public void setFool(java.lang.String);
    public java.lang.String getFool();
    public void setAlwaysRight(boolean);
    public boolean isAlwaysRight();
    public void setBooleanWithGet(boolean);
    public boolean getBooleanWithGet();
    public void setConstrainedProperty(int)       throws java.sql.SQLException;
    public int getConstrainedProperty();
}