jwzhacks

work
Mosaic Netscape
1994-1995
Back before you had heard of Netscape, I was responsible for the Unix versions of Netscape Navigator through release 1.1.
Netscape
Mail & News

1995-1996
Next, I designed, and Terry Weissman and I implemented, the Netscape Mail and News clients, versions 2.0 through 3.0. This was our contribution to the proof of the Law of Software Envelopment:
``Every program attempts to expand until it can read mail. Those programs which cannot so expand are replaced by ones which can.''
S/MIME
1996-1997
Netscape 4.0 was not my fault. During that dark period, I worked with Lisa Repka on S/MIME, Netscape's implementation of the then-new standard for cryptographically secure email. At the time, I was very glad that we managed to ship this before the U.S. Government had gotten around to making it illegal for us to do so. (And yet, all these years later and still nobody ever encrypts their email...)
Grendel
1997
After that, Terry, Will Scullin and I wrote Grendel, a mail/news reader implemented in Java. Sadly, the project was cancelled before we could finish it. (But we threw the source over the wall in 1998 anyway.)
Mozilla Dot Org
1998-1999
Next, I was one of the folks who created and ran the Mozilla Organization during the first year of its life: mozilla.org was the division of Netscape responsible for releasing the Navigator source code and coordinating the open source development of the browser, which eventually became Firefox. I resigned from both mozilla.org and from (what came to be known as) the Netscape division of America Online just before AOL took over.
Lucid Emacs
1991-1994
Before Netscape, I was primarily to blame for Lucid Emacs, the next generation of the GNU Emacs text editor / development environment / lisp system / religion. Lucid finally managed to go bankrupt, and lucid.com was melted down for scrap metal shortly thereafter. You can find the latest version of lemacs, now called XEmacs, at www.xemacs.org. (Click here for further evidence of why cooperation with RMS is impossible.)
DNA Lounge
1999+
But in 1999 I took my leave of that whole sick, navel-gazing mess we called the software industry. Now I'm in a more honest line of work: now I sell beer.

Specifically, I own the DNA Lounge nightclub in San Francisco. You can read all about it on my now-more-than-a-decade-long blog. We run audio and video webcasts twenty-four hours a day, so runnning the club does involve quite a lot of software, all of which is also available.
DNA Pizza
2011+
Oops, I seem to have opened a pizza restaurant!

play
XScreenSaver
1992+
A huge collection of free screen savers for X11 and MacOS. This is the standard screen saver collection shipped on almost all Linux and Unix systems.
Dali Clock
1991+
A melting digital clock for Unix, MacOS, iPhone, PalmOS and WebOS. When a digit changes, it "melts" into its new shape.
WebCollage
1999+
A program (and web page) that generates collages from randomly-selected images on the web, updated about once a minute.
jwzlyrics
2013
Displays the lyrics for the currently-playing track in iTunes or Spotify. Can also bulk-download lyrics for multiple tracks. There are many like it. This one is mine.
DadaDodo
1997-2003
A dissociator: a program that collects statistics on bodies of text, and then generates random text based on those numbers. (There is a web version here, too.)
Base64
Shortlinks

