Archivos para la Categoría 'Uncategorized'

GSoC wrapup – Konqueror new bookmarks system

So GSoC ended already, as most of you already know. I haven’t been blogging as much as I would like, and I didn’t achieve to finish on time everything I wanted, but that’s not a defeat, only a delay – I will continue working on this bookmarks system until it can get merged into trunk. And then I’ll fix incomintheg related bug reports =).

So the state of the art is: we’ve got an akonadi resource for konqueror bookmarks which stores the bookmarks in nepomuk. We’ve got a bookmarks organizer, and we’ve got a bookmarks menu integrated in konqueror. The new location bar is however not finished yet, but that will be fixed within days.

A lot has changed since last report. I’ll try to explain here what’s the base structure of the new classes and what I’ve been doing, mainly related to the location bar, and why I followed that design decisions.

KCompletion

The current konqueror location bar uses a KCompletion class for autocompletion, which is mainly handled by KLineEdit. But how does it work? Let’s use a simple example. Imagine you are developing kmail’s new email dialog. For the line in which the user enters the destination email address, you could use a KLineEdit, but in order to easy the task of the user, you could use autocompletion like this:


KLineEdit* destinationLineEdit = new KLineEdit(this);
...
KCompletion completion;
completion.addItem("tigerwoods@fortune.com");
completion.addItem("billgates@microsoft.com");
...
destinationLineEdit->setCompletionObject(completion);

You could of course get the list of items to add to the completion object from the address list too ;-) . If you were developing instead the location bar for dolphin, you would like to have directories listed while the user is typing. Instead of adding and removing items manually yourself to the completion each time the user types, you can use a KUrlCompletion object that does that automatically.

But for konqueror location bar we have a problem: it needs to be able to use kurlcompletion for completing directories, but it also needs to complete from bookmarks and history. We need to work with multiple completion objects at once even though KLineEdit and similar classes can work only with one. Also, we need to do more complex completion A normal KCompletion object contains a list of strings and matches what you type with those, but for having an amazing location bar we need more power: if I type “work” and I have a bookmark tagged “work”, I want it to show up in the completion list even if its URL doesn’t contain the word “work” at all. And that’s only the beginning. I want to be able to set an order of the completed items depending on the relevance and type of the items, and more..

Enter Qt Model-views

I need to confess that I love Qt model-views classes. QAbstractItemModel, QAbstractItemView, QAbstractProxyModel, QSortFilterProxyModel, QTreeView.. They provide an standard convinient and flexible way to manage and display almost any kind of collections. Even collections of completed items. Actually, the completed items popup is in reality a QListWidget, which displays a model associated with the completion object..

But that is an internal model which KLineEdit doesn’t let me change. So the question that follows is.. why not use directly my own custom item models instead of a KCompletion object? And that’s what I did, even if it required a lot of work to be done.

First of all, I tried to outline in paper the master plan. What classes needed to be created for everything to work fine. Then I wrote step by step what needed to be done before what. Then I started following those steps one by one and it worked!

Places all over the.. place

The plan was that the location bar autocompletes places. A place could be:

  • a history entry from history entries model
  • a bookmark from bookmarks model
  • an url from a kurlcompletion model

I had already a bookmarks model and konqueror already has an history entries model, but I had no kurlcompletion model. I looked at the code of the KUrlCompletion class I decided that I didn’t want to rewrite it.. so I simply created a KCompletionModel which acts as a proxy and converts a KCompletion object in a QAbstractItemModel. So to create a url completion model, I do:

KUrlCompletion* urlCompletion = new KUrlCompletion();
KCompletionModel* urlCompletionModel = new KCompletionModel();
urlCompletionModel->setCompletion(urlCompletion);

To do a completion, I connect the urlCompletion to the textChanged(QString) signal from the lineedit. And the completion objects reflects the changes which in turn instantly appear in the model. It’s not the best solution but hey it works.

Also, another problem was that the completion object of KLineEdit would be replaced by a model, not three. But now as you see I have again multiple completion objects, so what was the solution? creating an aggregated model created out of multiple models. It works like this:


