Older blog entries for lgs (starting at number 30)

5 Mar 2005 (updated 5 Mar 2005 at 17:58 UTC) »
decompyle

Yesterday I finished the version of a Gazpacho small plugin and I was about to create a svn project in the central repository for that. I just have an XML file, a PNG image and a Python file. Well, I also have the compiled Python file (*.pyc)

As you may know, we don't want pyc or any other form of auto generated files in the repository. So, before importing my code I removed the pyc file.

Oops, Murphy used the fact that it was 8 o'clock in the night and I was pretty tired, to made me erase the actual .py file instead of the .pyc file. Magically, 238 lines of code dissapeared in front of me as I didn't have any other copy of that file. Now is where the laughs come up.

Fortunately I had heard of python decompilers so I started looking on the net and then asked Johan. The program I was looking was decompyle. apt-get install decompyle and see what happens.

It didn't work because the decompyle program of this Debian (Ubuntu) installation was too old and didn't know how to handle python 2.3 bytecode format.

So, back to the net and look for the last version. Wooho, I found it and it says it can handle 2.3 format. So, where is the freaking download button? Nowhere, this has gone commercial and you have to pay to get your files back :-(

Well, this is the free software world. Somebody writes a good software, people like it, people use it and he/she try to get some money from his work. Totally legal and right stuff.

Back to Johan, he told me there is a fork on this software to keep it free (as in beer). God blesses forks (and free software to allow them). But this time it was no easy to find it, since all the google links points towards the commercial page. Finally I found it here: http://mirrors.wamug.org.au/ubuntu/pool/universe/d/decompyle/

This time it works properly and I got my file back :-)

The day of the living exception

Thanks to Gustavo I just discovered this really nice Python recipe: Automatically start the debugger on an exception

2 Mar 2005 (updated 2 Mar 2005 at 19:57 UTC) »
Problems with gtype

Until recently the way Gazpacho instantiates widgets was using their python class. For example, for a GtkWindow I had the <type 'gtk.Window'> class, that is what you usually get when typing:

import gtk; print gtk.Window

The problem was when loading a .glade file. Then when you have to instantiate a widget you don't usually know the module where this widget has the class in. For example, let's see this (fake) glade file:

<?xml version="1.0" ?>
<glade-interface>
    <widget class="GtkWindow" id="window1">

Now, how do I get the gtk.Window class from the 'GtkWindow' name. Well, if we just work with gtk+ widgets it's easy. All I have to do is to strip the 'Gtk' prefix from the name, and look for 'Window' in the gtk module.

Ok, that's cheating, and certainly doesn't work as soon as you start working with other modules, like kiwi.

So I tried another approach: getting the gtype from the class name and building the widgets with gobject.new:

>>> gobject.type_from_name('GtkWindow')
<GType GtkWindow (136052312)>
>>> gobject.new(_)
<gtk.Window object (GtkWindow) at 0xb72e22ac>

Looks like this works perfectly but actually, it doesn't. The problem now is that when you create your widgets in pure python (as kiwi does) you __init__ method is not called anymore when using gobject.new(). Seems like a bug but it is not, since this is the expected behaviour. Even when it's the behaviour I don't want at all.

Sooo, back to the classes. Let's sumarize: I don't have an easy way to get the class object from the class name and I can't use gobject.new to construct the object. So let's get the class object from the gtype. That's the best solution and it would also be great if pygtk would support this :-(

Here is my workaround function that I hope I can remove as soon as this bug is fixed:

def class_from_gtype(gtype, module_list):
  for module in module_list:
    for name, klass in inspect.getmembers(module, inspect.isclass):
      if gtype == getattr(klass, '__gtype__', None):
        return klass

Note how easy is to get the gtype from a python class: it's on the '__gtype__' attribute.

Update: new version of class_from_gtype function thansk to Johan:

def class_from_gtype(gtype, module_list):
    def is_gobject_subclass(k):
        return isinstance(k, type) and issubclass(k, gobject.GObject)
        
    for module in module_list:
        for klass in filter(is_gobject_subclass,
                            [getattr(module, n) for n in dir(module)]):
            if gtype == klass.__gtype__:
                return klass
23 Feb 2005 (updated 23 Feb 2005 at 22:15 UTC) »
libglade lessons

Today Mikael explained me why using libglade for loading .glade files in Gazpacho is a bad idea.

Basically we don't want to add stuff to libglade that it is specific for a GUI builder like i18n information or other things like that.

We shouldn't depend on libglade adding this kind of stuff because it is not designed for that. It just ignores this kind of information because applications don't care about it.

Having said that it doesn't mean libglade should not accept some other changes to accept new GTK+ features. IMHO libglade is starting to show its age (7 years) and it's been a while since it has not added a GTK+ feature.