2011
A WordPress plugin that makes your shortlinks shorter, by encoding 7+ digit post IDs into 4 characters, and using a shorter URL prefix.
Tip Calculator
2009
My first (and last) Palm Pre application, a restaurant tip calculator.
XKeyCaps
1992-2005
A (now-obsolete) program for re-mapping your keyboard on Unix.
Linux Kiosks
2000-2009
For many years, my nightclub DNA Lounge included public internet kiosks; this page explains how I constructed and secured them.
gallery
2001+
This generates static HTML photo galleries with thumbnails. For an example of what it looks like, see the DNA Lounge photo galleries.
picturetile
2005
This program takes a bunch of images and randomly tiles them into one large image. The images need not be of the same size or aspect ratio. Back when I used a film camera, I used to cover one of my walls with snapshots, but now that I use a digital camera, I no longer have prints lying around. I wrote this program to make it easy to cover my wall with digital prints in the form of large posters.
Gronk
2001-2005
(Now-obsolete) MP3 Jukebox software for Unix, from the days before I used iTunes.
Cheesegrater
2002-2004
A selection of tools for "screen-scraping" web pages to create RSS feeds. Back in the days before every web site provided an RSS feed, this was useful for creating your own feeds from their HTML.
lightlab
2002
X11 only. This is a hybrid GTK/OpenGL program for experimenting with the OpenGL lighting model. It lets you set colors and positions of lights and see what effect they have on a textured, rotating teapot.
gsendmail
2000-2004
X11 only. Obsolete. This is a simple standalone GUI mail composition tool for Unix. The 4.0-era versions of Netscape and early versions of Mozilla and Firefox didn't do anything sensible by default when you clicked on a mailto: link. This program could be used as the handler for those URLs.
BBDB
1991-1995
In 1991, I wrote this program, "The Insidious Big Brother Database", which was an address-book and note-taking system that was tightly integrated with the Emacs mail and news readers. It was pretty popular until 1997 or so when even the last hold-outs stopped reading their mail in Emacs.

marginal hacks
The following are mostly small utility scripts, rather than full-fledged applications. These are tools that I wrote for myself to fill a personal need. This means that they are not necessarily very polished, but possibly you'll find some of them useful. Please take most them in the context of "one-hour hacks that have lived on far longer than expected."
twit-backup
2014
Backs up your Twitter direct-message conversations to the local disk, one text file per person with whom you have conversed. (Note that while Twitter provides a way to download an archive of your public posts, that archive does not include your DMs.)
youtubefeed
2013
Reads a list of RSS feeds and download every Youtube or Vimeo video mentioned in them, using youtubedown. It keeps a list of already-downloaded URLs to avoid repeats. Also has a killfile.
ics-diff
2013
Compare two .ics (iCal) files, and emit one with the events that are in the first but not the second.
slowcat
2000-2013
This program reads files and copies their contents to stdout at an arbitrary bitrate, along with other bells and whistles. It's basically the heart of a streaming audio server: you want to serve data at audio rates, not full network rates.

Other features include: inserting metadata either in Icecast/Shoutcast style, or with a synthetic ID3 tag; limiting the output to a byte range across the whole set of files to implement HTTP "Byte-Range" audio seeking; and bursting out the first few seconds of the output to fill the client's first buffer quickly.
Herp Derp
2012
A WordPress plugin that herps all the derps. All comments are replaced with "herp derp". You may find that this makes my blog easier to read. You may find that it makes your blog easier to read.
ics-handler
.scpt

2012
Many sites (like Facebook) let you export events as .ics files which you can import into iCal; however, sometimes those imported events are not editable. This application will munge them into editability prior to importing them into iCal. Open the .scpt file in the AppleScript Editor, save it as an Application, and make that application be the default application for .ics documents.
scrape-sxsw
2012
Reads the schedule for the SXSW Music festival, intersects it against highly-rated tracks in your iTunes, and generates an iCal calendar file of bands of interest.
Curtain
2012
I built an Arduino-based controller so that I can open and close my apartment's curtains from the command line. This is the source code and a description of the hardware.
video-replaygain
2011
This adjusts the audio volume on a video file to the "correct" volume by re-encoding the audio track. The video track is untouched. This is sometimes necessary because iTunes does not provide sufficent control over playback volume of video files. (This script is flaky because ffmpeg is flaky. Check the output carefully for changes in aspect ratio and audio sync.)
video-bbox
2011
This tells you what the interior bounding box of a movie is, so you can tell which ones have hardcoded letterboxing in them. It also prints the bounding box, which you can then enter into a program like MPEG Streamclip to crop and re-encode them. (This script is flaky because it uses the very flaky mplayer to extract frames.)
munge videos
.scpt

