Recently I’ve been working on show notes support for SwallowCatcher. Since most podcast feeds include their show notes in the feed as embedded HTML I decided to render this HTML to display the show notes. This turned out to be ridiculously simple thanks to Android’s WebView class. The API for rendering arbitrary HTML within your app is almost Pythonic in its simplicity. However, there are a couple of gotchas which caught me out, so I decided to cover them here.
I started out by creating a new Activity class and a layout XML file for it. The layout XML was taken almost directly from the Android WebView Tutorial page:
<?xml version="1.0" encoding="utf-8"?> <WebView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/shownotes" android:layout_width="fill_parent" android:layout_height="fill_parent" />
In my Activity class the XML is loaded as normal. We also need to import the WebView class and the URLEncoder class. Additionally, the UnsupportedEncodingException class is required:
import android.webkit.WebView; import java.net.URLEncoder; import java.io.UnsupportedEncodingException;
Next, we need to encode the text in the correct format. Weirdly, WebView requires that the text is URL escaped, but without spaces converted to ‘+’ symbols. I used URLEncoder to encode my content then replaced the ‘+’ symbols with spaces. This probably isn’t perfect, but for my purposes it works.
String text = "<html><head></head><body>Content goes here!</body></html>"; text = URLEncoder.encode(text, "utf-8"); text = text.replace('+', ' ');
Finally, we find the WebView from the XML and tell it to load the string as its content:
WebView web = (WebView)findViewById(R.id.shownotes); web.loadData(text, "text/html", "utf-8");
All the above is encased in a try..catch statement for UnsupportedEncodingException, just in case the URLEncoder has a fit. That’s pretty much it. In SwallowCatcher the ShowNotesActivity is 56 lines, including all the verbose Java imports and bootstrapping and loading the content from the database via ORMLite.
As a wise action hero (and ex-Jedi) once said, “I love it when a plan comes together”.
QR Codes are a really easy way to share information between your desktop or laptop and a smartphone, which don’t have the privacy issues inherent in Google’s Chrome To Phone. The excellent FOSS Barcode Scanner app for Android makes scanning these codes and opening the scanned data a breeze. However, generating them on the desktop can be a bit of a pain. There are several websites, browser addons and APIs for generating these codes, but up until now I haven’t found anything really quick and easy.
That is until today, when I discovered the ‘qrencode’ utility. Qrencode does exactly what it says on the tin. It takes some text, encodes it as a QR Code and writes the result as a PNG file. It’s a simple command line tool, which opens up awesome scripting possibilities.
My use case is simply to send the URL of a web page that I’m viewing on my desktop to my phone, via QR Code. I found that qrencode was quite happy to write its output to stdout, which meant I could display the result directly using ImageMagick’s ‘display’ command, e.g:
$ qrencode http://blog.webworxshop.com -o - | display
You’ll notice that by default the QR Code is quite small. We can fix this by increasing the block size:
$ qrencode http://blog.webworxshop.com -s 10 -o - | display
Next, I wanted to automatically pull the text to encode from somewhere to save typing – the clipboard was an ideal candidate. Enter ‘xclip’. Xclip is a command line utility to read and write from/to the X system’s built in clipboard. I used bash’s backtick command substitution to grab text from the clipboard and encode it:
$ qrencode `xclip -o` -s 10 -o - | display
And there you have it, a simple one line command to generate and display a QR Code from the contents of the clipboard. I created a bash script containing the command and assigned it to a keyboard shortcut in Gnome (Ctrl-Shift-Q), so that sharing URLs to my phone is as simple as selecting the text in the location bar and hitting Ctrl-C followed by Ctrl-Shift-Q.
If you want to give this a try, you’ll need to install the utilities discussed, in Fedora these can be installed with:
$ sudo yum install qrencode xclip ImageMagick
Enjoy!
Welcome to our third instalment of interesting Python modules. Unfortunately I’m a bit late with this section this week – in fact its next week already! The fourth instalment should be along towards the end of the week thus catching me up.
Today we’re going to cover something which isn’t in the standard library, but is nonetheless very useful. The module is configobj which is used for reading from and writing to INI style configuration files files. A simple INI file is shown below:
item1 = value item2 = value2 [ section1 ] item1 = value [[ subsection ]] item1 = value
In the above we can see the simple use of items, values sections and subsection. Subsections can be nested down as far a you want, but I don’t think most applications will need many more than two or three levels.
Installation
As this module isn’t in the standard library, we need to install it. On most Linux distros it should be in the package repositories, for example on Fedora 14:
$ sudo yum install python-configobj
Windows and Mac users can install from PyPi by following the instructions on the homepage.
Basic Usage
Reading from a configuration file with configobj couldn’t really be any simpler:
import configobj config = configob.ConfigObj(filename) myoption = config['item1'] mysectionoption = config['section1']['item1'] mysubsectionoption = config['section1']['subsection']['item1']
Basically, all you need to do is open a ConfigObj object by passing it a filename, then you just read from it as if its a dictionary object. Sections and subsections appear as nested dictionaries. Writing to the file is just as simple:
import configobj config = configob.ConfigObj(filename) config['newoption'] = 'new stuff' config.write()
No surprises here, you just write to it as if it were a dictionary. All you have to do it call the write() method when you’ve finished, in order to sync everything to disk.
That’s pretty much it for basic usage. There is much more you can do with configobj, including advanced stuff like validation of configuration files. Check out the documentation for more info.
Here we are, the second Unofficial Python Module of the Week. Yes, the second – we started from zero (obviously!). This week we are covering the shelve module. Shelve provides you with a very simple Python object store. You can use it where you need quick persistent storage of objects between program runs, it’s much less overhead than using a database – even SQLite. Anyway, lets dive straight into it:
>>> import shelve >>> shelf = shelve.open("myshelf.db", writeback=True)
Here we import the shelve module (its in the standard library, so there’s no installation required). Then we open our persistent object store, supplying the filename that we want to store the objects in and the writeback parameter, which allows mutable objects to be stored more conveniently (otherwise they are only written when an assignment is performed). The writeback parameter also causes data to be cached in memory, which can be quite memory intensive, so you should call shelf.sync() every so on to flush everything to disk.
You can store anything that can be handled by the Python pickle module in a shelf:
>>> shelf['thedict'] = {'one': 1, 'two': 2, 'three': 3} >>> shelf.sync()
As you can see, using a shelf is just like using a dictionary. The only real limit is that the keys must be strings. You can also read back values from the shelf as with a dictionary:
>>> print(shelf['thedict']) {'one': 1, 'two': 2, 'three': 3}
That’s just about it, just remember to close the shelf when you’re finished with it:
>>> shelf.close()
If you want to find out more have a look at the official Python docs for shelve and Doug Hellmann’s PyMOTW posting on the subject.
[EDIT: This series has been renamed so as not to conflict with Doug Hellman's excellent Python Module of the Week series. See UPMotW #1 for details]
I’m going to try something different today. This is going to be the first in a series (hopefully once weekly) of Python Modules of the Week. This has probably been done to death elsewhere, but I’m using it as an opportunity to learn some more Python and to cement some of these modules in my mind.
Argparse is a Python module for processing command line arguments. It’s new in version 2.7 and is designed to replace the Optparse module. I’m not sure what the rationale for the change was as the two modules look very similar to me. However, it suffices to say that you should use argparse in all new code.
The main class of argparse is called ArgumentParser, it allows you to add arguments to your program and parse the provided arguments at runtime:
1 2 3 4 5 6 | parser = argparse.ArgumentParser() parser.add_argument("-v", "--verbose") # a flag type argument parser.add_argument("value", type=int) # an integer positional argument ... args = parser.parse_args() # parse the args from sys.argv print(args.value) # arguments accessed as data members |
You can also add meta-data such as help and descriptions to your arguments via keyword arguments to many of the methods. Take a look at the module documentation for examples. Once nice thing is that when you provide this data, argparse automatically generates the -h and –help flags and populates them with nicely formatted help output using the info you provide.
The argument parsing provided by argparse allows you to create some very complex command line interfaces to your scripts. I especially like the sub-commands framework, which allows each sub-command to exist as its own separate entity with its own options and help information. To create an argument parser with a sub-command is just a few lines:
1 2 3 | parser = argparse.ArgumentParser() subcommands = parser.add_subparsers() mysubcommand = subcommands.add_parser('mysubcommand') |
Of course,each sub-command is an ArgumentParser in its own right, so you can add all the options that you normally would, including command line flags, positional arguments and help information. Also each sub-command will be listed in the help and will also have its own help page which can be accessed via:
1 | ./pyprog.py subcommand --help |
All in all, this is a very useful Python module to know about. Its ease of use and the number of things it ‘just takes care of’ make it a pleasure to use. Hopefully it’ll have you writing nice command line interfaces to all those hacked together scripts that are currently controlled by commenting bits of them in and out!
Categories
Tags
adbard Android archlinux auckland awesome bzr conference crap crunchbang debian dhcp eeepc electricity facebook Fedora foss Free Software gallery3 google google analytics identi.ca java javascript kiwi pycon launchpad linux LVM mu-feeder netboot Open Cloud photos piwik pxe python site news skepticism SwallowCatcher tftp turnitin ubuntu UoA upmotw videos wifi wordpressI Also Contribute To...
Planets I'm On

