# HG changeset patch # User Steve Losh # Date 1261619960 18000 # Node ID 4ac1bf2cbaa2bd7e01ca603e32e266b02c2c84dd # Parent cf38a58b19270c17d2b1996d88b6b7e8e360eca2 Add the project content. diff -r cf38a58b1927 -r 4ac1bf2cbaa2 content/projects/django-hoptoad.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/content/projects/django-hoptoad.html Wed Dec 23 20:59:20 2009 -0500 @@ -0,0 +1,211 @@ +{% extends "_post.html" %} + +{% hyde + title: "django-hoptoad" + snip: "Now ponies can ride the toad too." + created: 2009-07-25 01:16:40 +%} + +{% block article %} + +django-hoptoad is some simple Middleware for letting [Django][]-driven +websites report their errors to [Hoptoad][]. Now [ponies][] can ride the toad +too. + +You can get it from [the repository on BitBucket][repo]. + +[Django]: http://djangoproject.com/ +[Hoptoad]: http://hoptoadapp.com/ +[ponies]: http://djangopony.com/ +[repo]: http://bitbucket.org/sjl/django-hoptoad/ + +[TOC] + +Requirements +------------ + +django-hoptoad requires: + +* [Python][] 2.5+ (preferably 2.6+ as that's what I've tested it with) +* [PyYAML][] (`pip install pyyaml` or `easy_install pyyaml`) +* [Django][] 1.0+ +* A [Hoptoad][] account + +[Python]: http://python.org/ +[PyYAML]: http://pyyaml.org/ + +Installation +------------ + +Grab the the django-hoptoad code by cloning the [Mercurial][] repository (or +just [download the latest version][tip-dl] and unzip it somewhere): + + hg clone http://bitbucket.org/sjl/django-hoptoad/ + +There's a git mirror too if you *really* want it. + + git clone git://github.com/sjl/django-hoptoad.git + +Once you download it, you can install it in the usual manner: + + cd django-hoptoad + python setup.py install + +If you'd prefer to be able to update at any time by pulling down changes with +Mercurial or git, you can symlink the module into your `site-packages` +directory instead of using `python setup.py install`: + + ln -s /full/path/to/django-hoptoad/hoptoad /full/path/to/site-packages/ + +To make sure it works you can run: + + python -c 'import hoptoad' + +[Mercurial]: http://mercurial.selenic.com/ +[tip-dl]: http://bitbucket.org/sjl/django-hoptoad/get/tip.zip + +Usage +----- + +To set up a Django project to notify Hoptoad of its errors, you need to do two +things in the `settings.py` file. + +First, add the `HoptoadNotifierMiddleware` as the last item in your +`MIDDLEWARE_CLASSES` setting: + + MIDDLEWARE_CLASSES = ( + # ... other middleware classes ... + 'hoptoad.middleware.HoptoadNotifierMiddleware', + ) + +Next, you'll need to add a `HOPTOAD_API_KEY` setting. You can get the key from +the Hoptoad project page. + + HOPTOAD_API_KEY = 'Your Hoptoad API key.' + +Optional Settings +----------------- + +There are a few extra things you can configure if you'd like to tweak the +notification process a bit. + +### Notify Hoptoad While in DEBUG Mode + +By default the Middleware will **not** report errors to Hoptoad when your +project is in `DEBUG` mode. The idea behind this is that if you can already +see the error information right in the browser you probably don't need to see +it in Hoptoad too. If you want to always notify Hoptoad of errors, even while +in `DEBUG` mode, add the following setting: + + HOPTOAD_NOTIFY_WHILE_DEBUG = True + +### Specify a Default Timeout + +The notification middleware will make sure the error notification gets to +Hoptoad before the response gets sent back to the user. If it takes a while to +contact Hoptoad the user will notice a delay. + +By default, the amount of time the notifier will wait before giving up is +Python's "global default timeout setting". I have no idea what that is because +the [documentation][urllib2docs] does not see fit to explain that to me. + +If you'd like to change that amount you can use the `HOPTOAD_TIMEOUT` setting. +You **must** be running Python 2.6+ to use this. + + HOPTOAD_TIMEOUT = 5 + +The number is the number of seconds the notifier will wait before timing out. +Yes, you can use a float like `0.5` to specify fractions of a second. + +[urllib2docs]: http://docs.python.org/library/urllib2.html + +### Track 404 Errors + +By default Hoptoad will **not** be notified of 404 (page not found) errors. If +you'd like to change this you'll need to add the following setting: + + HOPTOAD_NOTIFY_404 = True + +**IMPORTANT**: If you are using Django's `flatpages` app and want to track 404 +errors, you need to make sure the `FlatpageFallbackMiddleware` comes *after* +the `HoptoadNotifierMiddleware`. If you don't do this Hoptoad will be notified +of 404 errors even if the user actually sees a Flatpage. + +To track 404s while using the `flatpages` app your `MIDDLEWARE_CLASSES` +setting should look like this: + + MIDDLEWARE_CLASSES = ( + # ... other middleware classes ... + 'hoptoad.middleware.HoptoadNotifierMiddleware', + 'django.contrib.flatpages.middleware.FlatpageFallbackMiddleware', + ) + +A couple of things to note: + +* If your website doesn't have a favicon specified most browsers will request it each time. This will result in one (or possibly two, if it tries to append a slash) 404 errors for every page view. +* At the moment all 404 errors are grouped together as "similar" errors in Hoptoad. I am trying to figure out what causes this. + +### Track 403 Errors + +By default Hoptoad will **not** be notified of 403 (forbidden) errors. If +you'd like to change this you'll need to add the following setting: + + HOPTOAD_NOTIFY_403 = True + +Note: + +* At the moment all 403 errors are grouped together as "similar" errors in + Hoptoad. I am trying to figure out what causes this. + +### Ignore Specific User Agents + +If you'd like to ignore all errors from certain User Agents you can use the +following setting: + + HOPTOAD_IGNORE_AGENTS = ['MSIE 6.0', 'Trident'] + +If any of the strings in the list appear *anywhere* in the User Agent string, +Hoptoad will not be notified of the error. + +The strings are actually regular expressions, so you can be more specific if +you like: + + HOPTOAD_IGNORE_AGENTS = [r'^Mozilla.*compatible; MSIE \d+\.\d+.*$'] + +One thing this is useful for (aside from hating on IE) is ignoring errors from +web crawlers. Often bots will mangle URLs and if you're tracking 404 errors +you'll see a *lot* of errors that you probably don't care about. + +This would probably be a good starting point for ignoring crawlers: + + HOPTOAD_IGNORE_AGENTS = ['Googlebot', 'Yahoo! Slurp', 'YahooSeeker'] + +Troubleshooting +--------------- + +If things don't go smoothly, the first thing to do is run the tests to see if +they can determine what's wrong. To enable the tests you'll need to add +django-hoptoad to your `INSTALLED_APPS` setting: + + INSTALLED_APPS = ( + # ... other apps ... + 'hoptoad', + # ... other apps ... + ) + +Once you've done that you can run the unit tests: + + python manage.py test hoptoad + +**NOTE**: The unit tests are very simple at the moment. I'm working on more, +but please feel free to submit ideas (or better yet: patches). + +Suggestions +----------- + +This Middleware is a work in progress. If you have a suggestion or find a bug +please [add an issue][issues] or post a comment and let me know. + +[issues]: http://bitbucket.org/sjl/django-hoptoad/issues/?status=new&status=open + +{% endblock %} \ No newline at end of file diff -r cf38a58b1927 -r 4ac1bf2cbaa2 content/projects/fuego.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/content/projects/fuego.html Wed Dec 23 20:59:20 2009 -0500 @@ -0,0 +1,22 @@ +{% extends "_post.html" %} + +{% hyde + title: "Fuego" + snip: "Photographs of Alex. Studio." + created: 2009-01-19 01:25:20 +%} + +{% block article %} + + + +I really like how these turned out. One of them is hanging in my apartment. + +{% endblock %} \ No newline at end of file diff -r cf38a58b1927 -r 4ac1bf2cbaa2 content/projects/grabtweets.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/content/projects/grabtweets.html Wed Dec 23 20:59:20 2009 -0500 @@ -0,0 +1,77 @@ +{% extends "_post.html" %} + +{% hyde + title: "grabtweets" + snip: "A simple tool for backing up your tweets." + created: 2009-09-12 11:02:46 +%} + +{% block article %} + +`grabtweets` is a simple tool to backup your tweets. + +The code is in a [Mercurial repository][repository] on [BitBucket][]. + +[BitBucket]: http://bitbucket.org/ + +[TOC] + +Installing +---------- + +`grabtweets` requires [Python][] 2.6 or later. + +To install it, you can [download][] the latest version, or clone the Mercurial +repository: + + hg clone http://bitbucket.org/sjl/grabtweets/ + +You can put it anywhere you like. + +Using +----- + +`grabtweets` can back up your tweets and print tweets that it has already +archived. + +### Backing Up Tweets + +To back up your tweets, run `grabtweets` like this: + + $ grabtweets.py -u USERNAME FILE + +`grabtweets` will pull down the 200 newest tweets from USERNAME and store them in FILE. + +You probably have more than 200 tweets. However, Twitter will only let you +pull down 200 at a time and hitting the server too fast will result in Twitter +cutting off your access for a while. + +To deal with this, it's best to set up `grabtweets` as a cron/launchd job that +runs every couple of hours. Each time it runs, it will pull down the newest +200 tweets, plus 200 older tweets if there are any available. + +It will take about `NUMBER_OF_TWEETS_YOU_HAVE/200` runs to finish archiving +your tweets. Just set it up and forget about it. + +### Printing Backed Up Tweets + +To print the tweets that `grabtweets` has already backed up, run it like this: + + $ grabtweets.py -p FILE + +[Python]: http://python.org/ +[download]: http://bitbucket.org/sjl/grabtweets/get/tip.zip + +Problems, Contributing, etc +--------------------------- + +`grabtweets` was hacked together in an hour. There are probably bugs. If you +find any, go ahead and create an issue in the [issue tracker][]. + +Want to fix something or add a feature? Great! Fork the [repository][] and +send me a pull request. + +[issue tracker]: http://bitbucket.org/sjl/grabtweets/issues/?status=new&status=open +[repository]: http://bitbucket.org/sjl/grabtweets/ + +{% endblock %} \ No newline at end of file diff -r cf38a58b1927 -r 4ac1bf2cbaa2 content/projects/hg-paste.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/content/projects/hg-paste.html Wed Dec 23 20:59:20 2009 -0500 @@ -0,0 +1,73 @@ +{% extends "_post.html" %} + +{% hyde + title: "hg-paste" + snip: "Send diffs from Mercurial to various pastebin websites." + created: 2009-09-16 17:52:55 +%} + +{% block article %} + +hg-paste adds an `hg paste` command to Mercurial which can send diffs to +various pastebin websites for easy sharing. You can grab the code from the +[repository][] on BitBucket. + +It was inspired by [Pocoo][]'s [hgpaste][pocoopaste] extension, but is +designed to work with public pastebin websites instead of private +installations of [LodgeIt][]. + +[Pocoo]: http://www.pocoo.org/ +[pocoopaste]: http://dev.pocoo.org/hg/hgpaste/ +[LodgeIt]: http://dev.pocoo.org/projects/lodgeit/ + +[TOC] + +Installing +---------- + +Clone the repository: + + hg clone http://bitbucket.org/sjl/hg-paste/ + +Edit the `[extensions]` section in your `~/.hgrc` file: + + [extensions] + paste = (path to)/hg-paste/paste.py + +Using the Command +----------------- + +To paste a diff of all uncommitted changes in the working directory: + + hg paste + +To paste the changes that revision `REV` made: + + hg paste -r REV + +To paste the changes between revisions `REV1` and `REV2`: + + hg paste -r REV1:REV2 + +If any files are specified only those files will be included in the diffs. + +Several options can be used to specify more metadata about the paste: + + hg paste --user Steve --title 'Progress on feature X' --keep + +The pastebin website to use can be specified with `--dest`. Currently only +[dpaste.com](http://dpaste.com/) and [dpaste.org](http://dpaste.org) are +supported. + +Questions, Comments, Suggestions +-------------------------------- + +If you find any bugs, please create an issue in the [issue tracker][issues]. + +If you want to contribute (support for more pastebin websites would be great), +fork the [repository][] on BitBucket and send a pull request. + +[issues]: http://bitbucket.org/sjl/hg-paste/issues/?status=new&status=open +[repository]: http://bitbucket.org/sjl/hg-paste + +{% endblock %} \ No newline at end of file diff -r cf38a58b1927 -r 4ac1bf2cbaa2 content/projects/hg-prompt.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/content/projects/hg-prompt.html Wed Dec 23 20:59:20 2009 -0500 @@ -0,0 +1,167 @@ +{% extends "_post.html" %} + +{% hyde + title: "hg-prompt" + snip: "A Mercurial extension for adding repository info to your shell prompt." + created: 2009-06-19 22:25:17 +%} + +{% block article %} + +hg-prompt adds an 'hg prompt' command to Mercurial for viewing repository +information. It's designed to be used in a shell prompt. You can grab the code +from [the repository on BitBucket](http://bitbucket.org/sjl/hg-prompt/). + +Here's what it looks like: + +![My bash prompt while using hg-prompt.](http://stevelosh.com/site-media/storage/projects/2009-06-19-hg-prompt/hg-prompt.png "My bash prompt while using hg-prompt.") + +[TOC] + +Requirements +------------ + +hg-prompt requires Python 2.5+ and (obviously) Mercurial. + +Installing +---------- + +Clone the repository: + + :::text + $ hg clone http://bitbucket.org/sjl/hg-prompt/ + +Edit the `[extensions]` section in your `~/.hgrc` file: + + :::text + [extensions] + prompt = (path to)/hg-prompt/prompt.py + +Using the Command +----------------- + +The `hg prompt` command takes a single string as an argument and outputs it. +Here's a simple (and useless) example: + + :::text + $ hg prompt "test" + test + +Keywords in curly braces can be used to output repository information: + + :::text + $ hg prompt "currently on {branch}" + currently on default + +Keywords also have an extended form: + + :::text + {optional text{branch}more optional text} + +This form will output the text and the expanded keyword **only** if the +keyword successfully expands. This can be useful for displaying extra text +only if it's applicable: + + :::text + $ hg prompt "currently on {branch} and at {bookmark}" + currently on branch default and at + + $ hg prompt "currently on {branch} {and at {bookmark}}" + currently on branch default + + $ hg bookmark my-book + + $ hg prompt "currently on {branch} {and at {bookmark}}" + currently on branch default and at my-book + +Available Keywords +------------------ + +There a number of keywords available. If you have any suggestions for more +please let me know. + +* **bookmark:** the current bookmark (requires the [bookmarks][] extension) +* **branch:** the current branch +* **node:** the (full) changeset hash of the current parent +* **node|short:** a short form of the changeset hash of the current parent +* **node|merge:** the (full) changeset hash of the changeset you're merging with if you're currently merging, otherwise nothing. +* **node|merge|short:** a short form of the changeset hash of the changeset you're merging with if you're currently merging, otherwise nothing +* **patch:** the topmost currently-applied patch (requires the mq extension) +* **patch|count:** the number of patches in the queue +* **patch|applied:** the number of currently applied patches +* **patch|unapplied:** the number of unapplied patches in the queue +* **rev:** the repository-local changeset number of the current parent +* **rev|merge:** the repository-local changeset number of the changeset you're merging with if you're currently merging, otherwise nothing +* **root:** the full path to the root of the current repository, without a trailing slash +* **root|basename:** the directory name of the root of the current repository. For example, if the repository is in `/home/u/myrepo` then this keyword would expand to `myrepo`. +* **status:** `!` if the repository has any changed/added/removed files, otherwise `?` if it has any untracked (but not ignored) files, otherwise nothing +* **status|modified:** `!` if the current repository contains files that have been modified, added, removed, or deleted, otherwise nothing +* **status|unknown:** `?` if the current repository contains untracked files, otherwise nothing +* **status|modified|unknown:** `!` if the current repository contains files that have been modified, added, removed, or deleted, *and* `?` if it contains untracked (and not ignored) files, otherwise nothing +* **tags:** the tags of the current parent, separated by a space +* **tags|SEP:** the tags of the current parent, separated by `SEP` +* **task:** the current task (requires the [tasks][] extension) +* **tip:** the repository-local changeset number of the current tip +* **tip|node:** the (full) changeset hash of the current tip +* **tip|node|short:** a short form of the changeset hash of the current tip +* **update:** `^` if the current parent is not the tip of the current branch, otherwise nothing. In effect, this lets you see if running `hg update` would do something. + +[bookmarks]: http://mercurial.selenic.com/wiki/BookmarksExtension +[tasks]: http://bitbucket.org/alu/hgtasks/wiki/Home + +Remote Status Keywords +---------------------- + +There are several keywords available to monitor the status of remote +repositories. Because this can be an expensive operation if the remote +repository is across a network, they cache their results in +`.hg/prompt/cache/`. The cache is updated roughly every fifteen minutes. + +* **incoming:** this keyword prints nothing on its own. If the default path contains incoming changesets the extra text will be expanded. For example: `{incoming changes{incoming}}` will expand to `incoming changes` if there are changes, or nothing otherwise. +* **incoming|count:** the number of incoming changesets if greater than 0 +* **outgoing:** this keyword prints nothing on its own. If the current repository contains outgoing changesets (to default) the extra text will be expanded. For example: `{outgoing changes{outgoing}}` will expand to `outgoing changes` if there are changes, or nothing otherwise. +* **outgoing|count:** the number of outgoing changesets if greater than 0 + +Putting it in a Bash Prompt +--------------------------- + +To put it in your bash prompt, edit your `~/.bashrc` file to include something +like this: + + #!bash + hg_ps1() { + hg prompt "{ on {branch}}{ at {bookmark}}{status}" 2> /dev/null + } + + export PS1='\u at \h in \w$(hg_ps1)\n$ ' + +`source ~/.bashrc` after to test it out. Make sure you're in a Mercurial +repository or you won't see anything. This little prompt will give you +something like this: + + steve at myhost in ~/src/hg-prompt on default at feature-bookmark? + $ + +How about something a little more interesting? + + hg_ps1() { + hg prompt "{[+{incoming|count}]-->}{root|basename}{/{branch}}{-->[+{outgoing|count}]}{ at {bookmark}}{status}" 2> /dev/null + } + + export PS1='$(hg_ps1)\n\u at \h in \w\n$ ' + +And the result (this example assumes one incoming changeset and two outgoing): + + [+1]-->hg-prompt/default-->[+2] at feature-bookmark + steve at myhost in ~/src/hg-prompt + $ + +Questions, Comments, Suggestions +-------------------------------- + +The code was kind of thrown together in one night after I got tired of +chaining three or four hg runs together to get what I wanted. I'm sure it's +not perfect, so if you've got a way to improve it please [add an +issue](http://bitbucket.org/sjl/hg-prompt/issues/) and let me know. + +{% endblock %} \ No newline at end of file diff -r cf38a58b1927 -r 4ac1bf2cbaa2 content/projects/hgtab.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/content/projects/hgtab.html Wed Dec 23 20:59:20 2009 -0500 @@ -0,0 +1,114 @@ +{% extends "_post.html" %} + +{% hyde + title: "hgtab" + snip: "Smarter tab completion for Mercurial in bash." + created: 2009-03-10 20:22:44 +%} + +{% block article %} + +hgtab was created to provide smarter tab completion for Mercurial in bash. + +**UPDATE**: Apparently there's already [tab completion in +Mercurial](http://www.selenic.com/hg/file/11efa41037e2/contrib/bash_completion)! +It's way better than this, *use that*! It should probably be better documented +though – I posted this yesterday and it's already the top four results +for "mercurial tab completion" on Google... + +If I've missed something you'd really like tab completed, post an issue on the +issue tracker and I'll do my best to implement it. My bash scripting skills +are almost non-existent, so if you improve this (or port it to another shell) +feel free to send a pull request! + +You can download hgtab from its [BitBucket +repository](http://source.stevelosh.com/hgtab/). + +## Installing + +All you need to do to use hgtab is source it. There are three ways to do this, +ranging from easy and ugly to slightly less easy and more elegant. + +### OPTION 1: Easy, Ugly + +Copy the contents of hgtab-bash.sh into your ~/.bashrc file. + +### OPTION 2: Harder, Less Ugly + +Download hgtab-bash.sh and place the following line somewhere in your +~/.bashrc file: + + source ~/path/to/hgtab/hgtab-bash.sh + +### OPTION 3: Hardest, Elegant + +Clone this repository somewhere with this command: + + hg clone http://bitbucket.org/sjl/hgtab/ + +Add the following line to your ~/.bashrc file: + + source ~/path/to/hgtab/hgtab-bash.sh + +If you use this method you can update the file by pulling down the changes +from this repository: + + cd ~/path/to/hgtab + hg pull + +## Using + +Once hgtab is sourced it'll add some nifty tab completion features in your +shell. For example, you can tab complete Mercurial commands: + + #!console + sjl at grendel in test $ hg re + recover remove rename resolve revert + sjl at grendel in test $ hg re + +When you're using a command that wants a revision as a parameter, hitting tab +will complete on tags (and bookmarks) and branches. + + #!console + sjl at grendel in test $ hg branches + blue 20:f05ca6eb51a1 + red 16:8262f0345f41 (inactive) + default 15:67f959b8deb8 (inactive) + sjl at grendel in test $ hg book + * dev-1.0 20:f05ca6eb51a1 + sjl at grendel in test $ hg tags + tip 20:f05ca6eb51a1 + dev-1.0 20:f05ca6eb51a1 + beta 18:f3ab9bf730f7 + alpha 17:ca802019f04f + + sjl at grendel in test $ hg update + alpha beta blue default dev-1.0 red tip + sjl at grendel in test $ hg update b + beta blue + sjl at grendel in test $ hg update b + + sjl at grendel in test $ hg diff -r b + beta blue + sjl at grendel in test $ hg diff -r b + +It will also complete remote paths when you're pushing or pulling. + + #!console + sjl at grendel in test $ hg paths + alice-dev = http://alice-dev + alice-stable = http://alice-stable + bob = http://bob + default = ssh://hg@bitbucket.org/sjl/hgtag/ + + sjl at grendel in test $ hg push + alice-dev alice-stable bob default + sjl at grendel in test $ hg push + + sjl at grendel in test $ hg pull alice- + alice-dev alice-stable + sjl at grendel in test $ hg pull alice- + +Enjoy! + +{% endblock %} \ No newline at end of file diff -r cf38a58b1927 -r 4ac1bf2cbaa2 content/projects/index.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/content/projects/index.html Wed Dec 23 20:59:20 2009 -0500 @@ -0,0 +1,6 @@ +{% extends "skeleton/_listing.html" %} + +{% hyde + title: "Projects" + exclude: True +%} \ No newline at end of file diff -r cf38a58b1927 -r 4ac1bf2cbaa2 content/projects/lindyjam-com.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/content/projects/lindyjam-com.html Wed Dec 23 20:59:20 2009 -0500 @@ -0,0 +1,152 @@ +{% extends "_post.html" %} + +{% hyde + title: "lindyjam.com" + snip: "A page for a local weekly swing dance event (and more)." + created: 2009-01-21 18:28:35 +%} + +{% block article %} + +A few days ago I released the new [Lindy Jam][] website. Lindy Jam is a weekly +swing dance in Rochester, NY. I wanted to create a site that was useful for +those that attend the event but also more than just a "here's when it is and +how to get there" page. + +[Lindy Jam]: http://lindyjam.com/ + +![lindyjam.com screenshot](/site-media/storage/projects/2009-01-21-lindyjam/lindyjamcom-splash.png "Screenshot of the Lindy Jam site.") + +Design +------ + +Let me preface this section by saying: "I'm not a graphic designer." Yes, I +appreciate good design and typography, but I simply haven't studied it as much +as I'd like. That might change in the future, but for now I'll make due with +the knowledge I have. + +There are very few images used on the site; the background stripes and the +splash page photo(s) comprise all of them. I did this for a few reasons: + +* It saved me time. +* The site loads faster. +* The site scales to larger or smaller sizes very gracefully. + +I tried to keep things as clean as possible while still being useful. Comments +and error messages are displayed immediately, without reloading the page. This +makes it easier to see what you've done (or what went wrong) right off the +bat. + +I'm not 100% pleased with how it came out, but it will do until I learn more +about design. If you have advice or suggestions about the design, please +[email me][]! + +[email me]: mailto:steve@stevelosh.com + +Pages +----- + +### About + +The most important part of the site is probably the [About][] page, because it +tells people when and where the event happens. It's as simple and to the point +as I could make it so people can get the information they're looking for right +away. It's linked right from the splash page so it's easier to find. + +[About]: http://lindyjam.com/about/ + +### DJ Schedule + +Another important piece of the site is the [DJ Schedule][] page. Every week +someone can sign up to DJ the event. They get in for free, and we get to hear +a wider variety of music. The schedule page makes it easy to sign up for a +week in the near future. + +When you sign up to DJ you can also enter your email address or cell phone +number (or both) if you'd like to be reminded. I know that sometimes I've +almost forgotten to bring my laptop (and arrive right on time), so I hope that +this feature will be useful to other DJs too. + +[DJ Schedule]: http://lindyjam.com/schedule/ + +### Blog + +One thing I believe our Lindy Hop scene lacks is a place for people to write +thoughtful, well-crafted articles about the scene. I hope the Lindy Jam +[Blog][] can become such a place. + +It's a fairly simple blog; entries and comments are written in [Markdown][] so +authors don't need to know HTML to make their articles look nice. Anyone can +comment without signing up for anything, so I hope people will take advantage +of that and discuss the articles. + +[Blog]: http://lindyjam.com/blog/ +[Markdown]: http://daringfireball.net/projects/markdown/ + +### Links + +Most sites like this have a list of links to other sites that their viewers +might be interested in, and this site is no different. The [Links][] page is a +simple, clean list of links that anyone can contribute to. If someone knows of +a great page we haven't listed, they can submit it and it will appear on the +page as soon as it's been approved. + +[Links]: http://lindyjam.com/links/ + +### Quotes + +Along the top of every page is a random quote. Right now there aren't very +many, but I hope that people will submit some more by going to the [Quotes][] +page or by text messaging them to . + +I think the quotes add a more personal touch and allowing anyone to add one +can really make it a "community" site. + +[Quotes]: http://lindyjam.com/quotes/ + +### RSS + +We nerds love our [RSS][] feeds, so I've implemented a couple of different +feeds that people can use to stay up to date. + +[RSS]: http://lindyjam.com/rss/ + +Implementation +-------------- + +The site was built with [Django][] because it makes it very, very easy to get +a dynamic site like this up and running quickly. I use [Fabric][] to deploy it +(check out [this +entry](http://stevelosh.com/blog/entry/2009/1/15/deploying-site-fabric-and-mercurial/) +on my personal blog for more information about that). All of the fancy effects +use [jQuery][] so I can avoid programming them from scratch in javascript (and +tearing my hair out). + +One thing I would do differently if I were to design the site all over again +is use a CSS framework like [Blueprint][]. I used Blueprint for my personal +site and it made things far, far easier than writing the layout in CSS from +scratch. I definitely recommend it if you want to keep your sanity. + +The site itself is hosted on [WebFaction][]. I use them to host my own site +too and they're fantastic. Setting up a Django or Rails (or any other type) of +site is quick and easy, and they're very cheap. If you're looking for a web +host you should check them out. + +The site is open source if you'd like to take a look at what makes it tick. +You can browse or download the code from the [Mercurial repository][] on +BitBucket. + +[Django]: http://djangoproject.com/ +[Fabric]: http://www.nongnu.org/fab/ +[jQuery]: http://jquery.com/ +[Blueprint]: http://www.blueprintcss.org/ +[WebFaction]: http://www.webfaction.com/signup?affiliate=sjl +[Mercurial repository]: http://bitbucket.org/sjl/lindyjam/ + +Feedback +-------- + +If you have any comments or questions about the site please let me know! You +can post them here or [email me][]. + +{% endblock %} \ No newline at end of file diff -r cf38a58b1927 -r 4ac1bf2cbaa2 content/projects/stevelosh-com.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/content/projects/stevelosh-com.html Wed Dec 23 20:59:20 2009 -0500 @@ -0,0 +1,101 @@ +{% extends "_post.html" %} + +{% hyde + title: "stevelosh.com" + snip: "This website." + created: 2009-01-11 15:40:26 +%} + +{% block article %} + +For a long time I used [Squarespace][] to create and host my personal website. +It's a great service, and I highly recommend it to anyone that needs a simple, +easy, beautiful site. + +Recently, however, I've started learning more and more about web design and I +decided to completely revamp my website and build it myself from the ground +up. This is the result. + +Design +------ + +I like simplicity. In all areas of my life (music, dancing, photography, +programming, design, etc) I'm striving to make everything I do as simple, +clean, and elegant as possible. That's why I went with such a minimal design +for the site. + +I haven't used any graphics in the layout for a few reasons. First, I'm not +very good at making them. Second, I want the site to load quickly, even on +phones, and scale gracefully for accessibility. Third, I wanted the interface +to be as uncluttered as possible so the content of the site would be front and +center. + +I also stuck to a minimum of color. The only items that have any color on the +site are any photographs that I post and the links. I did this because I'm not +a graphic designer and so I haven't studied color enough to know how to use it +well. + +One last thing I tried to keep in mind was sticking to a baseline rhythm for +some elements of the site. The home page, blog entry list, and project list +all line up with the links in the right sidebar. I think it gives the layout a +more stable feel. + +Implementation +------------ + +This website was written in [Python][] using the [Django][] framework. Django +makes it really easy to write useful web apps quickly and cleanly. I love it. + +[Blueprint][] kept me sane while writing the CSS. Grid layouts are no longer a +nightmare! + +I rely pretty heavily on [Markdown][] throughout the site. The blog entries +and static pages are all written in Markdown and parsed to XHTML later. This +might not be the fastest way to do things but processor time is cheap and my +time isn't. + +The Markdown-based editor and preview for commenting is the wonderful [WMD][]. +It's clean, simple, and does exactly what I want it to do. Most of the other +Javascript magic comes from [jQuery][]. I use the [jQuery form validation +plugin][form validation] in a couple of places to make checking input easier. + +For site statistics I'm relying on the fantastic [Mint][]. It's got a gorgeous +interface and is absurdly simple to install. Plus it's hosted on my own host +so I have control. It's also just a one time fee, unlike some other site stat +packages that charge monthly. + +My development process is pretty simple. I use [TextMate][] to edit the code +and a [Mercurial][] repository to store it and protect against accidents. To +deploy, I push my local changes to a private repository on [Bitbucket.org][], +and then use [Fabric][] to pull those changes down to the server and restart +if necessary. + +The site is hosted by [WebFaction][]. If you're looking for a web host for +Django or Rails sites (or any other kind, really) you should definitely +consider them. Not only do they make installing Django or Rails very easy, +they're absurdly cheap: 10gb disk space and 600gb/month bandwidth is less than +$10 a month. I'd recommend them to anyone. + +It's Open Source, Too! +---------------------- + +Want to see what makes this site tick? Want to make it tick more smoothly? +Feel free to head over to and take a look +at the code. + +[Squarespace]: http://www.squarespace.com/ +[Python]: http://python.org +[Django]: http://djangoproject.com +[Blueprint]: http://www.blueprintcss.org/ +[Markdown]: http://daringfireball.net/projects/markdown/ +[WMD]: http://wmd-editor.com/ +[jQuery]: http://jquery.com +[form validation]: http://bassistance.de/jquery-plugins/jquery-plugin-validation/ +[TextMate]: http://macromates.com/ +[Mercurial]: http://www.selenic.com/mercurial/wiki/ +[Bitbucket.org]: http://www.bitbucket.org/ +[Fabric]: http://www.nongnu.org/fab/ +[Mint]: http://haveamint.com/ +[WebFaction]: http://www.webfaction.com/signup?affiliate=sjl + +{% endblock %} \ No newline at end of file diff -r cf38a58b1927 -r 4ac1bf2cbaa2 content/projects/t.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/content/projects/t.html Wed Dec 23 20:59:20 2009 -0500 @@ -0,0 +1,233 @@ +{% extends "_post.html" %} + +{% hyde + title: "t" + snip: "A command-line todo list manager for people that want to finish tasks, not organize them." + created: 2009-09-11 19:03:29 +%} + +{% block article %} + +`t` is a command-line todo list manager for people that want to *finish* +tasks, not organize them. + +The code is in a [Mercurial repository][] on [BitBucket][]. + +[BitBucket]: http://bitbucket.org/ + +[TOC] + +Why t? +------ + +Yeah, I know, *another* command-line todo list manager. Several others already +exist ([todo.txt][] and [TaskWarrior][] come to mind), so why make another +one? + +[todo.txt]: http://ginatrapani.github.com/todo.txt-cli/ +[TaskWarrior]: http://taskwarrior.org/projects/show/taskwarrior/ + +### It Does the Simplest Thing That Could Possibly Work + +Todo.txt and TaskWarrior are feature-packed. They let you tag tasks, split +them into projects, set priorities, order them, color-code them, and much +more. + +**That's the problem.** + +It's easy to say "I'll just organize my todo list a bit" and spend 15 minutes +tagging your tasks. In those 15 minutes you probably could have *finished* a +couple of them. + +`t` was inspired by [j][]. It's simple, messy, has almost no features, and is +extremely effective at the one thing it does. With `t` the only way to make +your todo list prettier is to **finish some damn tasks**. + +[j]: http://github.com/rupa/j2/ + +### It's Flexible + +`t`'s simplicity makes it extremely flexible. + +Want to edit a bunch of tasks at once? Open the list in a text editor. + +Want to view the lists on a computer that doesn't have `t` installed? Open the +list in a text editor. + +Want to synchronize the list across a couple of computers? Keep your task +lists in a [Dropbox][] folder. + +Want to use it as a distributed bug tracking system like [BugsEverywhere][]? +Make the task list a `bugs` file in the project repository. + +[Dropbox]: https://www.getdropbox.com/ +[BugsEverywhere]: http://bugseverywhere.org/ + +### It Plays Nice with Version Control + +Other systems keep your tasks in a plain text file. This is a good thing, and +`t` follows their lead. + +However, some of them append new tasks to the end of the file when you create +them. This is not good if you're using a version control system to let more +than one person edit a todo list. If two people add a task and then try to +merge, they'll get a conflict and have to resolve it manually. + +`t` uses random IDs (actually SHA1 hashes) to order the todo list files. Once +the list has a couple of tasks in it, adding more is far less likely to cause +a merge conflict because the list is sorted. + +Installing t +------------ + +`t` requires [Python][] 2.5 or newer, and some form of UNIX-like shell (bash +works well). It works on Linux, OS X, and Windows (with [Cygwin][]). + +[Python]: http://python.org/ +[Cygwin]: http://www.cygwin.com/ + +Installing and setting up `t` will take about one minute. + +First, [download][] the newest version or clone the Mercurial repository ( `hg +clone http://bitbucket.org/sjl/t/` ). Put it anywhere you like. + +[download]: http://bitbucket.org/sjl/t/get/tip.zip + +Next, decide where you want to keep your todo lists. I put mine in `~/tasks`. +Create that directory: + + mkdir ~/tasks + +Finally, set up an alias to run `t`. Put something like this in your +`~/.bashrc` file: + + alias t='python ~/path/to/t.py --task-dir ~/tasks --list tasks' + +Make sure you run `source ~/.bashrc` or restart your terminal window to make +the alias take effect. + +Using t +------- + +`t` is quick and easy to use. + +### Add a Task + +To add a task, use `t [task description]`: + + $ t Clean the apartment. + $ t Write chapter 10 of the novel. + $ t Buy more beer. + $ + +### List Your Tasks + +Listing your tasks is even easier -- just use `t`: + + $ t + 9 - Buy more beer. + 30 - Clean the apartment. + 31 - Write chapter 10 of the novel. + $ + +`t` will list all of your unfinished tasks and their IDs. + +### Finish a Task + +After you're done with something, use `t -f ID` to finish it: + + $ t -f 31 + $ t + 9 - Buy more beer. + 30 - Clean the apartment. + $ + +### Edit a Task + +Sometimes you might want to change the wording of a task. You can use `t -e ID +[new description]` to do that: + + $ t -e 30 Clean the entire apartment. + $ t + 9 - Buy more beer. + 30 - Clean the entire apartment. + $ + +Yes, nerds, you can use sed-style substitution strings: + + $ t -e 9 /more/a lot more/ + $ t + 9 - Buy a lot more beer. + 30 - Clean the entire apartment. + $ + +Tips and Tricks +--------------- + +`t` might be simple, but it can do a lot of interesting things. + +### Count Your Tasks + +Counting your tasks is simple using the `wc` program: + + $ t | wc -l + 2 + $ + +### Put Your Task Count in Your Bash Prompt + +Want a count of your tasks right in your prompt? Edit your `~/.bashrc` file: + + export PS1="[$(t | wc -l | sed -e's/ *//')] $PS1" + +Now you've got a prompt that looks something like this: + + [2] $ t -f 30 + [1] $ t Feed the cat. + [2] $ + +### Multiple Lists + +`t` is for people that want to *do* tasks, not organize them. With that said, +sometimes it's useful to be able to have at least *one* level of organization. +To split up your tasks into different lists you can add a few more aliases: + + alias g='python ~/path/to/t.py --task-dir ~/tasks --list groceries' + alias m='python ~/path/to/t.py --task-dir ~/tasks --list music-to-buy' + alias w='python ~/path/to/t.py --task-dir ~/tasks --list wines-to-try' + +### Distributed Bugtracking + +Like the idea of distributed bug trackers like [BugsEverywhere][], but don't +want to use such a heavyweight system? You can use `t` instead. + +Add another alias to your `~/.bashrc` file: + + alias b='python ~/path/to/t.py --task-dir . --list bugs' + +Now when you're in your project directory you can use `b` to manage the list +of bugs/tasks for that project. Add the `bugs` file to version control and +you're all set. + +Even people without `t` installed can view the bug list, because it's plain +text. + +Problems, Contributions, Etc +---------------------------- + +`t` was hacked together in a couple of nights to fit my needs. If you use it +and find a bug, please let me know. + +If you want to request a feature feel free, but remember that `t` is meant to +be simple. If you need anything beyond the basics you might want to look at +[todo.txt][] or [TaskWarrior][] instead. They're great tools with lots of +bells and whistles. + +If you want to contribute code to `t`, that's great! Fork the [Mercurial +repository][] on BitBucket or the [git mirror][] on GitHub and send me a pull +request. + +[Mercurial repository]: http://bitbucket.org/sjl/t/ +[git mirror]: http://github.com/sjl/t/ + +{% endblock %} \ No newline at end of file diff -r cf38a58b1927 -r 4ac1bf2cbaa2 content/projects/women-in-water.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/content/projects/women-in-water.html Wed Dec 23 20:59:20 2009 -0500 @@ -0,0 +1,26 @@ +{% extends "_post.html" %} + +{% hyde + title: "Women in Water" + snip: "Photographs of women in Lake Ontario." + created: 2009-08-04 18:57:36 +%} + +{% block article %} + + + +This is still a work in progress. + +{% endblock %} \ No newline at end of file