31 Jan 2005 (updated 31 Jan 2005 at 12:09 UTC) »
Improving my Python skils

After reading PythonIs Not Java, a great article by the way, I realized that when I write Python code I do some things just because I have a big inertia from other languages and from what some teachers teached me and don't really think in a Python way. Here are two things I should change:

  • Don't write setters or getters until you really need to do so because they involve more logic that just setting or getting an attribute. When the time comes to do so, you have the great property() builtin to allow you to do the changes without modifying any client code

  • Write functions than return functions so a lot of code can be reused. The inner function is a template for your common problem and the outer function is just used to give some parameters to the inner one

I specially like this sentence of the article:

Essentially, if you've been using Java for a while and are new to Python, do not trust your instincts. Your instincts are tuned to Java, not Python. Take a step back, and above all, stop writing so much code.

Thanks to Phillip J. Eby for this clear explanation

28 Jan 2005 (updated 28 Jan 2005 at 19:12 UTC) »
Gazpacho

Today I released 0.4.0 of Gazpacho and as always I forgot to do something. This time it was the announce text, I forgot to put a description about Gazpacho and some people asked me to do so. Sorry, I won't forget next time.

This release has a lot of new features thanks to the bunch of people who got interested in Gazpacho and who helped me with it.

I'll try to fix Menu Toolbar problems and make it rock solid for 0.5, which hopefullly will be next week. Btw, we are going to start using Gazpacho next week for real purposes so I expect bugs coming all over the places. I'm really scaried :-)

Plone

Today, I learned how to customize a Plone site so in one of the folders you can put a special page to show some information dinamically.

In my case I wanted to show the list of Plone sites that were running in our server. All this plone objects live under the folder 'sitios'. So let's go with the recipe:

  1. Write a Python script to get the list of plone objects and put it in the folder you want to use as the section for this dinamic page. Ours is called Asociaciones:
    resultado = []
    
    

    carpetasAExcluir = ['sandbox', 'Plantilla', 'CicodeGcubo']

    for carpeta in container.superValues('Folder'): if carpeta.getId() in carpetasAExcluir: continue portales = carpeta.objectValues('Plone Site') if portales: resultado.append(portales[0])

    resultado.sort(lambda a, b: cmp(a.getProperty('title'), b.getProperty('title'))) return resultado

  2. Write a Zope Page Template (ZPT) in the same folder with the name index_html. In this ZPT just say you are going to use the main template and you are going to override the content slot:
    <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"
          lang="en"
          metal:use-macro="context/main_template/macros/master"
          i18n:domain="plone">
      <body>
      <div metal:fill-slot="content">
        <div class="documentContent"  id="region-content">
        <h1 class="documentFirstHeading" tal:content="here/title_or_id">Titulo de la carpeta</h1>    
        <p>Esta es la lista de asociaciones cuyo sitio web está alojado en
        este portal:</p>
        <tal:block tal:repeat="aso context/listaAsociaciones">
          <div class="cajaAsociacion" >
            <h3><a href="#"
    	   tal:define="url python:aso.absolute_url()"
               tal:attributes="href python:url[:-7]+test(aso.isPrincipiaFolderish, '/', '')"
               tal:content="aso/title_or_id">
               Asociacion Sin Titulo
            </a></h3>
    	<p tal:content="aso/description">
     	   Descripcion de la asociacion
    	</p>
          </div>
        </tal:block>
        </div>
      </div>
    </body>
    </html>
    

  3. If you want, customize plone_css object in portal_skins/plone_styles to support the class I added in the example: cajaAsociacion:
    /* Estilo especificos de CicodeGcubo */
    /* Caja para las asociaciones en la seccion 'Asociaciones' */
    div.cajaAsociacion h3 {
    text-decoration: underline;
    }
    

As you can see, with Plone, logic, structure and visual aspect are separated. My grandma would be proud :-)

First post of the year. I have many nice things to say about me working in Async for the next 3 months but I'll just say I' m very happy to be among such good people and hackers.

So yes, I'm in Brazil, Sao Carlos and I'm writting these lines at Async Office which, btw, is very nice. There are plenty of young hackers among us and working with them is a pleasure. We even have three dogs to take care of ourselves.

So for the curious, first I will work on Gazpacho and Kiwi2 and once we have them in a usable state we'll try to make some interesting applications as fast as these tools let us.

It seems that we are getting some momentum with Gazpacho and more and more people is asking me about it which makes me very happy. Johan is helping me a lot and he is letting me know a fact already known by me: the code needs a lot of work. We probably need to redesign some parts as Gazpacho is not currently using some Python features that could make it much more powerful/easier to maintain.

First things I should work on is having an Application class and study the dependencies between all the different modules of Gazpacho so we can get rid of all those nasty globals all around the code.

Next thing I'd like to do is to wipe out as much as the XML files for the specific Widget code we have and use some Interface system.

