danigm's picture

Desde su comienzo, la idea de los ultraportátiles me ha parecido de los más atractiva, porque siempre he considerado que un portátil debe poderse llevar encima y hasta hace relativamente poco parecía que la tendencia era totalmente opuesta, con portátiles de 17 pulgadas y cosas similares.

Yo ya tenía un portátil pequeño, un dell xps 1210, de 12 pulgadas y dos kilos de peso que llevaba siempre en la mochila, por esta razón un ultraportátil al precio de 300 o 400 euros no me parecía necesario.

Sin embargo la semana pasada vi la oferta del asus eee 901 por 200 euros. Es el portátil más pequeño que se puede llegar a tener sin que inusable. Así pues me decidí y me lo compré.

eee

Este portátil viene por defecto con Xandros, una distribución basada en debian. Y por defecto viene con un tema de gtk parecido al estilo de xp silver y un escritorio para netbook. Como no me gusta nada ese sistema en cuanto pillé el cacharro le metí una Archlinux.

No fue difícil puesto que hay una página en el wiki de Arch donde está todo detallado y funciona todo a la perfección.

Para los netbook se han ideado diferentes escritorios, como el ubuntu netbook remix, pero para mí es más usable un escritorio estándar.

Así pues me he instalado un xfce4, con compiz, y como gestor de aplicaciones y lanzador utilizo gnome-do con el tema docky.

Estoy bastante contento con el rendimiento de esta máquina, ya que la batería le dura lo más grande (4.5 o 5 horas), es tan rápido como cualquier otro portátil y además para lo que yo uso un ordenador es completamente funcional.

Simplemente me he encontrado con problemas a la hora de diseñar con inkscape, puesto que la pantalla es demasiado pequeña y ni siquiera me cabe el programa, aunque con un poco de esfuerzo se consigue hacer cualquier cosa.

El teclado puede parecer incomodo, pero por lo menos yo me he acostumbrado a su tamaño y soy capaz de escribir de igual manera que en un teclado tradicional.

Otra funcionalidad para la cual es genial este aparatito es para leer libros en formato pdf, ya que los puedo abrir en el evince, ponerlos en horizontal y tumbarme en la cama como si fuera un libro y leer.

Y por último y no menos importante este es el primer portátil que consigo comprarme sin tener que pagar la licencia del windows de turno y por supuesto el teclado viene sin la tecla propaganda del maligno.

Hay una frase muy conocida; "Este es el año de linux en el escritorio", y yo creo que esto ya pasó hace muchos años. Por lo menos yo llevo muchos años usando linux en mi escritorio y esperando que no me obliguen a comprar un software que no quiero porque el hardware no se vende libre. Y por fin parece que es posible conseguir eso, parece que cada vez es más fácil conseguir un ordenador sin que venga con la pegatina de windows.

GECO's picture

Previously on GECO...

La semana pasada ya estuve programando algo, y conseguí una versión funcional, eso sí, solo para lectura, es decir aún no se podían añadir contraseñas nuevas. Sin embargo el cliente web listaba todas las contraseñas y era posible conseguir cualquiera.


gecoweb8

Un gran problema con el que me he encontrado es copiar una contraseña al portapapeles desde javascript. Por lo visto firefox lo tiene capado y no es viable desde javascript. Hay alguna chapucilla por ahí que utiliza un swf para hacerlo, pero me parece demasiado complejo para eso.

Así pues la solución por la que opté es no copiar la contraseña al portapapeles automáticamente sino que pego la contraseña descifrada en un textbox para copiarla rápidamente pulsando ctrl+x. La contraseña está visible durante 5 segundos si no haces nada para evitarlo, pasado ese tiempo se quita.

También le he añadido los botones de editar y borrar. Editar todavía no está implementado. Borrar funciona perfectamente, el único pero que tiene es que no pregunta por confirmación.

¿Qué hemos avanzado hoy?

Esta tarde he estado haciendo el formulario para añadir una nueva contraseña en el cliente web.

Le he añadido un generador de contraseñas aleatorias y además comprueba la fortaleza de esas contraseñas.