KAggregatedModel* aggregatedModel = new KAggregatedModel(this);
aggregatedModel->addSourceModel(bookmarksModel);
aggregatedModel->addSourceModel(historyEntriesModel);
aggregatedModel->addSourceModel(urlCompletionModel);

Now, those who know how an item model works will probably have a lot of questions about that. For example one could be.. Do all those models need to share the same columns? The answer is no. The aggregated model I created is quite simplistic in the way it works:

  • It assumes the source models have only one level of childrens.
  • It only shows one column, which is the default display column (sourceIndex.data(role)).
  • It shows the list of items as a list, showing first the items from the first item model, then the ones from the second, etc.

Places Manager

So far we have an aggregated model with completed urls, unfiltered bookmarks and unfiltered history entries. That’s yet not complete from being the amazing completer model. What we need to do is the amazing filtering and sorting. That’s done by the final completion model, the master of places..

It’s called PlacesProxyModel and inherits QSortFilterProxyModel. It takes a QAbstractIteModel and takes the Konqueror::PlaceUrlRole for each index, gets the URL, and obtains the corresponding Konqueror::Place for it. Then, knowing already all the available information for that place, tries to match it against the query the user entered in the lineedit and sets its relevance for sorting purposes. It also filters out duplicated entries. Quite an achievement, but how does all that work again?

First off, all previous models (url completion, bookmarks and history entries models) report their items to a Places Manager which keeps track of them and contains a Place for each relevant url. So for example, if the user has bookmark for http://www.kde.org and it’s been visited yesterday, there’s a place in the places manager with the information from both the bookmark and the history entry.

All those models also support obtaining the url related to each item by using the Konqueror::PlaceUrlRole. The aggregated model proxies calls to retrieve data from any role, including that. So in the end the information can be retrieved by the places proxy model. Then an algorithm that takes into account the number of visits, the last visit, if the user-written string matched the place’s url, title or tags, etc sets the relevance of the items in the proxy model.

The road to the location bar

The new location bar inherits from the modified KLineEdit which uses a QAbstractItemModel for completion, which I have named KLineEditView. An amazing location bar needs to be able to show an star that can be clicked to add/remove a bookmark, and the autocompletion needs to show for each place shown if it’s bookmarked, its tags, etc. Contextual information.

State of the art

What has been done? All the previous things I have mentioned are working. They can always improve, but the code is already there. The location bar widget is the last thing I started to write so it’s not finished: it has already plugins support so that new icons/sub-widgets can be shown inside the location bar. Now I need to write the plugin to let the user bookmark the current location, and I also need to write the CompletionPlaceDelegate to have a properly eye-candied completion list. And I’ll do it shortly.

Future and end

Unfortunately, a lot of things need to be done before this new bookmarks system ends up in konqueror trunk. Revamping such an integral part of Konqi is not a simple task. We also want to be sure that when the replacements comes into play the user doesn’t have to suffer it but to enjoy it instead, so I need to find fix and all the regressions. I need to write documentation and test cases too. I honestly don’t really know when the job will be done but I know I’ll continue working on it.

I want to thank specially my mentor David Faure for the support, for giving me a thumbs up even if I didn’t finish on time everything I wrote in my gsoc propossal. You rock david!

This is post has been too large I admit, so I think I’ll stop here :D . If you read everything yay you’ve got too much free time so go and do something more useful!

GSoC: I Am Alive! (And bookmarks too!)

First I want to apologise because I haven’t blogged fo a month about my gsoc. But that doesn’t mean that I haven’t been working, quite contrary. I’ve been having limited connectivity and the limited time I got access to Internet I didn’t feel like blogging. Now I do. Lot’s of things have happened. I’ve even suffered the H1N1 but don’t worry about that because it’s not as bad as TV shows: for me it was two days with flu and the third day I was 100% ok.

The konqueror bookmarks menu is already rewritten to support the new bookmarks system.  I like to read see other people’s code because it can inspire me when I want to develop something. Thus, I’ve been reading Arora code and I liked their idea of using QAbstractItemModel as the data source for QMenu and that’s how I’ve implemented the new bookmarks menu.

