Posts about python (old posts, page 6)

2005-10-17 17:30

A *real* programming challenge.

A long time ago, I wrote a piece about how I didn't like kcalc. It contained a very lame pyqt script showing a (IMHO) nicer calculator. Strangely, that lead to two very cool implementations of the concept!

One of them was written in Ruby, the other one in C++. I think that has some potential.

A few months later, I wrote a spreadsheet based on the same concept. Also based on PyQt.

This StupidSheet has some conceptual problems. Like, if you want to import Excel sheets, you would have to rewrite basic in python, so it's not a practical program, but it is a rather nice example showing programming using dynamic languages.

In fact, I used it as such last week at CafeConf.

Now, here's the challenge. If people that know how to write Ruby or Java apps using Qt (or KDE, why not) could write a similar application, we all could write a comparative guide to Qt/KDE programming on different languages.

Since we would all be starting with a not-too-complex, but really non-trivial example, and we would all do the same one, it should be pretty unbiased.

In fact, if you think this example is biased, please propose another one, and do this thing anyway.

You can find StupidSheet here

It has some small bugs (try setting B1 to A1+1 with no value in A1 ;-) but they are easy to fix.

We could remove some features (like the weird pasting stuff) to make the example more didactic.

I hope this gets some answers :-)

2005-10-11 11:15

CafeConf 2005

Nuevamente este año voy a estar en CafeConf . Es una charla de 45 minutos sobre PyQt el 13 de octubre al mediodía.

La idea: La gente se sorprende cuando uno agarra KHTML, engancha un par de widgets y sale con un navegador web. Se deberian sorprender más de que uno puede partir de una receta de 20 líneas en una página web y terminar con una planilla que funciona ;-)

Por lo tanto, voy a mostrar StupidSheet como un ejemplo de que el desarrollo de software con interface gráfica es mas facil de lo que la gente cree.

Como siempre, si mencionás esta página, te ganás una cerveza. Máximo 2 cervezas, no muy buenas.


I will be at CafeConf again this year. It's a 45-minute thing about PyQt in October 13th, at noon.

My idea is: People are amazed when you hook Khtml to a couple of widgets and write a lame web browser. They should be more amazed that it is possible to start with nothing more than a 20-line recipe from a website and end with a functional spreadsheet ;-)

So, I will be showing StupidSheet as an example of how writing GUI software in Python is simpler than people think.

As usual, if you mention this page, you get a free beer, maximum 2 beers, and not very good beer.

2005-09-09 19:34

Authenticated Pages in CherryPy

CherryPy is a cool, pythonic, simple, quick, fun way to write web applications.

