Tera Term subroutines

A long time ago I inherited a big monolithic mess of Tera Term macro code. After a few years the code base had grown considerably and become extremely unwieldy. I finally decided that it was time to fix the problem and created some utility code that would allow me to make the code more modular (and make the code more reusable for other projects). The result is subroutine.ttl, licensed under the terms of the MIT license.

This creates something akin to a namespace and function notation for Tera Term macros:

callsub = 'logging:backup_logs'
include 'subroutine.ttl'

For this to work, just create a logging.ttl file, copy some boilerplate/hook code to the top of the file, and add a block of code like this:

:backup_logs
    ; The backup code goes here
return

Thanks to Tera Term's scope-less variables (or, from another point of view, global-only namespace) you can even "pass" arguments and "return" values. Enjoy!

listparser 0.18

I'm pleased to announce the release of listparser 0.18!

This release simply replaces the regular expression-based RFC 822 date parser with procedural code. The package is available on PyPI.

listparser is a Python module that parses subscription lists (also called reading lists) and returns all of the feeds and subscription lists that it finds. It supports OPML, RDF+FOAF, and the iGoogle exported settings format, and runs in Python 2.5 through Python 3.5, Jython, and PyPy.

download | documentation | source code

feedparser 5.2.0

I'm pleased to announce the release of feedparser 5.2.0!

It's available only on the Python Package Index (PyPI) as Google Code is shutting down its services. The update incorporates over two years of work and patches from multiple authors.

Some of the release highlights include what will hopefully be a significant boost to performance: all in-HTML microformat parsing has been removed, the BeautifulSoup dependency has been removed, HTML Tidy support has been removed, and chardet use is now lazy -- it will only run exactly when it is needed...IF it is needed. Additionally, date-time parsing has been revamped to use procedural code, and many additional HTML5, MathML, and feed elements have been added, including Podlove Simple Chapters, MediaRSS, Dublin Core, GeoRSS, and GML, Finally, there have been a number of bug fixes.

The official repository has moved to GitHub in advance of Google Code shutting down services. Additionally, to support faster development and release cycles, feedparser now follows the Successful Git Branching Model. Basic summary: all development occurs in feature branches, these are merged with --no-ff into the develop branch, and when a new release is ready it branches off of develop for prep work and is merged into master with --no-ff and an annotated tag is created. The release branch is then merged back into develop.

tl;dr -- always create a new branch off of the develop branch when making changes to the code and submitting pull requests. =)

Future development is going to focus on a number of core issues, some of which have made feedparser a difficult body of code to approach and contribute to. For instance:

  • Pruning the list of supported Python interpreter versions
  • Splitting feedparser into a manageable set of function-specific files
  • Resolving differences between the various XML and SGML parsers
  • Reducing the amount of Unicode encode/decode operations
  • Modernizing the syntax, code idioms, and best practices used throughout the code
  • Leveraging the vibrant Python package ecosystem that has grown in the 13 years since feedparser was started

I'm excited for how feedparser will improve in 2015!

Twelve days later

It's been twelve days since my shoulder surgery so I thought I'd post a summary of what I've been up to.

In the first 24 hours there was an issue that cropped up at work. The problem was caused by an update to some software released by another group in the company, and, as frequently happens, I had warned the responsible group several months in advance that this was a potential problem. Nevertheless, in the first 24 hours after surgery I was remotely troubleshooting and releasing an update to my software to work around the issue.

I then spent the rest of the week writing my own static website generator. The purpose is explicitly to learn about some technologies that I haven't had a reason to learn about in my professional work, like virtualenv, blinker, and jinja2. After a week I had a pretty solid, extensible architecture and the beginnings of a website theme. This may grow beyond a simple learning exercise.

This week I picked up feedparser development again. The virtualenv exposure from last week helped a lot, and I finally learned how to handle remote git repositories. Then I packaged up a new feedparser release and published it.

As one of my friends joked last night, "Even crippled and high you're still more productive than half of the people on my team," a tongue-in-cheek reference to having one arm immobilized and taking narcotic painkillers they give you when they modify what your bicep attaches to.

Throughout the first week I found it difficult to focus: the oxycodone regimen afforded me only a few hours of lucidity each day. I don't enjoy that. This second week I've been skipping the painkillers as much as possible and have been sober now for about 36 hours. Unfortunately, I'm now experiencing frequent dull headaches. Ah well.

Oh! And I'm going for walks now when I manage to tie my shoelaces. Recovery's going well, and life is good.

Moving, part 8

With basically ten lines of code and a trivial template modification I've added support for multiple categories to Pelican. I'll make the code freely available soon. I expect to finalize the migration soon.

Speaking of which, perhaps I should have called this post series "migration" instead of "moving". I've gotten feedback that that's been confusing. Too late now!

Moving, part 7

Good news! I have almost 200 blog entries spanning eight years "imported" into Pelican (really, I have almost 200 text files on a USB drive). I've even written code that automatically converts in-blog links from LiveJournal URL's to the new URL scheme. I really need multiple categories, though, in part because I want the site to be extremely feeds-friendly, and being unable to make an announcement that will appear in category-specific feeds (which I did when announcing a new date parser for feedparser and listparser, for instance) seems very limiting. Maybe I should just give up and use tags. Ugh. Lawless.

Moving, part 6

I misspoke, apparently: the Unicode problem in the first tool was stemming from something weird going on with the xmlrpclib.Binary.decode() function. Extracting the raw utf-8 data and decoding that gets me the data I expect. New problem: some of my entries are not fully HTML. The paragraphs are not wrapped in <p> tags, resulting in a massive blob of text when converted to Markdown because html2text discards the newlines. I have to add the HTML tags before converting to Markdown.

Moving, part 5

Apparently Python-based LiveJournal softwares think they're special snowflakes that don't have to deal with Unicode. The first library created severe corruption and truncation. The second tool immediately crashed because it assumed I was using a Cyrillic locale that was compatible with characters the library's author introduced in the output (and crashed again when it encountered a post I wrote with Spanish phrases). Time to start writing patches.

Moving, part 4

I've gotten the site to a decent visual and functional state -- pagination works, categories work, feeds work...it still feels like it's missing something, either a functional or navigational element. Maybe it doesn't feel right simply because I'm unaccustomed to a single-column blog.

Things to improve but that take more effort: XSL transforms for the feeds (giving explanations and subscription links to various services), contributing a patch back to Pelican to use .atom and .rss extensios for feeds (which will fix MIME type problems caused by using a generic .xml extension), better meta data on the pages, sitemap creation, and displaying old comments.