2008+
This is an iTunes AppleScript to process newly-imported music videos. Among other things, it: marks the track as being a "Music Video"; sets the "Comments" field to the resolution in pixels of the video; sets the "Volume Adjustment" based on the video's overall audio volume; copies the year, genre, rating, and capitalization from older versions of this same track; and adds this new track to the playlists of an old track that it appears to be intended to replace; and the old version is marked as to-be-deleted.
itunes-rsync
2011
For doing a partial one-way sync of iTunes libraries, using rsync, ssh and AppleScript. This script gets the contents of a playlist in the local iTunes, and ensure that those tracks (and only those tracks) exist in the library of the remote iTunes, with identical metadata.
itunes-dj-nanny
2011
A cronnable script to make some executive decisions about what is and isn't allowed to remain in the "ITunes DJ" playlist as a result of anonymous user "Play Next" requests. It limits the length of the queue of upcoming songs, and only allows N songs by a single artist to remain in the queue, to prevent poor decision-making by the public.
itunes-growl
2011
You'd think the "Music Video" display mode in Growl would work with iTunes when it is playing music videos... well, it doesn't. This script, plus a patch to Growl itself, is needed to make it behave sensibly and display the name of the video that has just started, or is just about to end.
file-receiver
2011
Let's say someone has mailed you an attachment, and you need to move that file up to your web server. Let's say you're reading your mail on an iPhone or iPad. Since Mobile Safari doesn't support the <input type=file> form element, there's no easy way to accomplish that. However, with this script, you can configure a secret email address that will unpack any attachments sent to it into a directory of your choosing.
wppost.php
2010
This is a command-line utility for posting to a WordPress blog. Unlike the XMLRPC interface, this does not necessitate storing the clear-text password of a WP user in a file; it relies on normal Unix access control instead.
facebook-rss
2010
This script can create an RSS feed of your Facebook stream, your friends' photos, etc. This indignity is necessary because the RSS feeds that Facebook provides barely work. Also includes a killfile for users or apps.

