Tags

Tab completion for Python

4:42pm on Nov 17, 2011

I just discovered this. So cool!

1
2
3
import readline
import rlcompleter
readline.parse_and_bind("tab: complete")

Put that in a startup file you use with $PYTHONSTARTUP.

Finally, a plus API.... well... almost

1:06pm on Oct 20, 2011

So now there's a Google Plus API for Python. You will notice I've added +1 buttons.

However, the sidebar on the right is gone for the moment, because there's a rather major bug in either the Plus API, or the image resizer Google use for the thumbnail images. So right now I can't actually pull thumbnails from Plus, I'd have to pull them down myself.

I'm pondering that, sure, but it seems the wrong way to do it.

Anyway, here's the bug I've submitted to the Plus bug tracker. I suspect that'll languish there for a year or so in the 'new' state, and by that time, I'll have stopped caring.

You know, like most of the Android bugs I've cared about.

everyone's an amateur

2:04pm on Aug 18, 2011

Yep, I'm doing it again. I'm trying to fix poorly-written libraries. This time it's the python bindings for net-snmp, the most popular SNMP library for unix.

Libraries should never, just print error messages when they can instead throw an exception. Throwing an exception means the application developer using your library has an opportunity to handle the error gracefully, rather than having the library just crash, or in this case, not being able to determine an error condition even exists.

Bad practice.

Here's a link to my bug report. Until they fix it, just edit netsnmp/client.py and replace the 'print stderr...' line with one that throws a useful exception.

buzzing

2:33pm on Jul 20, 2011

Google need to hurry up and release a G+ API, so I can replace the sidebar there -> with my G+ feed rather than my Buzz feed.

Sorta feels like Buzz is irrelevant now, doesn't it?

Stock quotes, currency, and airports

11:59pm on May 25, 2011

For a recent project, I had need of simple Python libraries for currency conversion, stock quotes, and airport code lookup. In the past, I was using perl for this, so I used Finance::Currency::Convert::XE and Finance::Quote.

But since I'm using Python here, those aren't available to me. And unfortunately, I couldn't find anything on the web either.

And for the airport codes, I got a list and stuck it in a database. But then I have to maintain that... and that's annoying.

So.... here you are. airportcodes.py, googlequote.py and xecurrency.py.

Python RSS and Atom feed library

6:42pm on May 07, 2011

I'm now officially a contributor to feedformatter, a Python library to generate RSS and Atom feeds. I'll probably use it for this site soon.

Package Tracking

6:38pm on Apr 28, 2011

I've been doing a lot of work on two Python package tracking libraries lately:

I've got one app right now that does package tracking, and a future website I'm working on will need to do this, so I started looking for some useful code already done. Naturally there were a lot of semi-working or partly started things out there.

Python-fedex does work pretty well, after fixing a bug or two.

Packagetrack is a wrapper for FedEx, UPS, and USPS package tracking, that uses the individual APIs and provides a generic result object with common fields, so you can basically just not care what sort of tracking number you have. It also returns objects that inherit from dict so I can use it to make JSON objects for web stuff later.

One thing that sucks is that the docs on how to use the shippers APIs are pretty overcomplicated. But then, isn't that the case for most API docs? Good reading if you want to fall asleep, but frustrating when you want to actually get Real Work done.

I'm amused actually, since this is the first time in a LONG while that I've contributed to a public project. Nearly all of my work has been either for-hire (and thus proprietary), or so specific to my personal needs that there isn't any point in cleaning it up for release. I'm enjoying this, even if in this case I've had to learn how to use git.

Drag and Drop in PyQt

10:54am on Jan 14, 2011

So you want to be able to drag items out of a QListView? The docs suck on this. Here's how simple it actually is:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
class MyListView(QtGui.QListView):
  def __init__(self, parent=None):
    super(MyListView, self).__init__(parent)

    # enable dragging
    self.setDragEnabled(True)

    # I'm only interested in drag, not drop, so I disable drop
    self.setAcceptDrops(False)
    self.setDragDropMode(QtGui.QAbstractionItemView.DragOnly)

    # use this to allow selecting multiple entries
    self.setSelectionMode(QtGui.QAbstractionItemView.ExtendedSelection)

  def mouseMoveEvent(self, event):
    self.dragObject()

  def dragObject(self):
    if not self.selectedIndexes(): return

    drag = QtGui.QDrag(self)

    data = []
    for index in self.selectedIndexes():
        if not index.isValid(): continue

        # this assumes your model has a nodeFromIndex() method -
        # it's easy to set one up, you'll probably have a custom
        # model class anyways
        node = self.model().nodeFromIndex(index)
        data.append(str(node))

    # in this case I'm just making a newline-seperated list
    # of the data, you could do pretty much anything here
    md = Qt.QMimeData()
    md.setData('text/plain', "\n".join(data))

    # this is important.  Without this, it won't do anything.
    # you can use different actions like Qt.MoveAction, which
    # would remove the item from your model, but then your model
    # has to be more complicated.  I'm only interested in copy here.
    drag.setMimeData(md)
    dropAction = drag.exec_(Qt.Qt.CopyAction)

Yup, that's it. There's lots of conflicting docs, some tell you to do complicated things with mousePressEvent(), others are older than modern Qt, others just plain wrong.

Google Buzz

3:48pm on Nov 04, 2010

You may have noticed the word 'buzz' at the top of the right column on my site here. Yes, that does link to my Google Buzz account. Most things I post there, will also show up on this page.

This is actually quite easy to do.

The first thing you need is Google'z Buzz client library. I'm using Python, so I use this one here. The docs explain pretty well how to use it, but the basic code looks like this:

1
2
3
4
buzz_client = buzz.Client()
buzz_client.oauth_scopes=[buzz.FULL_ACCESS_SCOPE]
buzz_client.use_anonymous_oauth_consumer(oauth_display_name=g.buzz_name)
buzz_client.build_oauth_access_token(YOUR_API_KEY, YOUR_API_SECRET)

That will get you an active buzz client. Here's how I fetch a list of my own posts:

1
2
3
4
5
6
try:
  for post in buzz_client.posts(type_id='@self', user_id='@me', max_results=10).data:
      # do something with your posts here

except buzz.RetrieveError, e:
  # handle errors

The things I'm most interested in are the photos I post to my Picasa dropbox (usually taken from my phone while out in pubs and such). Photos are found in p.attachments, you'll have to check for one with the attribute 'type' equal to 'photo' (videos are unsuprisingly, 'video'). Then you have attachment.preview and attachment.link - these are what show up on my page here.

Also interesting is attachment.type 'article'.

New blog engine

12:04am on Oct 21, 2010

So I'm testing out a new blogging enigne I've written in Python.

It's based on Pylons and MongoDB, with a few nice extras, Genshi, WTForms, jQuery, Markdown, the usual stuff. I did this mostly as a playground for using these new technologies in various work and not-work projects.

[RSS] [atom]
Tags