Code, mostly.


[ Home | RSS 2.0 | ATOM 1.0 | Comment ]

Sat, 26 Dec 2009

Eco-button for linux

Having received an eco-button I wondered what it would take to get it to do anything in Linux. I was thinking about modifying a simple USB driver or something arcane like that, but it turned out to be much simpler. When you plug the eco-button in to a USB port and press it it generates a stream of XF86Sleep keypress events. It doesn't show up under lsusb which makes me think it might be injecting keyboard input, but anyway, it sends a clear and usable signal.

If your system is setup to sleep when the extended keyboard's sleep key is pressed the eco-button might work out of the box for your. If not, here are three simple steps to make it go.

  1. Have your window-manager bind the XF86Sleep key to run the following python program. Put the text below in a file, called perhaps /home/joeuser/bin/ecobutton, and then tell your window-manager to run it when the XF86Sleep is pressed. You'll need to make the program executeable (chmod +x /home/joeuser/bin/ecobutton). When you're setting up the hotkey, you can press the eco-button itself of course, to send the XF86Sleep keystroke.

import os
import time
import fcntl

aFile = open(os.path.expanduser("~/.ecobutton.lck"), 'w')
fd = aFile.fileno()
fcntl.lockf(fd, fcntl.LOCK_EX | fcntl.LOCK_NB)
# program aborts at this point if another already has lock
os.system("sudo /usr/sbin/pm-hibernate")
time.sleep(10)  # stay running to preserve lock
  1. Make sure the pm-utils package, or whatever package provides pm-hibernate, is installed on your system.

  2. Use visudo to add an entry like this at the end of /etc/sudoers (replace joeuser with your username):

    joeuser ALL=(ALL) NOPASSWD: /usr/sbin/pm-hibernate

That's it. Because the eco-button generates a stream of XF86Sleep key-presses the python program uses a lockfile to ensure pm-hibernate is only run once. That's probably unnecessary, pm-hibernate may do its own locking anyway.