I often use CherryPy to write custom web admin tools for customers. Suppose you want to provide them with a simple way for password management. Usually I have the following requirements:

  • It must be simple ( not webmin )
  • It must not be a terminal session (bye ssh :-( )
  • It must not be a graphical session (sadly, that leaves out PyQt :-( )
  • It needs to do custom stuff: set the samba password at the same time, send a mail warning about the next forced change, whatever.

Someday I may be able to use a single-app freeNX session, but right now that's a bit too much problem for different reasons.

So, I wrote a CherryPy page. Over time, I have become quite fond of it, and wrote a bunch of small tools around it. One of them was a way to login the user into the site using the system's users and passwords. Now I got to throw it away :-)

The new CherryPy 2.1 has a mechanism for implementing password-protected pages, called the Session authenticate filter which is sadly not documented yet anywhere I can find.

So, here is my attempt, so people googling it up can use it. Excuse me:

cherrypy sessionauthenticatefilter cherrypy sessionauthenticatefilter cherrypy sessionauthenticatefilter cherrypy sessionauthenticatefilter cherrypy sessionauthenticatefilter cherrypy sessionauthenticatefilter cherrypy sessionauthenticatefilter cherrypy sessionauthenticatefilter cherrypy sessionauthenticatefilter cherrypy sessionauthenticatefilter

That should do it :-)

What you need first is a function that takes a username and password, and returns None on success, or an error message for the failure.

For example, I can adapt something I wrote earlier using checkpassword-pam

def validPass(name,password):
                cmd='/usr/bin/checkpassword-pam -s xdm -- /bin/true 3<&0'
                p=os.popen(cmd,'w')
                s='%s\000%s\000xxx\000'%(name,password)
                print cmd,s
                p.write(s)
                r=p.close()
                if r==None: #Success
                        return None
                else:
        return "Login Incorrect"

Also, you may want a function that returns the login screen. If you do, remember the following:

  1. It must set the form action to doLogin
  2. The user field should be called login
  3. The password field should be called password
  4. You will take a fromPage argument that you should pass through, so the user will end on the page he wants.
  5. You will take a errorMsg argument which is probably the result of a failed previous login. Display it red or something like it. Unless it's empty, in which case it should not be visible.

Here's mine.

def loginScreen(fromPage, login = '', errorMsg = ''):
content="""
<form method="post" action="doLogin">
<div align=center>
        <span class=errormsg>%s</span><p>
        <table >
        <tr>
        <td>
                Login:
        <td>
                <input type="text" name="login" value="%s" size="40"/>
        <tr>
        <td>
                Password:
        <td>
        <input type="password" name="password" size="40"/>
        <input type="hidden" name="fromPage" value="%s"/>
        <tr>
        <td colspan=2 align=right>
        <input type="submit" value="Login" />
        </table>
        </div>
</form>
""" % (errorMsg, login, fromPage)
title='Login'
return renderTemplate(file='logintemplate.html')

Although I am using a template to display it nicely and with the right style, it should be pretty obvious how it works.

You could use the default login screen provided by the filter. While it works, it's just ugly.

Then you need to apply the filter to the set of your pass-protected pages. Suppose you want the whole site to be protected, except for your /static directory, which contains the stylesheet, images and such. Then you put this in your configuration file:

[/]
sessionAuthenticateFilter.on=True

[/static]
sessionAuthenticateFilter.on=False

Next thing is to hook the session authenticate filter to your custom auth code. In your app, do the following. It seems that you can't do this in the config file, though, so do it in code.

    settings={
            '/': {
                                    'sessionAuthenticateFilter.checkLoginAndPassword': validPass,
                'sessionAuthenticateFilter.loginScreen':loginScreen
        }
}
cherrypy.config.update(settings)

And that's it. Now your site is password protected. You can even have different authentication schemes for different pieces of the site, by resetting the hooks for the folder you prefer to a different function.

Also, I think this is a good example of why I like CherryPy. This mechanism is both flexible, powerful and simple.

2005-09-02 23:16

Small Linux Revisited

A Little History

Many moons (almost two years!) ago, I wrote an article called Small Linux detailing what I had done to make a reasonable Linux fit in a Toshiba Libretto 50.

That's a very limited notebook, with under 800MB of disk, a 75Mhz Pentium CPU and 16MB of RAM, and it has served me well for a long time.

Now, however, I am using the almost exact opposite, a second-hand Toshiba Satellite 1955-S805.

Where Salma (the Libretto) had a 640x480 screen, Monty (Toshiba), has a 16" 1280x1024. The RAM has increased 32 times. But they have one thing in common....

The 800MB HD

You see, Monty is second hand. My future mother-in-law and brother-in-law brought it from New York when they visited, for Rosario (My future wife, until February 18 2006 ;-).

And it had a broken HD. And I wanted to use it while I got a nice new 60GB one.

So, overcoming my fear of destroying expensive equipment, I got the HD out of Salma and into Monty, and started thinking....

The Tallest Guy In The World

He had a problem: really bad feet. He died of it, too. In the same way, Monty now booted, but the app selection was outdated, and really, lots of things Salma couldn't do, Monty could.

What on earth can one install on that disk when you don't have any other real hardware limitations?

The choice of distribution was tricky.

I am a CentOS guy lately, but the package selection is entangled enough that you can hardly get X installed without crossing the 800MB. The minimal install is about 450MB.

Debian again? Well... no.

Knoppix?

Now, that has some serious potential, since I could run the OS from DVD/CD, and then use the whole 800MB for data. But I wanted something where I could choose what to install.

I could have gone the path of one of the modular Knoppix derivatives, but it was yet another task on the pile.

So, I went with.... ARCH.

ARCH Is Arch

Yes, ARCH is saucy. It installs in roughly 200MB, including kernel sources and GCC. That's quite small.

I managed to create a reasonable desktop in about 550MB, including:

Scite:
A nice text editor
Python:
Needed it to work in a few proggies.
Firefox:
I have the RAM. The CPU is a 2.56 P4.
Xorg 8.2 with Nvidia drivers:
And just for kicks, 3ddesktop to see if they work ;-)
fluxbox:
I know it, and it's nice enough.
putty:
Nicer than xterm, and has a handy SSH builtin.
ROX Filer:
Not really all that useful, but what the hell, for 3MB you get sidebars, a file manager and a few extra tricks.
Slim:
A very nice xdm replacement. Specially with the mindlock theme :-)
upx:
Compress the exes. Save 30MB. Good.
CherryPy:
It's what I am working with. And it's only 74KB.
habak:
Simple, small tool to set the X root decoration.
rsync:
Stay synced with my older desktop.

