So I’m hunting for a job right now. (See my résumé, also posted on the front page of this site, if you happen to be hiring coders who travel, eg as sales engineers. 🙂
I’ve been hunting on and off since, err, gosh, I guess since September of last year. At this point I’ve talked to at least a dozen companies — some just at the level of trading a couple e-mails before one of us decided the other wasn’t a good fit, all the way up to one whose (thankfully non-exploding) offer I’ve been sitting on for a while. I’m at various stages of the interview process with enough companies that I’ve stopped being able to keep track of them all in my head, and we jump between enough communications mediums (phone, e-mail, in-person interview) that I can’t rely on my e-mail client to keep it all together. I started thinking about this a few weeks ago, and I played around a bit with the free trial version of Salesforce.com, but it pretty quickly became obvious that Salesforce was way more complicated than I needed in some ways and not featureful enough in others. Also, expensive. But the cognitive load of keeping track of all of these opportunities was starting to be a serious stressor, so I knew I had to do something. Then came spring break this past week (yay unscheduled time!), and so I broke down and started writing my own CRM (well, Potential Employer Relationship Manager) to manage my job-hunt.
I sketched out the basic data model pretty quickly, and it was obvious from that that I was going to want a database to back the system. I wanted it to be web-based, because I was going to need to be able to access it from anywhere over the public Internet, so that meant a web framework of some kind. Python is my default language these days for projects which don’t obviously require something different (text processing? Perl; manipulating binary data? C), and I’d walked through the Django tutorial before, and knew I could get something up quickly, so those both seemed like good choices. I used Git for source control because it’s my default these days, and it’s so stupid-simple to set up a repository for something that I’ve stopped even thinking about it.
At the beginning, I laid out the key requirements of the system, which were:
- I wanted a dashboard view which would show me, on a single page, the status of every potential job opportunity I was tracking, so I could easily see who I needed to respond to and who I hadn’t heard from in a while and needed to poke.
- It needed to accept e-mail and use that to update the dashboard view.
- It also needed to support action items which weren’t e-mail messages, so I could eg. put my interview dates in the app.
- I needed integration in my mail client so I could quickly send entire threads to the app.
Partway into the project I realized that Django’s default support for schema migration is basically non-existent, so, since the details of the data format were still seriously in flux, I was going to potentially be rebuilding the entire state of my app from e-mail every few days. That added a couple more requirements:
- The app needed to save all e-mail sent to it outside the database so I could rebuild its state quickly.
- I needed tools in the app that would let me quickly categorize a large amount of e-mail.
I got the dashboard up very quickly, relying entirely on Django’s very nice built-in admin interface to handle the heavy lifting of actually creating objects in the database. After a false start trying to make the app run a custom SMTP server using Python’s built-in smtpd library, which didn’t seem to actually work, I realized that my MTA, Exim4, would pipe incoming mails to a process specified in a user’s .forward file, so I set up a username for the app to run under and got it accepting e-mail. Python’s built-in mailbox library let me easily create a secondary mail store for rebuilding, and I kludged the ability to forward threads to the app onto the Sup hook script I use to forward spam to my spam filtering provider. Then I built a form for categorizing messages, the biggest innovation of which is the “associate all other correspondance with this contact with this opportunity” button. That all was basically my week, and by the end of it I was able to process a few hundred e-mails into a dozen or so job opportunities in the span of twenty minutes or so, giving me a dashboard that looks like this (censored, obviously):
It is not very pretty — I’m not a web designer or a leet CSS+HTML haxxor, and it shows — but that’s not the point. Now I Bcc: my app on all the job-related e-mails I send, and I can see at a glance what I need to take action on.
The code is very very alpha right now, and needs docs, tests, everything you expect from software that wasn’t written over spring break by a hosed MIT student. I’ll clean it up and do something with it after I’ve graduated. I’ll also probably hack more on it as I need new features or find existing bugs — I’ve adopted kcr‘s rule that whenever I feel like accomplishing something by frobbing the database directly, I’ll instead write the code to automate the process. Right now it meets my minimum requirements, and I’m pretty happy with that.
A few observations on the tools I used, mostly Django (caveat: I’m using 1.0 because it’s what Debian stable has):
- Django is in fact awesome for rapid prototyping/development of web apps.
- Django would be even more awesome for rapid prototyping/development of web apps if it had any kind of discernable story around schema migration.
- The Django admin interface is awesome for rapid prototyping/development of web apps.
- The Django admin interface would be even more awesome for rapid prototyping/development of web apps if there were some middle ground between “using the admin interface” and “writing HTML forms by hand, sucker”.
- More generally, I was surprised and disappointed that the framework didn’t give me more help with the UI, or anything remotely AJAXy. (The app as it currently stands is AJAX-less. Too much work for too little reward.)
- Wow, Django is really big on keeping views and templates separate. I can’t embed arbitrary Python code in my templates. Weeeeeird.
- Django is blessedly well-documented and easy to pick up.
- Python is a language made for writing ORMs, and Django’s is a nice one.
- I’m impressed at the breadth of Python’s standard library. Everything I’d have gotten off CPAN if I were using Perl — eg. e-mail (RFC822) and mbox handling — was shipped with the Python interpreter. I didn’t have to pull in any external libraries besides Django.
- Not so impressive: the smtpd library shipped with the 2.5.something Python interpreter was poorly documented and didn’t seem to work. I expect better QA of things which are included in the standard distribution. (Though maybe that’s less reasonable to expect when everything is included in the standard distribution? I don’t know.)
It was a good learning experience and a pretty good use of my spring break. I’m now much less stressed about things falling through the cracks in my memory, which makes the entire project very much worth the time it took.
Now I just need to find a job. 😉