La cosa funciona así, el cliente web recibe la contraseña en claro, ya sea generandola con javascript o escribiendola a mano. Mediante javascript se cifra esta contraseña. Luego al pulsar "Vale!" se envían los datos del formulario, pero claro está, no se envían las contraseñas en claro, es más, se puede añadir una contraseña escribiendo tan solo la cadena cifrada.

Por lo tanto las contraseñas creadas desde el cliente web son teóricamente seguras.


gecoweb7

Y nada más, lo próximo será habilitar la edición y comenzar con el cliente en gtk, aunque antes de eso debería habilitar una función tanto a nivel de gecojs como de gecolib para cambiar la contraseña maestra de todas las contraseñas, valga la redundancia :P

GECO's picture

Python es un lenguaje con el que se pueden programar grandes cosas sin tener que conocer nada más que un par de cosas, pero que si te pones a aprender vas aprendiendo diferentes formas de hacer las cosas.

En python todo es un objeto. Esto que parece una tontería, en realidad lo es. Todo un objeto, guay, una función es un objeto con un método __call__. Por lo tanto puedo hacer una función que reciba como argumento una función y devuelva una función. Y eso está guay, y es uno de los fundamentos de la programación funcional.

Y te preguntarás, ¿Para qué puedo querer yo una función que reciba una función? Pues eso es un "decorador" en python. Y tienen su utilidad. Y da la casualidad de que cuando no conoces algo no tienes la necesidad de usarlo, pero cuando lo conoces dices: "¿cómo he podido vivir yo sin esto?".

Así pues en cuanto supe de los decoradores en python empecé a verle utilidad en cada programa que hago.

¿Y a qué viene todo esto? Vamos a ver algún ejemplo práctico que he usado en geco.

Por ejemplo, para el cliente web yo tenía varias funciones en las cuales hacía la misma comprobación:

  1. def GET(self, args):
  2. username = session.get('username', '')
  3. if username:
  4. ...
  5. (aquí lo importante de la función)
  6. ...
  7. else:
  8. raise web.seeother('/login')

Para evitar la repetición de este código se puede usar un decorador, y la cosa quedaría así:

  1. @authenticated
  2. def GET(self, args):
  3. ...
  4. (aquí lo importante de la función)
  5. ...

Si esto se escala a varias funciones claramente se ve que nos ahorramos un buen cacho de código (no tanto :P ), y la parte realmente importante de la función queda mucho más clara.

authenticated es una función que recibe una función y devuelve una función, y que con la sintaxis esta tan bonita de la arroba no quiere decir más que esto:

  1. def GET(self, args):
  2. ...
  3. (aquí lo importante de la función)
  4. ...
  5. GET = authenticated(GET)

Pero con la sintaxis de la arroba queda más bonito. Por otra parte queda ver el código de la función decoradora:

  1. def authenticated(function):
  2. session = web.ses
  3. def new_function(*args, **kwargs):
  4. username = session.get('username', '')
  5. if username:
  6. return function(*args, **kwargs)
  7. else:
  8. raise web.seeother('/login')
  9.  
  10. return new_function

Es una función, en la cual se define una función anidada, new_function, que recibe un número indeterminado de argumentos sin nombre (*args) y un número indeterminado de argumentos con nombre (*kwargs), y desde esta función anidada se hace una llamada a la función original que es la que se recibe por parámetro.

Otras cosas interesantes de python

Cuando en una función se define un parámetro con asterisco (*args) quiere decir que esta función puede recibir varios argumentos. Estos argumentos se almacenan en una lista de nombre args. El operador asterisco también sirve para desplegar una lista en argumentos a una función, por ejemplo una función que reciba dos argumentos "def f(x, y): pass" puede ser llamada pasándole una lista como
argumento "a = (1, 2)", ">>> f(*a)".

Lo mismo que lo anterior pasa cuando se ponen dos asteriscos, pero en lugar de tratar con argumentos sin nombre tratamos con argumentos con nombre y en lugar de una lista tenemos un diccionario. Por ejemplo:

  1. def f(x=1, y=2):
  2. pass
  3.  
  4. d = {"x": 3, "y": 5}
  5. f(**d)

-> pass -> no hace nada
-> raise -> sirve para lanzar una excepción

Y ya está, que me enrollo. Pronto pondré más capturas y contaré como va el cliente web, que ya tiene una pinta estupenda :P

