Posts

Showing posts with the label Technology

The reasoning behind Lumberjack

So why, in 2009, in a world of RIA frameworks, web-based applications, and a wide variety of blogging engines to choose from, would I write a desktop application in Java targeted exclusively for one company's proprietary blog platform? First of all, it was tempting to write this as an Adobe AIR application. It would have fit my requirement that it be cross-platform and run as a desktop application, but I've never written anything with Adobe development tools before. Given the limited time I had on weekends to work on it, I wanted to get something written as quickly as possible rather than spending all my time learning a new platform. With Java, I could just hit the ground running, and it was just a matter of referencing the Swing-specific documentation. It boiled down to what was expedient and familiar because it would allow me to build something quickly. With respect to the issue of making this application web-based, the main point is that I didn't want to start up a br...

Introducing Lumberjack, a desktop client for Google Blogger

Earlier this year, I mentioned that I was working on a desktop application, a client for Google Blogger, written in Java with the Swing GUI toolkit. I recently found some time to work on the enhancements that I said I wanted to do during my last update, and I'm ready to release the application to the world. Get a ready-to-run file at the Lumberjack download page . Just download the JAR file, save it, and run it; it will work as long as you have a Java runtime installed. If you're running Windows, Mac OS X, or Linux, you probably do. If you have trouble logging in, you may have to solve a Google CAPTCHA first. You should only have to do it once. If you're a developer, you'll find the source code at the Lumberjack GitHub repository . Simply run ant to build the application. (Yes, I put a lot of effort into getting this one-step build working.) Patches, questions, and suggestions are most welcome. Just leave a comment on this post.

Automated summaries and excerpts

Image
You've seen them around the web: they're the blocks of text appearing under the headlines, giving you a little more information on what the linked article is about. If the headline didn't tell you enough, the summary or excerpt is supposed to serve as a sort of fall-back mechanism to tell you a little bit more. The websites of such longtime print titans such as The New York Times , The Economist , and The Wall Street Journal tend to have good summaries beneath their headlines. They know how summaries should be written — by hand. They are, after all, the professional producers of such content and have a vested interest in getting that content viewed. Those who are a few steps removed from the production of such content, on the other hand, make it readily apparent that they just don't care. Two of the most surprising offenders are Google and Apple — ironically, two media darlings who appear regularly in feature articles. A quick jaunt over to Google Finance gives us an ...

Lessons from refactoring

I enjoy the process of refactoring software — especially software that was written by other people. It forces me to understand things inside and out (which is a tough point to arrive at when all you do on that code is the occasional drive-by bug fix). On top of that, since the desired functionality is known already, it's all redesigning of the data model and writing code. There are fewer product-level questions that come up. The specification is pretty much set. For this particular project, though, I have the unique challenge of making the new design pass muster with multiple parties. People are picky and they always have something to say, so I took special care this time to anticipate any objections and address them so they'd get a better sense of my thought process. I've still had to make changes — and I make them gladly — but I've found that having to explain each decision I'm making generally serves to clarify my thought process. It certainly helps to have some ...

Blogger client as a Java Swing desktop application

Ever since I started using Blogger, I've been looking for a decent, no-nonsense desktop client to write my posts. I personally find it to be a lot of hassle to load up a big, heavy web browser and log in to Blogger to make my posts. (To be fair, Drivel was quite excellent in the past, but doesn't look like it's maintained anymore.) After a little poking around at Google's API documentation, I am pleased to announce that I'm writing this post from a desktop application of my own making. It's a Java desktop application using Swing, so it will run on Windows, Mac OS X, Linux, and any other major desktop platform with a Java runtime. So far, I can select from a list of blogs, write in post titles (to be friendly to those search engines), write post content, and submit new posts. It's really basic, but it's quite a milestone and a major motivator for me to at least have gotten this far. Soon to come on the feature front, I'm aiming for loading old posts ...

Ruby on Rails: optimizing a slow-rendering page

Recently at work, I was faced with the problem of fixing a slow-rendering page. The page is part of an internal content management system, where the content includes video, images, and text. We have over a thousand pieces of content being managed with this tool and the slow page was a listing of all the content along with key overview-type information for each content package. Everyone was fine with this page loading slowly, since we knew that there was a lot of content. The problem arose when the page would only show around 50 items and then stop loading; the server configuration was set to automatically stop requests that took too long to process. I knew that the best course of action would be to start measuring. I took a look at the logs to see how long the request was taking and the approximate tasks where time was being spent. At JibJab , we take pride in caching the hell out of everything. Only a tiny fraction of time was spent hitting memcached . And it looked as though memcache...

Colored bash prompt

The following will set a bash prompt to highlight the name of the directory in yellow, and in bold. export PS1="[\u@\h \[\033[1;33m\]\w\[\033[0m\]]$ " This will also work: export PS1='[\u@\h \[\e[1;33m\]\w\[\e[0m\]]$ ' The escapes have to be in single quotes, however. During a previous attempt, I wasn't terminating everything correctly, and so when my command exceeded the length of the row, it wouldn't wrap around and start a new line. It was not just a Mac OS X Terminal problem; I tried it in rxvt (installed via MacPorts) as well as the xterm that came standard with Leopard's X11.