Of course all of this is just a convoluted way of invoking the hibernate function, and to a degree it's just code for its own sake, making the button work in Linux. On the other hand it really has reduced my energy usage, because it inspired me to test Ubuntu's hibernate function (which wasn't working well last time I looked, 2-3 years ago, but is now fine), and the glowing button thing reminds me to use it.

posted at: 12:21 | path: /code/python | permanent link to this entry

Wed, 23 Sep 2009

N-up layout extension for Inkscape.

I'd forgotten about this until someone changed the tags on the wishlist "bug" which acts as a home for this code:

Basically an inkscape extension for n-up layouts, great for postcards and labels.


posted at: 10:51 | path: /code/python/inkscape | permanent link to this entry

Sat, 15 Aug 2009

Syntax highlighting for Pyblosxom

After running around in circles a bit I've found it's quite easy to get syntax highlighting in Pyblosxom if you're using the rst plugin.

  1. Install the rst plugin.

  2. Make sure pygments is installed on your system. It's available as a package for Ubuntu, so you can just do:

    sudo apt-get install python-pygments
  3. Get from the pygments distribution (or from the end of this article). It's in the 'external' folder. It may not be included in the package for your system, but you can get the file by itself by browsing the pygments site.

  4. Rename it because that seems more sensible, and put it in you plugins folder. You would think you would need to import it from the rst plugin, but you don't, because Pyblosxom will have imported it just because it's in the plugins folder.

  5. Edit and change:




    Doing so causes pygments to use <span style="color: #BA2121"> instead of <span class="comment"> etc., but it saves a lot of trouble trying to ensure the CSS file is available.

That's it. Now in your rst you can use the sourcecode directive:

That's it.  *Now* in your rst you can use the `sourcecode` directive:

.. sourcecode: python

  import foo  # get access to foo"test") or raise SystemExit

to syntax highlight rst (above), python (below), and all the other languages and markups pygments knows.

import foo  # get access to foo"test") or raise SystemExit

Graham Higgins's post may have set me off on the right track here, at least by making me aware of pygments.

Syntax highlighting on external files

To make pygment's sourcecode directive even more useful I added a quick tweak to allow inclusion of a file like this:

.. sourcecode:: python
  :filename: ../tlog/plugins/

In this form the inline content is ignored and the content of filename is formatted instead.

Here's the complete, modified, (original from external folder on pygments Trac site). Put it in your plugins directory. Modifications are:

  • the if 'filename'... block
  • setting ...options['filename'] = directives.path
# -*- coding: utf-8 -*-
    The Pygments reStructuredText directive

    This fragment is a Docutils_ 0.4 directive that renders source code
    (to HTML only, currently) via Pygments.

    To use it, adjust the options below and copy the code into a module
    that you import on initialization.  The code then automatically
    registers a ``sourcecode`` directive that you can use instead of
    normal code blocks like this::

        .. sourcecode:: python

            My code goes here.

    If you want to have different code styles, e.g. one with line numbers
    and one without, add formatters with their names in the VARIANTS dict
    below.  You can invoke them instead of the DEFAULT one by using a
    directive option::

        .. sourcecode:: python

            My code goes here.

    Look at the `directive documentation`_ to get all the gory details.

    .. _Docutils:
    .. _directive documentation:

    :copyright: Copyright 2006-2009 by the Pygments team, see AUTHORS.
    :license: BSD, see LICENSE for details.

# Options
# ~~~~~~~

# Set to True if you want inline CSS styles instead of classes

from pygments.formatters import HtmlFormatter

# The default formatter
DEFAULT = HtmlFormatter(noclasses=INLINESTYLES)

# Add name -> formatter pairs for every variant you want to use
    'linenos': HtmlFormatter(noclasses=INLINESTYLES, linenos=True),

from docutils import nodes
from docutils.parsers.rst import directives

from pygments import highlight
from pygments.lexers import get_lexer_by_name, TextLexer

def pygments_directive(name, arguments, options, content, lineno,
                       content_offset, block_text, state, state_machine):

    if 'filename' in options:
        if options['filename']:
            content = [line.rstrip('\n') for line in file(options['filename'])] 
        del options['filename'] 

        lexer = get_lexer_by_name(arguments[0])
    except ValueError:
        # no lexer found - use the text one instead of an exception
        lexer = TextLexer()

    # take an arbitrary option if more than one is given
    formatter = options and VARIANTS[options.keys()[0]] or DEFAULT
    parsed = highlight(u'\n'.join(content), lexer, formatter)
    return [nodes.raw('', parsed, format='html')]

pygments_directive.arguments = (1, 0, 1)
pygments_directive.content = 1
pygments_directive.options = dict([(key, directives.flag) for key in VARIANTS])

pygments_directive.options['filename'] = directives.path

directives.register_directive('sourcecode', pygments_directive)

posted at: 09:02 | path: /code/python/pyblosxom | permanent link to this entry

Mon, 10 Aug 2009

Testing mostly pingback

And maybe trackback, maybe.

posted at: 10:41 | path: / | permanent link to this entry

Fri, 07 Aug 2009

``zipas`` - ensure .zip file contains an outer wrapper folder

A trivial bash script to create a .zip file where everything's in a top-level folder. Saves creating a folder temporarily, and copying / linking things into it:


if [ @# -lt 2 ]; then cat <<EOF
usage: $0 <wrapper-folder> <target files>

e.g. zipas jul0907 *.c

  HEADNAME=${PATHNAME%%/*}  # i.e 'foo' from 'foo/bar/inner'

  if [ -a "$HEADNAME" ]; then
    echo "ERROR: '$HEADNAME' exists"
    mkdir -p $PATHNAME
    for i in $@; do
      ln -s "$PWD/$i" "$PATHNAME/$i"
    zip -r $ $HEADNAME
    rm -rf "$HEADNAME"

posted at: 15:01 | path: /code/bash | permanent link to this entry

Made with PyBlosxom