All included, I am at 120 packages, using 557MB of disk (with extensive trimming, see the original article for some examples).

So, what's the difference between this set of apps and my previous choice....

Well, look at the result of free:

             total       used       free     shared    buffers     cached
Mem:        512544     408924     103620          0      33468     162916
-/+ buffers/cache:     212540     300004
Swap:            0          0          0

Just for laughs: here's the old one, when doing roughly the same things: editing an article, browsing the web, a few terminals:

                total    used    free    shared   buffers        cached
Mem:            14708   14144     564      4644       816          5304
-/+ buffers/cache:       8024    6684
Swap:           47992   18880   29112

Scary isn't it? I am using roughly 25 times the amount of memory I used on the libretto. It's easy to see why, tho.

Consider the desktop. It shows a pretty picture. It is 1280x1024. It is in millions of colors. That is in RAM. That is either 3932160 or 5242880 bytes. On the libretto, I was intentionally not using anything there :-)

So, it really is not comparable anyway, and Monty's life as a malformed box will be short. But it was quite a bit of fun :-)

2005-08-04 21:27

Not letting stuff fall off the ' net

For a bunch of apps I write, I often want to be able to add a systray icon.

But... I write them using PyQt, and the systray stuff is in PyKDE.

But... Torsten Marek did write a module to do that. The only problem for me is the python-ctypes requirement, but it's no big deal for my apps that are not massively deployed.

You can find his code, in a somewhat mangled form, here

And since building extension modules is not completely trivial, here's a simple setup.py that will do it:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from distutils.core import setup
from distutils.extension import Extension

setup(
  name = "systray",
  ext_modules=[
    Extension('traywin', ['traywin.c'],  libraries=["X11"],library_dirs=['/usr/X11R6/lib'])],
)

Put it in the same folder with his code, then you can do python setup.py install or somesuch, then you can use it in your app like in Torsten's systray2.py example, and it will work.

2005-05-14 16:22

Data aware widgets in KDE

Well, reading in planetkde about how nice data aware widgets would be, I have to say this:

  • Data aware widgets are great
  • Data aware widgets in C++ are not the best possible solution

Using a higher level language, and specifically a more dynamic language makes lots of things much simpler.

As a tiny, lame example, please check the little thing I wrote about data aware widgets in python here.