Can also back up your Facebook private messages to the local disk.
fbmirror
2010
This script can mirror posts to your Twitter account into your Facebook account. There are other ways to accomplish this (using Facebook apps or RSS feeds) but I find this more reliable. Longer explanation on my blog.
ljgrabber
2010
This script downloads an archive of your Livejournal and its comments. It can be used to import your LJ into a WordPress blog. It can also be used to set all of your posts older than a certain age to "no new comments allowed".
jwz.nnwstyle
2010
This is a theme for NetNewsWire that makes the display of your feeds be green-on-black, just like the Internet was intended to be. Unzip it and place the "jwz.nnwstyle" directory in ~/Library/Application Support/NetNewsWire/StyleSheets/ then select "jwz" from the Themes menu in the lower left.
jwz-nnw.js
2010
Some Greasemonkey-like Javascript to modify NetNewsWire's display, to make feeds from Youtube and Flickr more usable. Links to Youtube videos are converted to embeds; and Flickr thumbnail images are converted to full-sized images. To install, add
<script language="javascript" src="http://www.jwz.org/hacks/jwz-nnw.js" />
to your NNW theme, e.g., in the file
Library/Application Support/NetNewsWire/StyleSheets/jwz.nnwstyle/template.html
reeder-jwz
2012
Likewise, if you use Reeder as your news reader, this makes the display of your feeds be green-on-black. Put this somewhere and add @import url('that-URL') to the top of the article.css file deep inside of Reeder.app.
ljpost
2008+
This is how I post to my blog via email. It takes an incoming mail message, extracts the images and saves them to a directory of your choice, then constructs HTML from those images and the rest of the message, and posts that to WordPress, Livejournal and/or Twitter. If there are images and they have location data in them, it marks the post with that location. It also allows you to write your text using Markdown instead of HTML.
youtubedown
2007+
Given a YouTube or Vimeo URL, downloads the underlying video file, with a sensible file name. It downloads the highest resolution version of the video available: first it tries HD MP4, then regular MP4, then WebM, and finally FLV. It also works on playlists, and works as a bookmarklet to download the video you're watching.
mp3dir
2007+
This is a CGI that gives your web server prettier directory listings for directories full of MP3 files: instead of just listing the file names, the directory listing will include the ID3 data for name, artist, album, etc. It will also include a link to generate a zip file for each directory.
itunes-recent
2006
Generates a static HTML page listing the music that has been added to your iTunes library in the last 90 days. It does this by interrogating the running iTunes via AppleScript. (It's possible to generate such a list manually from iTunes by creating an "added in the last 90 days" smart playlist and exporting the list; but this script is suitable for use from cron.)
jwz-html-mode.el
1997
A dead-simple HTML-editing mode for Emacs. I hate the HTML mode that XEmacs uses by default: it does too much second-guessing of my typing (automatically inserting matching close-tags before I've typed them and crap like that.) This is the minimalist HTML mode that I use: it has a proper syntax table, correct paragraph delimiter, and basic, restrained use of font-lock patterns.
bookmarklets
2004+
A few bookmarklets (clickable JavaScript functions) that manipulate the URL of the page you're looking at:

[ up ]     Go up one directory.
[ + ]     If the URL contains a number, increment it.
[ - ]     If the URL contains a number, decrement it.
validate
2003+
A small HTML validator: really all this does is make sure your tags are balanced, that your tables aren't missing TRs around the TDs, and that the local files that any relative URLs point to exist. There are much more fully-featured validators out there, but I haven't found them very useful: when all I want to know is "you left out a </UL>", they tend to spend their time whining at me about "where's your DTD?" and similar nonsense.
check-links
2000-2003
I guess everybody has written their own version of this; well, here's mine. This script checks for dead and/or moved links in the given HTML files. It parses the HREFs out of the HTML, then does a GET on each of them (not a HEAD, because that doesn't work with all sites) and prints out a list of URLs that were not retrievable, or that redirected to elsewhere.
http10proxy
2008
Have you ever wanted to run a really, really old web browser, like one from 1994? I have. If you have, you may have discovered that they don't work with most modern web servers, because they spoke HTTP/1.0 instead of HTTP/1.1. Specifically, they don't send a "Host" header, and don't understand the "charset" parameter in "Content-Type". However, if you point one of these antique browsers at this proxy server, it will translate. (To run those old browsers on modern Linux systems, you'll also need some old libraries.)
sms-backup
-iphone