So in other words, it's time to think about Gazpacho general design and write some diagrams and documentation about it.

Windows tricks

Yes, I'm learning some Windows tricks. Erny is my teacher and Google is my friend:

Autocompletion in the system terminal
Go to the Registry and assign a 9 to the key HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Command Processor\ComletionChar . Hint: 9 is the ascii code for the tab character

Autorunning Python programs
What I want is that if I have the file myprogram.py in the current directory and I type "myprogram" it should execute "python myprogram.py". So add ";.py" to the env variable PATHEXT

grep, diff, cat and some other old friends
Yes, we all know the great cygwin project but I want something much more lightweight. Voila!
XML-RPC From Javascript

I've been trying some fresh new concepts lately and it's time to share it with everybody who read this :-)

Sometimes I wish I could reload some part of a website without reloading the whole page. People usually do this by inserting an IFrame and reloading its contents with a Javascript timer or something similar. That's not a bad solution but I was looking for something more flexible.

So I jump into XmlHttpRequest. This is something Microsoft first created for Internet Explorer and then the other browser decided to provide something similar. So, except for the creation code, everything else should be crossbrowser.

So what you can do with XmlHttpRequest? Basically you can open http connections from Javascript so you can assign this kind of functions to onClick events or whatever you want, get some data from a server, and then use that data to update your favourite div. Pretty neat, right?

Well, not everything is so nice. Security issues arise when you want to make PUT request instead of GET ones. Mozilla won't let you make a PUT to a domain different from the domain your page is living on. Please note that http://localhost and http://localhost:8000 are different domains from Mozilla point of view. If you use a url of the form file:/// you just need to give your page some security permissions, but to be honest, file:/// urls are not very useful.

Next point, XML-RPC is cooler than simple HTTP, don't you think so? I was pretty happy to find that Mozilla has a component called nsXmlRpcClient.js (in /usr/lib/[mozilla|firefox]/components) that seemed to do what I wanted. Well, I spent the whole tuesday afternoon trying to make it work with the examples and couldn't make it.

So next day (yesterday) I decided to write my own XML-RPC layer on top of xmlhttprequest and I was pretty succesfull with very simple calls (no arguments). I was very excited to get something useful actually running. Today I just added a lot of sugar to it: multiple arguments calls, autoscrolling debugging console, more descriptive error messages, ...

The last problem was the security one? How do I have an http server (for hosting the pages) and an xml-rpc one at the same port so I can make Mozilla happy with security issues? Well, there are several solutions (Zope, your custom server, ...) but I just write a rewrite rule for Apache so everything that looks like http://localhost/xmlrpc/ is forwarded to my xml-rpc python server which is listening at port 8008. Simple and effective!

For those of you who want something visible I have some demos at http://sexmachine.homelinux.net/test_xmlhttprequest.html . Internet Explorer won't work. muHAHAHAHA

Informat 2004

I had a talk at Informat 2004 where I explained how to get money with Free Software. It seems people liked my words so I'm pretty proud and happy.

Manuel Martin, from La Junta de Andalucia, was also happy to know that our company try to make free software so hopefully we will work together in future projects. A great thing indeed.

Jornadas GNOME Hispano

14:45 end of the talk. 14.50 start driving to Madrid. 19.30 arrive to Madrid. 20.00 start my workshop about Python and GNome. 21.00 end of the workshop and start focusing in dinner. As you can see, a pretty busy friday.

Grex took us to a small bar in Madrid were we drunk a lot of Ribeiro and ate several Sepias, Croquetas and Pulpo. Amazingly it was only 6 euros each one!! Yes, Madrid. After going to some pubs and drinking a little bit more we had the oportunity to see acs and Jordi in some very funny situations.

Fabian, Antonio and me decide to head home and the adventure continued. Looking for Fabian house at 3 o'clock in the morning driving through Madrid citycenter is pretty funny specially if you think you are at the south of the Kio Towers and you are at the north instead. Blame the simetry!

So even if I only was at the end of the meeting I'm very happy I did 400 kilometers to be there because I talked with several interesting people and meet some very nice geeks.

Optimism

I finished work today and when I left the office suddenly it was night again. Last friday it was still sunny at the same time but it seems the autumm has came already.

Today, it rained a lot. I was driving home, listening to some good rock band. The reworked freeway was being a breeze and everything was making me feel good.

I like winter. I like raining. I like darkness.

A new week starts. Maybe a new life?

21 older entries...

New Advogato Features

New HTML Parser: The long-awaited libxml2 based HTML parser code is live. It needs further work but already handles most markup better than the original parser.

Keep up with the latest Advogato features by reading the Advogato status blog.

If you're a C programmer with some spare time, take a look at the mod_virgule project page and help us with one of the tasks on the ToDo list!