Tue, 13 Oct 2009

Good Python Habits: vim + pyflakes

Here is a neat little hack for running pyflakes on Python files after you save them. I like using pyflakes for quickly catching dumb errors, but you could easily replace it with a more comprehensive tool like pychecker, or pylint for more strict PEP8 compliance.

All you have to do is throw this in your ~/.vimrc

au BufWritePost *.py !pyflakes %

This has saved me *tons* of time and frustration over the past few weeks, and I have no idea I lived without it.

posted at: 13:32 | link | Tags: , , | 3 comments

Sat, 01 Sep 2007

Recovering a Pyblosxom blog using liferea's RSS cache

My buddy who used to host lewk.org didn't pay his bills, so his server got taken down last week. What sucks is I that never backed up my Pyblosxom data. What doesn't suck is that thankfully Liferea, my RSS reader, did for me.

Grepping through ~/.liferea_1.2/cache/feeds, I was able to find my blog cached in some XML format. Then I wrote a little bit of code to re-create my Pyblosxom entry structure with the proper filenames and timestamps.

#!/usr/bin/python -tt
 Turns XML into pyblosxom blog entries.

 It parses BLOG_XML pulling out blog entires in the form of:

     <feed version="1.1">

 The file '2007/08/20/bar.txt' will be created in pyblosxom format with
 the appropriate timestamp.  The #mdate is used by the pyblosxom.vim plugin.

     #mdate Aug 20 10:47:48 2007

import os
import time

try: from xml.etree import cElementTree
except ImportError: import cElementTree
iterparse = cElementTree.iterparse

entries = {} # { 'title' : <Element> }

BLOG_XML = 'blog.xml'
BLOG_ROOT = 'http://foo.com/blog/'

def getField(elem, field):
    for child in elem:
        if child.tag == field:
            return child.text

## Pull out all feed items, removing older duplicates
for event, elem in iterparse(BLOG_XML):
    if elem.tag == 'feed':
        for child in elem:
            if child.tag == 'item':
                title = getField(child, 'title')
                if entries.has_key(title):
                    if int(getField(child, 'time')) > \
                       int(getField(entries[title], 'time')):
                        entries[title] = child
                    entries[title] = child

for title, entry in entries.items():
    source = getField(entry, 'source').replace(BLOG_ROOT, '')
    source = source.replace('.html', '.txt')
    if not os.path.isdir(os.path.dirname(source)):
    output = file(source, 'w')
    output.write(title + '\n')
    mtime = time.localtime(int(getField(entry, 'time')))
    mdate = time.strftime("%b %e %H:%M:%S %Y", mtime)
    output.write("#mdate %s\n" % mdate)
    output.write("<p>%s</p>\n" % getField(entry, 'description'))
    timestamp = time.strftime("%y%m%d%H%M", mtime)
    os.system("touch -t %s %s" % (timestamp, source))

It also adds an #mdate tag into each entry, which read by the spiffy pyblosxom mdate vim hack that Jordan Sissel wrote to restore each entries original timestamp after editing. His code only works on FreeBSD at the moment, so I started a pyblosxom.vim plugin that works on Linux (hopefully it will eventually support both, along with a bunch of other handy functions). You can find all of this code in my mercurial repo: hg.lewk.org/xml2pyblosxom

posted at: 16:44 | link | Tags: , , | 31 comments

Sat, 19 May 2007

Dealing with multiple email addresses in mutt

I recently watched Bram Moolenaar's "7 Habits for Effective Text Editing 2.0" Google Tech Talk presentation, which inspired me to dust off the old vimrc and poke around for a bit. I tend to live most of my life inside of vim, which is actually a pretty kickass place to live (I even started working on a life.vim script to replace my [excessive] tomboy usage, and add a bit of GTD sauce).

I use mutt for my email accounts, and recently made some modifications to my vimrc to help automate a task that utilizes far too many of my keystrokes each day: changing the From field of outgoing messages.

let g:addresses = ['lewk csh rit edu', 'lmacken redhat com', 'lmacken fedoraproject org']
function NextEmailAddress()
    if !exists("g:email_idx")
        let g:email_idx = 0
    s@^\(From:.*<\).*>@\=submatch(1) . g:addresses[g:email_idx % len(g:addresses)] . ">"@
    let g:email_idx += 1
map <silent> @ :call NextEmailAddress()<CR>

This lets you cycle through your email addresses by pressing '@' when composing a new mail. From here, my messages go through esmtp, which ships them off to the proper SMTP server based on the identity of the mail.

I'd be curious to hear of any other tweaks people have made to their vimrc's to help improve their mutt usage, or of any life-changing hack that saves you tons of keystrokes every day.

posted at: 19:15 | link | Tags: , , , | 1 comments