I’ve always wanted to have menus more advanced than just normal menus. When I saw that inside Mac OS X Help menu there’s a search bar I knew I wanted to have something like that in KDE and I wondered if that was possible. The answer is yes. Qt Menu system allows to insert custom widgets with WidgetAction class so I’ve added a Search Bar to Bookmarks Menu. When you type in the search bar, the source model of the Bookmark menu changes to a DescendantsPRoxyModel which represent all bookmarks and folders in a flat list and uses a QSortFilterProxyModel to filter out results. It’s not finished yet, there are some issues with the search but all in all I’m quite satisfied. Next step: Awesome bar, and fix more bugs =).

I’ve also been working on the bookmarks organizer, fixing bugs, adding support inline bookmark editing in the bookmarks view using double-click, adding a BreadCrumb view similar to Dolphin’s breadcrumb mode but using a QAbstractItemModel as a source for paths, etc. Here’s a small videocast where I show some of the mentioned features in action:

GSoC biweekly report++ – State of the bookmarks editor

Summers is already here for those who haven’t noticed – we’re having 44ºC here in Sevilla during the day and yesterday it was 36ºC at 23:30. That’s how Spain can be like in summer, so GCDS assistants you’ve been warned and don’t forget swim-wear!

First week of June I went to the AC/DC Madrid concert and it was awesome, but I didn’t program much that week. This week I’ve been working in the bookmarks editor, and now you can see that it’s getting more featureful. However I’d first like to share some comments about other bookmarks editors I’ve found over the net.

Safari 4 bookmarks editor with the iTunes-like cover view the most impressive:

Safari4b1CoverFlow

I haven’t tested it, but it’s quite clear that the cover view eats a lot of space. They remove the space dedicated for showing the details of current bookmark, and instead (I guess) the bookmarks are editable “inline”.

Another interesting point worth mentioning is that in the left side they have two sections: Collections and Bookmarks. In the new Konqueror bookmark editor I’m using Akonadi, and Akonadi already uses the concept of collections internally so something like that will be easy to implement. Instead of showing in the left a Tree with a Root element and everything inside that (Bookmarks Toolbar, Bookmarks Menu, Recently Added Bookmarks, Unclassified bookmarks, etc) I could use a lateral panel similar to the one used in the Open file dialog with those items, and then show a breadcrumb widget over the bookmarks listing widget to let the user know (and manage) the current location:

bookmarks 15 june - open file

Okey now let’s see what I’ve done so far. You can add, remove bookmarks, and edit them (either using the line edits or even inline in the bookmarks view), and also I’ve borrowed some code from dolphin to make the bookmarks view columns resize nicely. And you can show whatever columns you choose, it’s up to you:

bookmarks 14 june

If you look closely, you see that the menus are pretty similar to the current bookmarks editor menu. I’ve just replaced the Bookmarks and Folder menus with an Organize menu. Taking a look at Firefox bookmarks organizer vs. current Konqueror bookmarks editor, I see that Konqueror has more options but even then they seem quite intuitive. Also something to wonder is how is FF bookmarks organizer missing toolbar buttons for the most common actions: New Bookmark, New Folder, Remove.

bookmarks 14 june - cols

Next week, I want to have all the already listed features in the bookmarks editor working (see for example the “Find in bookmarks”? it doesn’t work. Same for the breadcrumb which is just some text in a label, etc), and the following week I’ll hopefully have sorted out how to do the virtual folders structure and show it to the user in the bookmarks editor.

Pequeño relato: Agudiza tus sentidos. ¿Qué hora es?

Mi hermano Félix ha encontrado una chica que le gusta mucho. No obstante cuando hemos visto una foto suya nos hemos dado cuenta de que pasa algo raro: la chica es muy vieja y fea, y él habla de ella como si fuese mucho más joven y bella. Intentamos razonar con mi hermano, pero se vuelve histérico. Félix tiene su visión nublada, y no ve la realidad como tal. Inmediatamente nos damos cuenta de esta certeza, y a este comportamiento sólo encontramos una posible explicación: ha sido hipnotizado.