I am sure that some of our better programmers (or more creative thinkers) can come up with awesome stuff if they divorce from C++ in this subject :-)

2005-05-13 18:13

Pissed off at SSH

Ok, not really, since SSH has made my life much simpler than it would be otherwise, but really, it has some usability issues.

And I mean real usability issues, not the usual crap.

  • It can't be integrated into kdewallet

While there is a mechanism to have a GUI asking the password, this helper app (askpass) doesn't get any session info, so it's meaningless, unles you are trying to directly start a X app over ssh.

Which you probably aren't.

  • Fingerprint management sucks.

Suppose you have a firewall. You keep port 22 as a way to log into it, and forward port 23 to a mail server in the DMZ. Well, it will complain and print huge, scary warnings each time you login into one or the other, depending on which one you used first.

Or, it can simply refuse to connect.

And that's just the easy two.

What can be done?

  • Take the dropbear client (not openssh, dropbear code seems simpler), and put a putty-like UI into it. Use the konsole kpart for display.
  • Take the GTK version of Putty and hack it into KDE shape, put kdewallet in it. I don't quite like the idea of having a seaparate, different terminal app for remote sessions.

I would probably go the dropbear route if:

  1. I had a working PyKDE (maybe someday)
  2. The idea of delving into someone else's C code didn't make me nauseous. (probably after I surgically remove my sense of taste).

2005-05-10 21:29

Extreme code reuse

I am, as always, playing with stuff. And I was faced with a problem I must have solved a dozen times before:

Given a list of items with obvious hierarchical names (say, a list of folders), turn it into a reasonable data structure.

Since there are not all that many names, there is no need to do it on-demand, or anything like that.

I must confess I suck at this kind of things because I hve to actually think them through. I don't know how to do this kind of things.

Mind you, I have done it before, but I said, hey, maybe google can help me...

And yeah! Python code from 1994 that does exactly what I needed. I had to touch a single line ( string.splitfields(a,'.') to a.split('/') ) and it worked.

The Internet never forgets!

2005-04-08 23:59

Sometimes things just click

I have been writing web-based interfaces for applications for about 5 years. Nothing public, nothing very interesting, just tiny front ends for custom tools in clients' installations.

And I have hated every minute of it. PHP hurts, Twisted hurts, mod_python hurts...

For a couple of months I have been using CherryPy and I finally am having fun doing it.

And after I figured out how to do AJAX using it, it's even more fun ( because the apps interaction model is not totally braindead :-)

I don't expect it to be as fun as PyQt/PyKDE, but it's totally not awful. I suppose the same epiphany comes to people when they use rails or some other decent, productive, fun framework.

All in all, I could get used to this.

2005-03-17 23:59

Linux: a not-unix-like OS.

Well, I am still experimenting with my concept-distro.

I am now up to a running PyQt using uClibc, which I thought unlikely ;-)

I completely removed all the sysv init stuff, and replaced it with runit, which has an interesting effect:

It boots to a graphical login in about 15 seconds. Inside qemu. In a 900Mhz duron. Including kernel loading.

Of course the trick is that you have the login while stuff is still loading, but I am working on that, too.

Since using runit it's pretty simple to get a overview of where the booting process is (services have dependencies, they simply get started in order, and in parallel), I will hack a system-wide ksplash-like thing on a side of the xdm (probably will end up writing my own whateverdm).

Think of it as Fedora's rhgb, only you can login instead of getting bored.

I also switched to a root-free system Ubuntu style. Not decided yet on it, but it's not hard to do (or use).

Next step: hack Knoppix HW-detection script (or rather rewrite them in a real language).

I understand why there are 743 Linux distros. It's quite a lot of fun to hack one together.

Oh, and it needs a name. It's not going to be useful for anyone, it's just a personal toy, but it needs one.

Come on, Planetkde guys, throw me names for a non-unix like linux, if you dare ;-)

Contents © 2000-2018 Roberto Alsina