GECO's picture

Vale, es verdad, la forja de rediris tiene la funcionalidad de asignar tareas y demás, pero no me gusta, es demasiado arcaica. Así que he creado el proyecto geco en launchpad y he enlazado la rama que hay en mi servidor, que está en bazaar.

Vale, hay que usar la forja de rediris, y yo la uso, tengo el plugin bzr-svn con el que cada push de mi rama se sube al subversion de la forja de rediris. Ya intenté usar las listas de la forja (no he conseguido que funcionen) y no me siento cómodo con esta forja, así que a usar launchpad.

¿De qué va la cosa? Pues de que voy creando una serie de "bugs" en launchpad y siguiendo estos voy orientando un poco el desarrollo. Sería una especie de lista de cosas por implementar.

Por otra parte, aunque parezca que no, yo sigo implementando a mi bola, y ya utilizando el sistema porque tengo muchas contraseñas que gestionar.

danigm's picture

Desde pequeño yo siempre he tenido, digamoslo así, habilidad con los lápices. No es que fuera, ni sea, un gran dibujante/pintor/artista, pero hay que reconocer que algo hay.

Recuerdo que cuando iba a parvulitos yo era bastante competitivo y siempre quería acabar antes que los demás las actividades, cuando los demás iban por la letra c en la cartilla micho yo iba por la m, y no toleraba que me pusieran al nivel de los demás.

Siguiendo este afán cuando tocaba colorear, yo era siempre el primero en acabar, por supuesto consiguiendo una estupenda obra de arte pero sin respetar para nada las líneas que en teoría delimitaban el dibujo. Así era yo, cualquier gafapasta diría que era un rebelde creativo, pero mas bien era un chaval que no sabía colorear.

Por aquellos tiempos en los que yo era joven, joven de verdad, era un seguidor acérrimo de Bola de Dragón, como cualquier chaval de la época. Y por otra parte yo era de los chicos a los que les flipaba jugar con muñecos de plástico. Yo quería tener muñequitos de Goku, Picolo, etc. Pero por aquellos tiempos mi poder adquisitivo se limitaba a unos 20 duros (100 pesetas) los domingos, y eso era para jugar a las recreativas, así que había que buscar otra solución.

Así pues los primeros dibujos medio en condiciones que recuerdo eran personajes de bola de dragón. Los dibujaba, los coloreaba y los recortaba, y tachán! ya tenía un par de muñecos con los que recrear las emocionantes peleas de la serie.

Como todo buen estudiante, tenía la última página de todos mis cuadernos llena de dibujos y tonterías, pero aún no tenía un estilo propio.

Mi vida como dibujante dio un giro gracias a una excursión escolar a Sevilla. Sí, se trajeron a un colegio de un pequeño pueblo de Córdoba a Sevilla, y acabamos llegando a la plaza de España. Allí había un dibujante de caricaturas, que dibujó a un par de amigos míos. Y ese dibujante fue sin quererlo un gran maestro para mí.

Observé maravillado cómo ese hombre dibujaba unos personajes sobre papel y teniendo ya un bagaje artístico considerable aprendí unos cuantos trucos y desarrollé casi sin quererlo un estilo propio, mezcla de lo que pude recordar de aquel día y lo que ya tenía.

A partir de ahí comencé a dibujar mucho más y a creerme capacitado para hacer lo que quisiera. He ido desarrollando mi estilo personal hasta llegar a crear personajes con un toque especial.

Nunca he necesitado de un lápiz para dibujar, nunca me han gustado las gomas de borrar, he sido cliente fiel de los bolis bic de toda la vida, y además simpre me ha gustado el boli negro, no sé por qué.

Y un día llegó a mis manos un ordenador. Y en el ordenador había herramientas con las que se podía dibujar. Incluso hice mis pinitos con la animación en flash (4º de ESO) cuando aún no era usuario fiel de linux.

Poco más tarde me hice usuario de linux y ahí encontré más herramientas para dibujar. Al principio con gimp, escaneando dibujos, coloreando, incluso llegué a tener una tableta digitalizadora.