Mi hermano es cabezota por naturaleza. Yo creo que es genético. En realidad sea una característica común de los seres humanos, pero los hay más empecinados que otros. Cuando él ve una foto de esa chica, sus ojos reciben la imagen real de una poco agraciada y vieja mujer, pero el cerebro humano está entrenado para interpretar lo que ve sin darnos cuenta, y el suyo concretamente ha sido programado para ver al amor de su vida. Así que su mente es lo que finalmente ve. Una mala persona ha debido hipnotizarle con algún tipo de excusa, y manipulado su mente cuando estaba su merced para conseguir este efecto.

Igual que si nos pasara a una persona que no tiene su mente manipulada, cuando le decimos a mi hermano que esa mujer no es lo que él ve, se niega a reconocerlo. Le estamos diciendo lo mismo que decía Groucho: ¿De quien te vas a fiar, de mi, o de tus engañosos ojos?. A cualquiera que le hagas esa pregunta, la respuesta es obvia, y para Félix también. Pero en su caso es peor, porque sus ojos (personificando en ellos a su mente) realmente le están engañando. Y en lo más profundo de su mente, él también lo sabe, pero su mente se resiste a admitirlo. Es lo que se llama, en terminología Orwelliana, el doble-pensamiento: una verdad da lugar a otra visión de la verdad completamente errónea, desechando y olvidando automáticamente la realidad. 2 + 2 = 3.

Pero en alguna parte de su mente, sabe que esa mujer no es tan bella como él la ve. Una parte de su mente sabe la verdad. Y cuando se le confronta con la verdad, su mente lucha por mantener la verdad que actualmente admite como válida. Su mente lucha por tapar la realidad, y por ello mi hermano se pone violento; está defendiendo lo que es suyo. En estos momentos mi hermano Félix se había ido corriendo a su cuarto, probablemente a chatear con tan apuesta muchacha. Y pobre del que se acercara.

Le llamamos, e intentamos hablar con él. No da resultado y se vuelve a poner violento, y no atiende a razones, como anteriormente. Cuando el resto de mi familia, preocupada, ya se da por vencido, intento razonar con él, para a su vez hacerle entrar en razón:

- Félix, escúchame aunque no me creas. Tu eres ingeniero, y a ti te gusta la lógica, y razonar, siempre te ha gustado. Puede que te parezca una locura lo que nosotros te intentamos decir, y puede ser bien cierto que nos hayamos vuelto todos locos y tu seas el único cuerdo que queda en esta sala. Pero somos tu familia y merecemos que nos escuches. Verás, has sido hipnotizado para creer algo que no es cierto y tomarlo como la verdad. Sin duda es una locura, y lo es tanto para tí como para nosotros. Pero a ti te gusta la lógica, te gusta la ciencia. Así que juguemos.

Cuando alguien es hipnotizado, su mente entra en un estado parecido al de la mente cuando uno entra en un sueño. Ve todo lo que le rodea como si fuese real, y aunque no lo sea, no se plantea esta opción. Muy probablemente la capacidad de ser hipnotizado es debida y va estrechamente ligada a nuestra habilidad de soñar. No obstante, a diferencia del sueño, la mayor parte de lo que ves cuando estás hipnotizado es real, y la mayor parte de lo que ves como normal es normal. Así pues, en el hipotético caso de que una persona esté sometida a hipnosis ¿Cómo puede darse cuenta?

No lo sé, porque no soy ningún tipo de experto en hipnosis. Pero si mi tesis es cierta y esa mujer tan guapa y joven no lo es en realidad, es necesario averiguarlo. Sabes como yo que en los sueños cuando eres consciente de que estás soñando éste hecho se llama sueño lúcido, y normalmente te despiertas con facilidad de un sueño de este tipo. Nuevamente, si mi tesis es cierta, esperemos que ocurra lo mismo cuando alguien está bajo hipnosis y se vuelve consciente de ello. Cuando estás en un sueño, un truquito para averiguarlo muy conocido es averiguar qué hora es. Cuando miras la hora en un reloj en un sueño, luego aparta tu vista del reloj un momento  y vuelves a mirarlo, el reloj ha cambiado su hora siempre, y además probablemente pone horas sin sentido del estilo: 33:71. Esto es parte fundamental de la forma en que funcionan los sueños: ocurren cosas sin lógica ninguna, pero no te das cuenta porque no te lo planteas y por tanto eres inmune a ese tipo de fallos en la realidad. La idea de los que persiguen darse cuenta de si están experimentando un sueño lúcido es darse cuenta de esos fallos en Matrix ¿Sabes qué hora es sin mirar el reloj Félix?