2010
A perl script that extracts the log of SMS messages from an iPhone (actually, from the iPhone's backups inside iTunes) and logs the messages to text files, with one file per conversation per month (analagously to the way most AIM and IRC clients archive things, instead of just dumping it all into one file). It's careful to never delete old archived messages, even if the phone's SMS log has shrunk or vanished.
sms-backup
2006
The older, PalmOS version: A perl script that runs sms2csv to extract the log of SMS messages from a Palm Treo and logs the messages to text files.
google-itunes
2006
There are a zillion programs out there that will try to automatically download album artwork for iTunes tracks, mostly by searching Amazon or the Apple store, but I've found that just feeding the artist and album name into Google Images and dragging the images in by hand is the most reliable way. This script gets the list of selected tracks from iTunes, and opens multiple browser windows running Google image searches.
id3-clean
2007
This perl script walks through a directory of MP3 files and deletes any ID3v2 frames that aren't used by iTunes. I found that I had a lot of useless crap in my MP3 metadata, left there by whatever software happened to rip them or touch them in the past. This removes all the cruft that iTunes can't edit (since if iTunes can't edit or display it, it might as well not exist).
id3-check
2007
This perl script walks through a directory of MP3 files and points out trivial spelling differences in band names, e.g., if sometimes you used "Pixies" and sometimes used "The Pixies".
emlx
2005
A parser for the (undocumented) .emlx mailbox files used by Mail.app on MacOS X 10.4+. You can use this to convert Mail.app mailboxes back into standard BSD "mbox" files, for importing into other software.
mvpix
2005-2008
When I used Linux, this script was how I got pictures off of my digital camera. It files each image that it moves from the card into an appropriate directory of the form YYYY-MM-DD, and does some clever tricks to divide multiple "sessions" on the same day into different directories: e.g., when 30+ minutes has passed between photos, it starts a new directory. It works on both Linux and MacOS X, though these days I use Lightroom.
ppmcaption
2001-2004
This is a program adds text to images in PPM files. These days you should just use ImageMagick instead, but when I wrote this, that wasn't fast enough for my purposes.
rotimg
2008
Losslessly rotates a JPEG image (using jpegtran). Preserves (and updates) the existing EXIF data, if any, including also losslessly rotating the embedded thumbnail image.
tuner
2006
This script provides remote control of Denon tuners (e.g., Denon AVR 2805, 2313CI and similar) via their ethernet or serial port. It speaks the AVR/AVC control protocol language, and lets me, among other things, change the volume on my stereo by typing things like "tuner volume=-30dB".
cvslogall
2005
This script is like "cvs log", except it also shows you the modifications made in each checkin by running "cvs diff" on each two adjacent versions. This is a way of seeing every checkin made to a given file, along with the log message for each checkin.
galdown
2006-2011
Given a URL of a photo gallery, this downloads the largest versions of all of the photos. It understands the gallery formats used on Flickr, Facebook, Picasa, OvaHere, Google Drive, SF Weekly (and related sites), Instagram, and sites using SmugMug or Zen Folio. It's easily extensible for new idiosyncratic gallery formats.
wgetn
2004
A wrapper for wget to download numerically contiguous URLs based on a format string; for example, "wgetn http://host/img_%04d.jpg 201 299" to download img_0201.jpg through img_0299.jpg. Especially useful when trying to mirror galleries that have stupid directory structures (where simply using --mirror would download too much.)
mirror
2004
A wrapper for wget that automatically computes a proper --cut-dirs value based on the number of directory components in the given URL. E.g., "mirror http://host/A/B/C/" will use --cut-dirs=3, meaning that /A/B/C/D/E/index.html will become D/E/index.html.
pf-mode.el
2004
An Emacs mode for editing OpenBSD "pf.conf" files, with font-lock highlighting.
resizeimg
2004
Resizes all of the image files passed on the command line to fit within the given bounding rectangle, and rotate them to be upright if necessary. Any existing EXIF data is preserved.
mork
2004
This script lets you extract the URLs from your Mozilla history file, sorted by last access time. There were scripts to do this with every version of Netscape Navigator, because it stored history in a straightforward Berkeley DBM file. Sadly, the Mozilla folks saw fit to replace that with a brand new database called "Mork" for which no tools exist. So I wrote this to parse Mork and spit out the URLs. Mork sucks.
scrmable
2003
I raed a scrmabled-up peice of text taht cliamed that
    "it deosn't mttaer in waht oredr the ltteers in a wrod are, the olny iprmoetnt tihng is taht the frist and lsat ltteer be at the rghit pclae. The rset can be a total mses and you can sitll raed it wouthit a porbelm. Tihs is bcuseae the huamn mnid deos not raed ervey lteter by istlef, but the wrod as a wlohe."
so I worte tihs scrpit to scrmbale txet in taht way. Hey, it wroks!
multalt
2002
This script converts an HTML document into a multipart/alternative mail message, with a text/plain first part, and a text/html second part. It produces very readable text/plain parts.

The most interesting part of this script is that it contains a simple HTML parser that does a reasonable conversion of HTML to plain text. It handles most interesting tags: it does nested indentation for UL, OL, BLOCKQUOTE, etc; it handles PRE; it handles character entities; it wraps paragraphs. (It does not, however, handle TABLEs.)

Quoted-printable encoding will be used when necessary. When QP is used, lines are broken at word boundaries instead of merely every 72 characters: this means that the QP-encoded text will be highly readable in raw form, unlike most QP text you've probably run across in the past.
jwz-lj.el
monkeybutter.el

2002-2009
This is how I used to post to my blog, back in the day. jwz-lj.el is a simple Emacs mode for posting to LiveJournal. There was a Livejournal mode for Emacs already, but it doesn't work with XEmacs, so it was of no use to me... Closely related is monkeybutter.el, which is built on top of it and is geared toward re-blogging web pages.
irc2html
2000-2013
Paste your raw chat logs into this web page, and it will convert them to pretty HTML with wrapped lines, clickable links, inlined images and so on. Works with IRC, AIM, text messages, whatever. Can produce HTML that looks like iPhone-like chat bubbles.
copyright-image
1998
This script slaps a copyright notice into the comment field of a JPEG, TIFF, or GIF image, by using wrjpgcom or giftrans, as appropriate. Update: Now it also writes the copyright info into the EXIF data, using exiftool. (Note that Canon RAW files are actually TIFFs, so it works on those too.)
gdb-highlight.el
1997
This is a package that makes Emacs's gdb-mode much more usable by making almost everything that shows up in the *gdb* buffer be clickable, and have a context-sensitive pop-up menu of commands on the object that have been printed. (Some people, when confronted with a problem, think "I know, I'll use regular expressions." Now they have two problems.)
jack
1997
A predecessor of the XJack hack from XScreenSaver; I won't spoil the joke, but will instead just tell you: ``man sh | jack''.
nntp-to-mbox
1997
Have you ever wanted to convert the contents of a newsgroup into a mail folder? I did once, and so that's what this script does. Point it at your news server, tell it what group you want, and optionally, what message to start at, and it will write out a properly-quoted mbox file (the kind used by Netscape, Eudora, and just about all of the Unix mail readers.)
folderstat
1997
This is a script that prints out some statistics about the messages in an mbox folder, e.g., to show who the most prolific posters to a mailing list are. It prints out a table of stats sorted several different ways.
worth
1996-1998
Do you hate your job? Are you only still there because you're waiting to vest? I feel your pain, brother. The only thing that kept me from leaving Netscape in 1997 and walking away from a dumptruck full of cash in frustration was this script. I ran this every morning for at least a year: it prints out the following motivational message:
    Today's NSCP price is $__._; your total unsold shares are worth $____. You are __._% vested, for a total of ____ vested unsold shares ($____). But if you quit today, you will walk away from $____.

    Hang in there, little trooper! Only _ years __ months __ days to go!
It's amazing how this script can put it all back into perspective and keep you from going postal and strangling someone. Fill in your numbers, and let it remind you not to do something you'll regret later.

As I'm not maintaining this any more, you may also be interested it a descendant of it over on dzm's site. He's added more features.
audio-tape.ps
1988-1994
This prints j-cards for cassettes, cartridge tapes, 8mm tapes, DATs and CD jewel cases. It does all kinds of automagic font scaling and has the ability to include graphics. It is implemented completely in PostScript. This was one of the first popular programs I ever distributed online, way back in 1988. I haven't touched this since 1994, when I stopped using cassette tapes.
video-tape.ps
1988-1991
The companion PostScript program for printing labels for VHS video cassettes. Last modified: 1991.
Lisp Machines
1985-1993
Back before the Computing Dark Ages of the Nineties began, I hacked on Lisp Machines. If you've still got an Explorer or Symbolics, you might find some of the stuff I wrote in the good old days useful. It's archived in the CMU AI Repository.

© 1985-2014 Jamie Zawinski <jwz@jwz.org>
so much to do, so little time.