Y finalmente, no recuerdo cuánto tiempo hace, pero no más de 6 años, descubrí lo que era el dibujo vectorial gracias a inkscape, y desapareció la necesidad de escanear dibujos y desapareció la necesidad de usar un lápiz digital, ya podía dibujar con el ratón y de una manera más simple, e incluso más potente.

Y así llegamos hasta el día de hoy, lo mío es el dibujo de personajes no realistas, pero también le he dado a todos los palos del diseño, haciendo carteles, logos, personajes para videojuegos.

Algunos trabajos que yo recuerdo que he hecho, como por ejemplo:

Si necesitas que te diseñen un logo o que te hagan algo de "artwork" no dudes en ponerte conmigo, si el proposito de tu diseño es altruista, como software libre, una web personal o que se yo, lo haré encantado y sin pedir nada a cambio. Si lo necesitas para un negocio o una cosa comercial no dudaré en hacerte un presupuesto.

danigm's picture

El otro día hice un dibujo a mano, estaba aburrido de mi antiguo avatar y quería dibujar uno nuevo:



wq.jpg

Y dige: "voy a pasarlo a vectorial". Le saqué una foto, lo abrí con el inkscape y me puse a dibujar sobre él hasta que hice esto:



wq.png

Por cierto me he dado cuenta de que se me han olvidado las cejas :P

GECO's picture

Hoy voy a explicar cómo he hecho la ventanita emergente (o popup) con javascript y css que se puede ver en esta captura:



gecoweb5.png

Aunque pueda parecer algo complicado no es más que html. Son dos simples divs que se muestran u ocultan según convenga.

html

En nuestra página html debemos añadir un div con el contenido que queramos que se muestre dentro del popup:

  1. <div class="input">
  2. <img src="/static/images/error.png" class="close" alt="close"/>
  3. <div id="master">
  4. <label for="master">Master password:</label>
  5. <input id="masterpwd" name="master" type="password"/>
  6. <br/><button type="submit" id="rec" class="imaged"></button>
  7. </div>
  8. </div>

Esto es un simple div con la imagen del circulito con la X y un formulario dentro.

Y también habrá que añadir el div que hace que el fondo se ponga oscuro:

  1. <div id="overlay"></div>

hojas de estilo (css)

Ahora hay que darle un estilo para que aparezca centrado, que el fondo sea gris medio transparente, etc.

Este es el código css de geco que hace todas estas movidas:

  1. #overlay {
  2. display: none;
  3. position: fixed;
  4. left: 0%;
  5. top: 0%;
  6. width: 100%;
  7. height: 100%;
  8. z-index: 999;
  9. background-image: url('/static/images/overlay.gif');
  10. }
  11.  
  12. #master {
  13. clear: both;
  14. padding-bottom: 1em;
  15. }
  16.  
  17. .input {
  18. display: none;
  19. color: black;
  20. position: fixed;
  21. left: 25%;
  22. top: 50%;
  23. width: 50%;
  24. z-index: 1000;
  25. text-align: center;
  26. background-color: white;
  27. border: 1px solid black;
  28. }
  29.  
  30. .close {
  31. cursor:pointer;
  32. float: right;
  33. }

Lo más importante aquí es el display: none que hace que no aparezca por defecto (ya lo mostraremos con javascript) y los atributos de posición, position: fixed para que sea fijo en la pantalla y left y top que posicionan el div. También es importante el z-indez que posiciona una cosa encima de otra.

El efecto sombreado lo hago con una imágen gif. Pero gif no soporta medio-transparencias, con gif un pixel o es transparente o es opaco. Pues muy fácil, se hace un truqui que consiste en poner un pixel negro y otro transparente alternativamente creando el efecto deseado.

Aparecer/desaparecer (javascript)

Para que aparezca el popup cuando se pulsa sobre un enlace o un div, hay que usar javascript. Lo más fácil es usar jquery y así lo he hecho yo, creando el fichero gecojs.js que contiene lo siguiente:

  1. ...
  2.  
  3. $(document).ready(function() {
  4. $(".pwdname").click(function(){
  5. var pwd = $(this).next().html();
  6. $(".input").fadeIn(300);
  7. $("#overlay").fadeIn(300);
  8. });
  9. $(".close").click(function(){
  10. $(".input").fadeOut(300);
  11. $("#overlay").fadeOut(300);
  12. });
  13.  
  14. $("#rec").click(function(){
  15. mimasterpwd = $("#masterpwd").attr("value");
  16. $("#masterpwd").attr("value", "");
  17. $(".input").fadeOut(300);
  18. $("#overlay").fadeOut(300);
  19. setTimeout(olvidar, 10 * 60 * 1000);
  20. });
  21. });
  22. ...