En estos momentos mi hermano se pone muy nervioso y busca un reloj donde mirar la hora. Confieso que yo mismo me pongo algo nervioso. Le contesto yo mismo:

Por como está el sol y el rato que llevamos despiertos, y dado que es verano, deben ser las siete y media de la tarde. No obstante este tipo de pistas sobre cosas que fallan ocurren en los sueños y puede que no ocurra igual cuando estás hipnotizado. Sabemos por las películas y por aquel día que fuimos a un espectáculo de hipnotismo que cuando te hipnotizan cierras los ojos, y escuchas una voz que primero te relaja y te deja indefenso, y luego te dar ordenes cuando estás hipnotizado. Esa voz probablemente intenta asemejarse a la voz de nuestra consciencia para llegar a suplantarla temporalmente. Cuando estas hipnotizado, es de suponer que nuestra consciencia real habrá sido doblegada por la voz del hipnotizador y dirá lo que éste último le ordenó decir.

Por otra parte también sabemos que cuando te hipnotizan, a diferencia de como pasa en los sueños, muy probablemente el 99% de las cosas que ocurren son reales. Se mezcla realidad e imaginación. Para diferenciar lo uno de lo otro, si estás realmente hipnotizado, agudiza tus sentidos. Si no lo estás no sufrirás ningún tipo de penalización por intentar hacerlo así que por favor inténtalo. Intenta escuchar esa voz de tus consciencia de forma consciente, intenta escuchar que dice y averiguar si eres realmente tú. Intenta también escuchar mi voz con atención, y fijarte en los detalles: de donde viene, el tono de voz, quien habla..

De repente, me encuentro a oscuras tumbado en mi cama escuchándome a mí mismo balbuceando, e inmediatamente dejo de hablar. Todo ha sido un sueño. Intento abrir los ojos que tengo pegados con las legañas, y averiguar qué hora es no por saber si estoy en un sueño o estoy hipnotizado, que cuando estás despierto es evidente que no es así (tan evidente como cuando estás soñando o estás hipnotizado, pero cierto esta vez, supongo), sino para saber si debo seguir durmiendo. Noto que entre las rendijas de la persiana se cuelan algunos haces de luz y por tanto es una hora digna para levantarme.

Me voy a la cocina a desayunar, a hacerme mi zumo de naranja y tomar leche con cereales, mientas me asombro del sueño tan surrealista que acabo de tener, a la par que pasa el tiempo y rápidamente voy olvidando detalles del sueño. Mientras desayuno,  se me ocurre pensar en el significado de este sueño,  e incluso me acuerdo de otro sueño que había tenido esa misma noche. Creo que en el sueño que aquí he contado, mi hermano me representa a mí mismo – quien mejor que mi hermano gemelo para actuar por mí – y lo que es peor, yo también hago de mí mismo, pero intentado despertar a mi otro yo. Objetivo cumplido, pienso.  Cuando termino de desayunar, escribo este relato.

Escándalo electoral en las Autonómicas y Europeas

La Junta Electoral Central niega la recogida de firmas antes de la convocatoria electoral a PIRATA y otros partidos minoritarios exigiendo condiciones absurdas como la necesidad de recoger las 15 mil firmas para poderse presentar a las Europeas en tan sólo 3 semanas, recogiéndolas una a una ante notario pagando 60 mil euros o bien validando las firmas ayuntamiento por ayuntamiento a lo largo de la geografía española.

Más en el comunicado de PIRATA. Hay que decirlo más.

Web Encryption Framework

Last year danigm, which is a good friend of mine told me about this new project he was going to undertake, that he will present to CUSL (Free Software University Contest). It’s GECO (Password Manager), which will allow you to store your passwords online so that you can sync them in different computers.