Where software developers fear to tread, or why open source fails

Open source has had its triumphs and failures. The most notable wins include Eclipse , Linux, Apache HTTP server , MySQL , and Mozilla Firefox. Developer tools and server software are generally areas of strength for open source. I wouldn't say that Mozilla Firefox is an anomaly. Rather, it shares something in common with developer tools and server software: the programmers who work on it are also its users. Unfortunately, this is not the case with the gaps that open source has so far failed to close. A friend of mine recently asked me about my choice of spreadsheet software. We talked about it for a bit, and agreed that OpenOffice.org Calc is still clunky. I suggested Gnumeric , but I don't really hear anything notable going on with it these days. In short, I don't see an Excel killer in either of these. It's not for lack of vision that these spreadsheet projects have stagnated. It's for lack of sustained passion and developer interest in making these products world...

Foreign key cascade on update dangerous?

In relational databases there's a feature called foreign key cascading. Typically, there's an ID associated with each row, or entry, in a database table. Tables may refer to other tables using a foreign key, which typically refers to the IDs of the rows being linked. There are options to "cascade" on two kinds of operations: delete and update. When a table refers to another table, the table pointing to the other table can be configured to take changes in the ID of the original table and integrate them automatically. This is what happens when ON UPDATE CASCADE is set on a foreign key. When ON DELETE CASCADE is set on a foreign key, deleting rows in the original table will also delete rows that are pointing to that row. So, it's not hard to imagine situations where cascading on delete would be dangerous. Now a while ago, I was talking to a database specialist about cascading updates on foreign keys. He mentioned that they're dangerous, so I took his word for it...

Observations about making money from open source

Open source is a great thing and I've personally benefited tremendously from it. It has let me deepen my knowledge, given me entire software platforms to invest my energies in, and has opened up a wide landscape of job opportunities. For a company though, it's pretty challenging to make money from it, and I recently I got around to thinking what successful companies in open source have done. Arguably, Red Hat is the most successful open source software company out there. They came to mind not only because their product portfolio is mostly based on open source or that they've been around for a long time (relatively speaking), but because I actually use their products and find value that I willingly pay for. Good for them. But I wanted to figure out what it was they did in very general terms, because I'm definitely not going to try to take them head on. Open source software has its strengths and weaknesses, where the strengths and the value produced often tend to accrue t...

Growing responsibility on a solid base

People who cannot handle small, easy duties should not be entrusted with more power and responsibility. Basically, be faithful with the small things, and you will be entrusted with bigger and better things. I particularly like this lesson because I love the process of building and focusing on smaller tasks, but at the same time I've always been a big dreamer. As one would expect, though, I also experience that impatience to move on to the next step, even if I'm nowhere near ready. But that's the way the world works. I've been thinking too, that the ability to wield power and responsibility is not entirely intrinsic. True, you can be put in charge of small things as a test of your potential, which is a property that never changes, and it does serve as a way to winnow out the good from the bad. But I realized that the process and experience of handling the little issues and tiny problems is itself critical to bringing out any latent potential or untapped talent in peo...

Freedom is shabby and inconvenient

As much as we value liberty and tout the virtues of living in a free society, I humbly submit that eternal vigilance is not the only price we pay for our freedom. Anywhere there's freedom, you will find disorder, inconvenience, and shabbiness. We allow our freedoms to be restricted because we want some sort of orderliness, convenience, or good aesthetics. These are good things, but conceding to rigidity often means losing substance or meaning. Take homeowners' associations, for example. With pretty much any HOA, you cannot get away with painting your house bright pink, letting the weeds grow to four feet in your front yard, and then parking your car among the weeds. It may be how you prefer to live your life and run your household, but by joining the HOA you are giving up freedoms that you would otherwise have, in exchange for the assurance that your neighbor across the street will not paint his house a loud pastel purple, because pink is okay but purple is not. You may be fine...

JavaScript syntax highlighters

I'm really into writing documentation, and very often, this documentation must include code samples. I wanted a JavaScript syntax highlighter that: involved very little hassle in setting up, worked like a real parser using parse trees to ensure accurate highlighting, and provided decent coverage of the most common programming languages in use today. Obviously, by opting to go with a JavaScript syntax highlighter, I chose to forgo the option of doing my syntax highlighting on the server side. Doing it on the server side still interests me, but for immediate and practical reasons, the quickest way to get syntax highlighting in my documentation would be to do it on the client side. I went searching around for JavaScript syntax highlighters, and these are the top three that met my criteria. Javascript code prettifier . This was the first decent one that I found. It's pretty basic but I got up and running very quickly. The documentation is sparse and the tone of the README quite ter...

Where the rubber meets the road