Y aquí está la mágia de jquery, al pulsar sobre cualquier objeto de la clase pwdname, se lanza la función que muestra tanto el input (popup) como el overlay (fondo gris) con un efecto de aparición (fadein)

Luego si se pulsa en el botón de cerrar o en el botón recordar se oculta con un fadeOut.

Esto no tiene más historia y es un efecto visual bastante agradable.

Fácil, Fácil :P

GECO's picture

Hoy ha sido un día bastante productivo por lo que respecta al cliente web de GECO.

Lo primero que he hecho es implementar un sistema de captcha matematico para evitar que se registren bots. ¿Cómo? fácil, generando un par de números aleatorios entre 1 y 10 y validando que en el registro que la suma es correcta.



gecoweb3.png

Por otra parte ya he implementado la funcionalidad del listado de todas las contraseñas que gestionas desde GECO.



gecoweb4.png

Y haciendo uso de mis conocimientos en css, html y jquery he implementado un popup vistoso para preguntar la contraseña maestra para poder descifrar las contraseñas. Por supuesto esa contraseña nunca se va a mandar y tan solo se va a almacenar en el navegador durante un tiempo determinado.



gecoweb5.png

Y por último quería destacar una funcionalidad que le he implementado basandome en el sistema de templates y es que es posible pasar mensajes o errores de una página a otra a traves de unas variables de sesión.



gecoweb6.png

Nota: La palabra desautenticado me la he inventado.

GECO's picture

Teniendo ya implementado un servidor funcional con un frontend xmlrpc y un cliente funcional de terminal es hora de empezar la parte más importante del proyecto que es el cliente web.

Buscando entre el gran número de frameworks para desarrollo web en python me encontré casi sin querer con web.py que es un framework ultrasencillo que concuerda con mi filosofía de desarrollo, las cosas lo más simple posibles.

¿Cómo implementar el cliente web?

Basandonos en el cliente de terminal es casi tan simple como
eso. No tenemos ni que tratar con bases de datos, ni con modelos complejos, puesto que gecolib ofrece una serie de métodos que hacen todas las operaciones que tendrá que hacer este cliente. Por lo tanto tan solo tenemos que hacer la interfaz, pedir datos y mostrar datos.

De momento tengo desarrollado el login y el registro en la aplicación, quizás en el registro falte un captcha para evitar que se registren bots.


gecoweb1.png

El estilo ya lo tenía decidido de hace algún tiempo, algo simple, pero con alto contenido en colores fuertes, llamativo y a la vez elegante.

He utilizado imágenes para los botones, con un suave degradado, un alto contraste entre la fuente y el fondo y una ligera sombra difuminada. El svg se puede conseguir del repo, posiblemente la fuente te salga diferente porque no la tendrás, se llama "Orange".


gecoweb2.png

Web.py tiene un módulo simple que genera formularios con validación, y un sistema de templates con una sintaxis muy parecida a python, por lo que facilita en gran medida el desarrollo. Por otra parte este "framework" no requiere de gran tiempo de aprendizaje y no por ello se pueden hacer menos cosas, si dominas python, este es tu framework de desarrollo web.

El mayor problema al que me he tenido que enfrentar en esta etapa del desarrollo ha sido a la hora de almacenar el objecto gecolib.GecoClient en una sessión de webpy. Al ser un objeto que contiene una conexión xmlrpc no es posible almacenarlo, por lo que he optado por almacenar la "cookie" de geco y modificar el constructor para que acepte un parametro cookie y no sea necesario pasar por el método auth.

Mañana espero tener al menos la vista de las contraseñas de un usuario autenticado.

danigm's picture

Porque mercadear con la cultura y el arte, que son el fundamento, el sostén y la fuerza motriz del espíritu humano, equivale a mercadear con el propio espíritu humano y, por consiguiente, a convertir el género humano en una triste raza de esclavos.