Posts about code

tags: #code

2013-08-22 12:00

The Little Ol’ Wiki From Pasadena

(originally from https://web.archive.org/web/20150422203816/http://ajcsystems.com/blog/blog/2012/10/30/the-little-ol-wiki-from-pasadena/)

It seemed like a simple enough desire. I wanted a small, functional wiki with (roughly) the following features:

  • Use a git repository for page storage and version control
  • Map files on the filesystem directly to web pages (making it equally easy to edit from a CLI or from the web UI)
  • Render various wikitexts (particularly Markdown) into some appropriate output format
  • Support intra-page links and image includes, etc.
  • Be written in a language I am comfortable with

I considered several projects, including:

  • Hatta: Backed by a Mercurial repo, non-trivial to change
  • Giit: Written in Haskell. I had neither the time nor the inclination to learn that for this project.
  • Gollum: Mostly suitable, but written in Ruby (which isn’t my strong suit). Plus I wasn’t super-fond of the way it handled subdirectories and other complex filetypes.

But none of them quite scratched my itch. Thus, I was left with no choice but to write my own.

Introducing valet

valet is a script that turns any directory into a simple wiki, complete with wikitext rendering, editing, and automatically committing changes to version control.

Here’s a short list of valet‘s features:

  • Single file, depending only on bottle
  • Handles navigating around the filesystem rooted where you start it
  • Automagically detects the type of various files, and (if you have the supporting Python libraries installed) renders them as they ought to appear. As a bonus, if you have pygments installed, source code will be syntax-highlighted where possible.
  • Changes from the web UI are automatically saved into the git repo (if desired)
  • Runs as a standalone service, serving from your local machine
  • Optionally supports CGI and WSGI; rename the script to something.cgi or something.fcgi and it will Do The Right Thing TM. This makes it suitable(-ish) for serving through Apache or some such with SSL, authentication, access control, etc. etc.
  • Installable with pip!
pip install valet

Hopefully this proves as useful to other people as it has been for me.

tags: #code | #python | #til

2012-10-10 12:00

Regular Expression Non-Capturing Groups (or, what’s "(?:" mean?)

(originally from https://web.archive.org/web/20150422001421/http://ajcsystems.com/blog/blog/2012/10/10/regular-expression-non-capturing-groups-or-whats-mean/)

When I was working recently on changing poodledo‘s parser from using a lexer to using regular expressions, I found myself implementing some crazy logic to try and ignore the results from matched groups whose matches I didn’t actually want (since I was using parentheses for their “pick one of these two alternatives” function instead of their “pull out this specific chunk as a match” function).

For example, take the string “task title @context name #due date”. Starting with the at-sign, I want to match all words until some other symbol is reached; or, to avoid confusing the parser, match everything following the at-sign and between two square brackets. Here’s the regex I came up with:

(^|\W)@([\b ]?(([\w\"\'.@]+ )*[\w\"\'.@]+)[\b]??|[\b(.+?)\b])

Using this regex, though, gave me a lot of extraneous matching groups:

>>> q = r'(^|\W)@([\b ]?(([\w\"\'.@]+ )*[\w\"\'.@]+)[\b]??|[\b(.+?)\b])'
>>> task = 'task title @context name #due date'
>>> re.findall(q, task)
[(' ', 'context name', 'context name', 'context ', '')]

How do I determine programmatically which of these groups is the one I want?

Digging around in the Python regex documentation, I found a section about non-capturing groups, which seemed like it would save me a significant amount of sanity. Apparently, Perl-5-compatible regular expression parsers often implement a regex extension syntax by following an open parenthesis with a question mark, and then some other symbols that indicate which extension is in use. In this specific case, “(?:” indicates a group whose matches shouldn’t be captured in the output list. Eureka!

>>> q = r'(?:^|\W)@(?:[\b ]?((?:[\w\"\'.@]+ )*[\w\"\'.@]+)[\b ]??|[\b(.+?)\b])'
>>> re.findall(q, task)
[('context name', '')]

Now the only logic I need is “Ignore matching groups which are empty”, my sanity is preserved, and all is well with the world.

tags: #code | #javascript

2012-10-08 12:00

Dr. jQuery-Cycle, or how I learned to stop using Keynote and love HTML

(originally from https://web.archive.org/web/20150422001009/http://ajcsystems.com/blog/blog/2012/10/08/dr-jquery-cycle-or-how-i-learned-to-stop-using-keynote-and-love-html/)

We have a number of fancy dashboards displaying on TVs here at $work, and some of them are implemented with Keynote to get the endless-cycling effect. This is lame because Keynote is very hard to use for this purpose (precise grid positioning, versioned changes, lots of other stuff).

Read more…

tags: #code

2011-11-13 12:00

Neat new software I’ve written recently

(originally from https://web.archive.org/web/20150422203246/http://ajcsystems.com/blog/page/2/)

I’ve been on a bit of a coding tear lately. I’ve written a FUSE filesystem for Amazon Cloud Drive, and also made a lot of improvements to my Toodledo API library, including writing a command-line tool modeled on Tom Limoncelli’s Cycle System from Time Management for System Administrators.

FUSE Filesystem for Amazon Cloud Drive

Github; does what it says on the tin. I couldn’t find a supported way to upload music from Linux, so I made one. Currently I’m a bit hesitant to call it production-ready, as Amazon has an eight-device-per-account limit and this appears to consume multiple slots instead of counting as just one extra device. I’m hopeful I can get that sorted soon.

Poodledo (Toodledo API Library)

Github; I wrote (well, forked and extended) a Python library for interacting with the web-based task management system Toodledo. Toodledo has quite an extensive ecosystem, including a light version of the website suitable for embedding, SMS and Twitter integration, an official iOS client, and several Android clients (Due Today is what I use). However, there was no easy way to add tasks from a command line, and also it wasn’t possible to create tasks with metadata (due date, project name, priority, etc.).

With the Python library in hand, I wrote a couple of tools to add and manage tasks from a command line. tdcli implements a super-fancy lexer which can add metadata to a task while creating it, e.g. “Create a task that’s due today and part of the Poodledo project #today *Poodledo”.

“cycle” for Toodledo

The other tool I wrote for interacting with Toodledo is cycle, modeled after Tom Limoncelli’s Cycle System from Time Management for System Administrators. It would take a while to explain; you should read the book, as it’s excellent. Here are some examples of its use.

tags: #code

2011-10-06 12:00

Poodledo library updated

(originally from https://web.archive.org/web/20150421212536/http://ajcsystems.com/blog/blog/2012/10/06/poodledo-library-updated/)

I spent some time the past few days updating and improving the Python library I maintain for integrating with Toodledo. The big new features I’m excited about are automatically tab-completing your folders, goals, etc. when creating a new task (as I can never remember exactly what I called them without checking), and adding multi-line notes. Now I can add a new task, pick out the right project and such right from the command line, and ramble on to add whatever other notes I want to write down right there.

I’m hoping that this new set of features will help me get back in the habit of adding new tasks directly to Toodledo, instead of just writing them in a text file and going back to reprocess them later. :-P

Check it out at github.