Here is a Progress Cell Renderer for pygtk based applications. It allows one to embed a progress bar inside a TreeView. It’s being used in Smart to present progress for downloads of packages and other items.
Archive for the 'Snippet' Category
My weekend was taken by boring academic stuff. More specifically, I’ve built a validator in C, including a tokenizer, a parser, and a scope system, to check for a small subset of the C language syntax. Anyway.. I was still able to do something interesting after all.
Taking further my research about pyperl, I’ve wondered if it would be possible to wrap the XchatPython plugin interface for perl usage. Actually, it turned out that besides being possible, it was easy. It was just a matter of putting the following wrapper in the ~/.xchat2 directory:
import xchat
import perl
perl.eval("$xchat = Python::eval('xchat')")
perl.eval("do '" + __file__[:-3] + “.pyl’”)
__module_name__ = perl.eval(”$__module_name__”)
__module_version__ = perl.eval(”$__module_version__”)
__module_description__ = perl.eval(”$__module_description__”)
This wrapper will load a file with the same name as itself, but with a .pyl extension, which should contain perl code defining the plugin (I haven’t used the .pl extension because this would conflict with the internal perl plugin of xchat). That code may access the $xchat object to interface with xchat, using the same API as defined in XchatPython.
Here is a small sample module in perl, defining the /test command:
#!/usr/bin/perl
$__module_name__ = "perlwrap";
$__module_version__ = "1.0";
$__module_description__ = "Testing perlwrap.";
sub test {
$xchat->prnt("Test command!");
return $xchat->EAT_ALL;
}
$xchat->hook_command("test", \&test);
$xchat->prnt("Plugin perlwrap loaded!\n");
Notice that the interface is exactly the same, including the meta-information.
Unfortunately, there seems to exist some bug in the MULTI_PERL support of pyperl which makes it lose track of function references once the python support commutes the thread states. To make this trick work, remove the MULTI_PERL support by deleting the MULTI_PERL file in the root of the pyperl distribution.
Today I’ve been talking to Cavassin about Webmin, and wondering if it would be possible to write Python modules for it. I was sure that I wasn’t being original in that idea, and Cavassin also mentioned that he had read something about it somewhere, so I’ve looked in google for possible references.
Of course, we were right. I have found the python-webmin project. OTOH, I’ve looked in the code, and that’s not really what I had mind. This module reimplements the Webmin API in Python. This means that one will have to maintain it forever, and check for updates in every Webmin release, and even then, it won’t be able to do more advanced stuff which requires deeper interaction with the Webmin system.
The correct solution for that would be to somehow wrap the Webmin API in a way that Python calls the real methods, thus requiring little or no maintenance. It’d be even better if this system was generic and not bound to Webmin in any way. While looking for the solution, I found Inline, which did exactly what I had in mind, but reversed (Python inside Perl), and PyInline, which unfortunately doesn’t seem to support Perl yet. Then, I finally found what I was looking for: pyperl.
The pyperl project embeds a Perl interpreter inside a Python module, allowing arbitrary Perl functionality to be used from Python. It’s really amazing to see it working. Have a look at these simple examples:
>>> import perl
>>> perl.eval('sub func { printf("Hello $_[0]!\n”); }’)
>>> ret = perl.call(”func”, “world”)
Hello world!
>>> func = perl.get_ref(”func”)
>>> ret = func(”world”)
Hello world!
>>> perl.require(”Digest::MD5″)
1
>>> md5 = perl.callm(”new”, “Digest::MD5″)
>>> md5.add(”something”).hexdigest()
‘437b930db84b8079c2dd804a71936b5f’
Isn’t it fantastic?
Another amazing thing is that pyperl also includes support for doing Python inside Perl. Of course, you can do Python inside Perl inside Python:
>>> n = 5
>>> perl.eval('Python::eval("n")*2')
10
Now, it’s just a matter of finding some time to create a basic wrapper on top of the Webmin Perl API, turning it into something more pythonic and also protecting Webmin modules developed in Python from changes in the pyperl API.
References
Today I’m a little short in time, so I decided to implement one of the bit-sized tasks in my backlog. These UTF8 raw strings appearing in my xchat when someone else is using that encoding is bothering for a long time, and the fix is now straightforward, with the latest update I’ve done in the xchat python plugin (the emit_print() API function was implemented). It’s just a matter of creating a decode() function which tries to decode the string from UTF8, and reencode it as ISO-8859-1. If it succeeds, it blocks xchat, and sends the message by itself. Otherwise it just lets xchat do its work. After that, I’ve hooked this method in the many print events, including information about which of the parameters are the strings to decode. Here is an excerpt (the full version is in the examples section of the xchat-python page):
...
def decode(word, word_eol, userdata):
event, pos = userdata
if type(pos) is int:
pos = (pos,)
changed = False
for i in pos:
try:
reencoded = word[i].decode(’utf8′) \
.encode(’iso-8859-1′)
except UnicodeError:
continue
if reencoded != word[i]:
word[i] = reencoded
changed = True
if changed:
xchat.emit_print(event, *word)
return xchat.EAT_XCHAT
else:
return xchat.EAT_NONE
EVENTS = [
("Channel Action", 1),
("Channel Action Hilight", 1),
...
]
for event in EVENTS:
xchat.hook_print(event[0], decode, event)
…
Notice that you need the latest version of the xchat-python plugin, which will be available in the next version of xchat (coming after 2.0.5). You may also download xchat 2.0.5, and update the plugin with the file available in the Download section of the plugin page.
I’m a little late here, since python-dateutil was released last week. Anyway, this is a Python package providing powerful extensions to the standard python datetime module, available with Python 2.3. I wrote it because I really missed some generic date/time manipulation features to empower the nice datetime module. I confess it ended up being a little more than what I expected initially, mainly because I had a lot of fun building these algorithms.
Here is a list of features, from the homepage:
- Computing of relative deltas (next month, next year, next monday, last week of month, etc);
- Computing of relative deltas between two given date and/or datetime objects;
- Computing of dates based on very flexible recurrence rules, using a superset of the iCalendar specification. Parsing of RFC strings is supported as well.
- Generic parsing of dates in almost any string format;
- Timezone (tzinfo) implementations for tzfile(5) format files (/etc/localtime, /usr/share/zoneinfo, etc), TZ environment string (in all known formats), iCalendar format files, given ranges (with help from relative deltas), local machine timezone, fixed offset timezone, and UTC timezone.
- Computing of Easter Sunday dates for any given year, using Western, Orthodox or Julian algorithms;
- More than 400 test cases.
And to give a small example, in addition to the many examples available in the web page, suppose I wanted to know the date of the three following company happy-hours, knowing that we have it once every month, in the last friday:
>>> from dateutil.rrule import * >>> rrule(FREQ_MONTHLY, count=3, byweekday=FR(-1))[:] [datetime.datetime(2003, 10, 31, 10, 37, 59), datetime.datetime(2003, 11, 28, 10, 37, 59), datetime.datetime(2003, 12, 26, 10, 37, 59)]
What about the next Friday 13th?
>>> from dateutil.rrule import * >>> rrule(FREQ_MONTHLY, bymonthday=13, byweekday=FR)[0] datetime.datetime(2004, 2, 13, 10, 42, 27)
Cool, isn’t it? ![]()