Back when I was writing software that ran on HP LaserJet printers, I hated having to wait 45 minutes for one-line changes to compile (in a ClearCase build system) and then burn to flash memory. Sometimes, a problem with the printer's behavior wouldn't even be a problem with my software. It would sometimes be caused by an obscure bug in the hardware. Because of time to market pressures, the team would have to work with prototype hardware, the design of which wasn't even finalized yet. The guys who wrote the low-level code had to write some registers and hack their way around hardware defects. Somehow, it seemed wrong to me that I should constantly be worrying about the integrity of the underlying hardware or the operating system on which my software ran. I should have been able to take it for granted. I longed for the day when I could instead work on web applications, where I could safely assume that the hardware was fine and that there were no major defects with the platfo...

Physical media and bit rot

Last night, I played some of my old classical music CDs — good music to program to. The songs skipped every other second because of the scratches on the discs. It appeared that my careless handling of CDs over the years eventually caught up with me. Tonight, I ripped some of these to Ogg Vorbis (an open and royalty-free file format similar to MP3) to see if I could listen to my songs without the skipping. Sure enough, they were all smooth! Now, none of this is stuff that I'm terribly surprised about, but it just served as a reminder to me that relying only on physical media to store data is a little dangerous, especially when the medium goes bad or acts flaky. The lifetime of information on the network is short, but as long as it's out there, stored and accessed frequently, it's constantly being duplicated and refreshed. Information that's alive and circulating is healthy information.

Parsing lists of e-mail addresses

I came across a situation where I had to parse a list of e-mail addresses. E-mail clients these days take e-mail addresses in two forms: one showing the name of the individual as well as their e-mail address, and one with only the e-mail address. When multiple e-mail addresses are listed, they are separated by commas, whether they're of the full form or of the simple form. When I had to extract the list of e-mail addresses initially, I assumed only that I could separate them using commas. This would capture a list such as the following. "Joshua Go" <joshua.go@playpure.com>, joshuago@gmail.com It would capture two e-mail addresses: "Joshua Go" <joshua.go@playpure.com> and joshuago@gmail.com . A problem arose when I came across one form of the full e-mail address that threw off my simple parsing technique: the occurence of e-mail addresses such as "Go, Joshua" <go.joshua@yahoo.com> . Since I am no master of regular expressions, and wor...

Arrays in Visual Basic and classic ASP

For the programmer who is used to C-like syntax, working with arrays in Visual Basic or classic ASP can be aggravating. In this post, I will briefly go over declaring single- and multi-dimensional arrays, then iterating through them — the basic operations that make arrays useful. One-dimensional arrays Let's declare an array with six elements. Dim OneDimArray(5) Yes, that says "5", but it has six elements. When we're going through the elements of this array, we'll start counting from zero and end at five. Iterating through one-dimensional arrays For i = 0 to UBound(OneDimArray) Response.Write(i) Next There will be six elements iterated through. General notes about arrays in Visual Basic So far, we're left with the impression that Visual Basic is a strange language. When we declare arrays in VB, the real size is the declared array size plus 1. If you're used to programming in a C-like programming language such as C++ or Java, it's the declared array...

Accented characters with a US keyboard in X11

I've always been too busy to figure out how to map the useless Windows flag keys on my keyboard to do something useful in Linux/X11. On traditional Unix systems, there's a Compose key . According to Wikipedia, "On some computer systems, a compose key is a key which is designated to signal the software to interpret the next keystrokes as a combination in order to produce a character not found on the keyboard." To see what the Windows flag and menu keys are mapped to, I ran the following. xmodmap -pk | grep 11{5,6,7} This resulted in the following output: 115 0xff20 (Super_L) 116 0xff20 (Super_R) 117 0xffcc (Menu) This output told me that the flag keys (left and right) were free to map to Multi_key . I figured I would leave the menu alone. Next, I had to perform the remapping. I created a file, .Xmodmap , which is sometimes already there in a user's home directory. For me, it wasn't, so I went ahead and created .Xmodmap with ...

PDF bookmarks with LaTeX

After the mail fiasco was taken care of, I decided to pursue one of the things I've been wondering about: how to make PDF files have bookmarks (those links on the side pane that let you jump to well-defined sections of the document). For my setup, all I had to do was add this in my document: \usepackage[pdftex,bookmarks=true]{hyperref} Since I use Ubuntu, I had to install the tetex-extras package, which contains hyperref.sty for running pdflatex.

Thunderbird's "too many connections" message and Courier IMAP

When we use Mozilla Thunderbird at my workplace for our IMAP mail, Thunderbird often tells us that we have too many connections. It makes going through my folders impossible. This article explains that it's because Courier IMAP (which is used by Plesk) limits the number of connections from a single IP address to something like 4. Since we're all behind a firewall, we're all considered to be one user, as far as the server is concerned. I just had to change the values of MAXDAEMONS and MAXPERIP in /etc/courier-imap/imapd to allow more connections. Mozilla Thunderbird caches something like 5 connections by default, so even one user will put the IP past the limit. While I was figuring my way around this problem, I set up another server to copy my mail over. It's an Ubuntu machine and I just used the distribution's Courier IMAP, but since I've been using UW-IMAP all these years, the configuration process for getting a system user up and running was completely for...