Of course, storing all your passwords must be done in a very secure way if you don’t like surprises. The connection with the server must be secure (SSL?) so that no one else can see your passwords. But what’s more, are you going to upload your passwords in clear? No way buddy, that’s too risky. I wouldn’t trust all my passwords not even to my best friend, and even if so, what if the server gets compromised?

So the thing is, GECO is designed to have both a web and desktop client. The problem here is that current web browsers like Firefox don’t provide a standard framework to cipher and decipher data on the client. You’ve got SSL, but that only ciphers communications with the server, and that doesn’t solve the problem.

So what did my friend danigm do? He will be using Slow AES, a free software implementation of AES both in Javascript and python. Because he not only needs to be able to cipher and decipher text in the client via Javascript, but he also needs to ensure that when he uses the gnome desktop client developed in python, exactly the same AES algorithm implementation is used, so that what is ciphered using the web client can be deciphered in the desktop client and vice-versa.

The penalty of this is that this AES implementation is, as it name shows, slow. That’s not much a problem for ciphering small text strings like passwords. But I’m using his project as an example of what I think is coming next in the future. Because web applications are becoming common in our daily Internet life. There’s Gmail for example, which is an astonishing piece of software, and I’m tempted of using it replacing the good old KMail, but there’s one big feature that I’m missing: GPG.

I’ve tried the GPG Firefox plugin for Gmail, but it doesn’t work very well and besides, it doesn’t in other web browsers, like our all times favourite Konqueror. I’ve even used sometimes the Gtalk chat Gmail’s feature, which connects via Jabber to my IM contacts but also with my email contacts that use Gmail, which is handy sometimes, but being me an avid user of Kopete’s OTR plugin, I miss the security it provides. Finally, there are also some web services which provide online data
storage, an online hard disk if you want to name it like that. Google itself seems to be playing with idea of launching the Google Drive. Storing more
and more data online will make yourself much more exposed to potential privacy loss risk unless they are stored encrypted.

As a consequence, I think SSL is not enough any-more as a way to protect your privacy online: we need a comprehensive, well-designed framework for encrypting and decrypting data in the web browser. The next question is, then, how should be such a framework?

I have some ideas about that too: it should use standard implementations of well-known algorithms, like GPG and RSA. Probably a Javacript binding of lybcrypto should be fine. But we need also a way to ensure users that the clear data is not going anywhere else, meaning that the Javascript code is not playing tricks like copying the clear data and sending it to the web server, and the web server will only get the ciphered data and not in clear.

Now, there’s no easy way to solve that. In order to accomplish that last point we need to isolate the part of the page that deals with the ciphered data from the part of the page which deals with the clear data, creating a software jail for the later. The idea is having special html tags or tags with special attributes, which:

  1. Can be stylized using css (remember? it’ not 1999 anymore)
  2. Ciphered data can be processed securely and transparently in the web browser without compromising its security.

So normal Javascript code would see this data ciphered, and would be able to communicate with the server via usual ways: either sending a form via POST/GET or using AJAX. In the other hand, the Javascript code that deals with the encrypted data would see the data in the clear, but would not be allowed to communicate
with anyone, to send the data anywhere. That code is in jail. And for various purposes like updating the encrypted data, some information would be allowed to flow from the normal Javascript code to the jailed Javascript code, but not in the opposite direction; information would flow only in one way: from insecure code to secure code, not compromising security.

Of course, if such framework gets developed, standardised and deployed in most web browsers, even then some sites won’t make use of it at least for a long time. It’s not in Google’s best interest to let you cipher easily your email and IM conversations if they want to be able to show contextual ads, for example. But other services like GECO, or other kind of services we can’t even think of yet, will surely make good use of such a framework, and that’s the idea. I think the potential use of a Web Encryption Framework (or WEF for friends) is not only in common-place web applications and web services, but also in business web applications where security is a must.

Don’t get me wrong, I haven’t thought the actual details of this proposal. What you see here is all I’ve got at the moment. This is only one idea that I wanted to write about so that you people tell me what do you think about it, so now it’s your turn.

Licencia GPL vs. aplicaciones web. AGPL

Esta nueva entrada en el blog proviene de un mensaje que he mandado a la lista de correo de Sugus. Lo publico en mi blog porque quiero tener una URL que pasar a la gente cuando quiera que conozcan el problema que tiene licenciar bajo GPL software en red, y cómo la licencia Affero GPL lo soluciona.

Hay cierto desconocimiento sobre los términos de la GPL en las aplicaciones web. Creo que es importante para aquellos interesados en el software libre conocer realmente las implicaciones de la licencia libre por excelencia, la GPL.

La GPL y todas las licencias libres han de cumplir las cuatro libertades del software: poder ejecutar el programa, acceder al código, modificarlo y redistribuirlo. Pero estas libertades sólo las tienen los usuarios del software.

Edulix 2010

Si yo soy un usuario de MS Windows y quiero ejecutar el sistema operativo Edulix 2010, puede que tenga que pagar para ello. Si yo como creador del software elijo un modelo de negocio en el que sólo los usuarios
legítimos, aquellos que tienen binarios de Edulix 2010, puedan acceder al código cuando me lo pidan por email, eso lo permite la GPL. Y si elijo también que tengan que pagar 35€ para que yo les ofrezca una copia de Edulix 2010, la GPL también lo permite. Libre != Gratis.

Claro que.. cualquiera podría pagar 35€ y luego redistribuir mi software de manera gratuita.

Google

Ahora pongamos como ejemplo el caso del código del buscador Google. Nadie que no sea de Google tiene acceso a él, e incluso dentro de la propia compañía casi seguro que guardan cierto control sobre su código para que no haya filtraciones.

Resulta que los únicos que tienen acceso a los binarios o código de las páginas web de Google son los propios empleados de Google, y por tanto, son los únicos “usuarios legítimos”, por llamarlo de alguna manera. De esa forma, si el código fuese GPL y sus usuarios decidieran no redistribuir el código a
nadie, seguiría siendo técnicamente software libre, igual que cuando te bajas un programa que sea software libre, lo modificas y no lo redistribuyes.  Sigues cumpliendo con los términos de la GPL.

Eso es lo chocante: pese a que millones de personas acceden a la página web de Google todos los días, su código podría estar bajo licencia GPL y sin embargo todos éstos millones de personas no tendrían derecho legítimo a acceder al código fuente. Desde mi punto de vista, es un fallo de la GPL.

Affero GPL (AGPL)

La licencia AGPL resuelve precisamente éste problema. Es una copia calcada de la GPL, pero añade una cláusula (sección 2(d)) que añade la obligación de distribuir el software si éste se ejecuta para ofrecer servicios a través de una red de ordenadores.

En el preámbulo de la propia licencia lo explican claramente (traduzco del inglés):

La Licencia Pública General GNU permite crear una versión modificada y dar acceso público a ella en un servidor sin tener que liberar el código fuente al público.

La Licencia Pública General de Affero GNU está diseñada específicamente para asegurarse de que, en esos casos, el código fuente modificado esté disponible a la comunidad.

Como véis no me estoy inventando nada. Eso lo dice la licencia oficial de la FSF. Ah por cierto también explican que la GPL v3 en principio iba a contener la famosa cláusula 2(d), es decir que iba a ser igual que la AGPL… pero que algunas empresas [1] no les gustaba la idea y por tanto la quitaron
de la versión final de la GPL v3. (y digo yo: vendidos!)

Lujury, conclusiones

Así que… Anarb, lo siento pero técnicamente Lujury podría perfectamente ser libre, GPL. Algunos me llamarán taliban por esto pero.. pero desde mi punto de vista la GPL y demás licencias que no tienen en cuenta el problema del software en red no son suficientemente libres. Stallman es un vendido, podría
haberlo arreglado en la GPLv3 y no quiso :-P . Tenemos la GPL en un altar y ésto nos puede llevar a confusión cuando no comprendemos realmente la licencia.

¿Mi sugerencia/solución? Para aplicaciones en red como las páginas web, licenciar el software bajo Affero GPL (AGPL). Y yo incluso abogaría por especificar éste problema para que las licencias que no lo resuelvan no sean consideradas completamente libres por la FSF o la OSI.

[1] Lo siento no he encontrado la referencia sobre lo de “algunas empresas”, pero juro que lo leí en alguna parte xD