Archivo

Archivo del autor

Adiós SMS de 1€! hola Twitter!

Jueves, 22 de Abril de 2010

Desde eitb.com llevan años trabajando para la integración de las nuevas tecnologías y redes sociales en la programación de los canales del grupo, para intentar que sus contenidos sean más interactivos. Además coincide que he sido un firme opositor a los sistemas de SMS de pago en los programas de televisión ya que siempre he creído que eran una forma de estafa encubierta sobre todo en programas que tenían un publico claramente menor de edad.


Por tanto la idea de sustituir los mensajitos de marras por Tweets que se ha llevado acabo en el programa “El conquis” (programa de debate del reality “El conquistador del Fin del Mundo”) me llamo la atención desde el primer momento y me pareció una iniciativa digna de aplaudir y de dar a conocer de cara a que estas practicas sean mas populares en los medios de comunicación.

En el caso de este programa el sistema es muy sencillo: se define un hashtag (#conquis) y los usuarios pueden enviar comentarios a través de sus cuentas de Twitter añadiendo dicho hashtag en sus comentarios. Desde el programa se sigue el feed generado a partir del hashtag y se muestra en la parte inferior de la pantalla.



Simulación (no he conseguido una imagen real) de como se muestran los tweets en directo


Soy realista y no espero que programas como Salvame, La Noria o DEC renuncien a una (sino la principal) de las fuentes de ingresos de sus programas. Pero si creo que por lo menos las televisiones públicas no deben de participar de este tipo de estafas que son los SMS de pago y apostar por sistemas de participación más abiertos y accesibles.

Esperemos que estas iniciativas que se están llevando a cabo en diferentes medios de comunicación se popularicen en detrimento de otras practicas menos recomendables.

Iker Noticias , , , , ,

Android Application Widget

Martes, 6 de Abril de 2010

Plugin para WordPress que permite mostrar la información de tu propia aplicación o aplicación preferida para Android. Se conecta automáticamente a Android Market descargando de forma periódica la información sobre tu aplicación como: valoración de los usuarios, descargas, comentarios, versión,.. etc.

Además facilita la instalación de la aplicación por parte de los usuarios ya que al pulsar “Instalar” se muestra un código de barras que permite acceder a la aplicación en Android Market directamente.

La aplicación se conecta a Androd Market mediante una pequeña implementación de protocolo usado por Google para acceder al Market a través de los terminales Android. Esta implementación es aun muy simple y se ira mejorando en próximas versiones.

WordPress plugin for displaying the information of your own or preferred Android application. Widget automatically connects to Android Market downloading the information about your application like: rating, downloads, reviews, release, .. etc.

It also facilitates the installation of the application by users. Pressing “Install” shows a bar code that allows access to the Android Market application directly.

The application connects to Androd Market with a small implementation of the protocol used by Google to access the Market through the Android terminals. This implementation is still very simple and it will be improved in future releases.

Mas información/More info:

http://wordpress.org/extend/plugins/android-application-widget/

Iker Android, Noticias , , ,

Versión BETA de Eitb Irratia disponible en Android Market

Miércoles, 24 de Marzo de 2010

Install Eitb IrratiaYa esta disponible en Android Market la versión BETA de Eitb Irratia. Esta versión esta aun en desarrollo pero es completamente funcional. Existen bugs conocidos en los cuales estoy centrando los esfuerzos. Actualmente las líneas de trabajo principales son:

  • Eliminar el “gap” o lapso en la recarga del audio cada cierto tiempo
  • Implementar el sistema que permita obtener la información de la programación
  • Implementar un sistema de localización de la aplicación que permita seleccionar Euskera (Android aún no soporta Euskera)

Descarga la aplicación desde aquí o con un lector de código de barras.

Iker Noticias , , ,

Vodafone hace “magia” con el HTC Magic

Martes, 16 de Marzo de 2010

Si señores, parece que Vodafone ha decidido que conectar tu SIM a un HTC Magic es suficiente para darte de alta un servicio de tarifa plana de datos sin ningún tipo de firma de contrato ni consentimiento del usuario. Es decir, que si alguien te presta su HTC Magic por alguna razón (te has quedado sin batería, te lo ha prestado temporalmente porque se te ha roto el tuyo…) Vodafone es capaz de detectar que tu SIM esta conectada a un HTC Magic y da de alta automáticamente la tarifa plana de datos.

Todo empezó hace un mes cuando mi novia me presto su HTC Magic para hacer unas pruebas con unas aplicaciones que estaba desarrollando yo mismo. Como sabia que yo no tenía ninguna tarifa plana asociada, para que no me saliera la torta un pan, instale APNDroid para evitar que el terminal se conectara a Internet ya que para las pruebas usaría la red WIFI local mía. La verdad es que no me podía quejar, las pruebas iban bien y el terminal, aunque quizá un poco justo de recursos funcionaba correctamente con mis aplicaciones.

Tengo la mala costumbre de no leer las facturas, pero ayer me llego una factura de Vodafone y se me ocurrió mirar los importes. En la factura aparecía un importe de 24€ en la sección otros servicios, por lo que llamé a Vodafone para informarme. Tras hablar con un agente me comenta que tengo mi SIM conectada a un HTC Magic y que ese teléfono tiene asociada una Tarifa plana de datos. Le digo que el terminal no es mío, que lo tengo prestado y que la tarifa plana la tendrá el dueño del terminal que fue quien firmo el contrato de adquisición del terminal. Me dice que eso es igual, el terminal parece ser tiene un efecto “Vírico” (no se conforman con distribuir mariposas y confickers) y a cada SIM que se conecta al terminal se le da de alta la tarifa plana de datos. Ante mi asombro, le pregunto como es posible que insertar una SIM en un teléfono me comprometa a un servicio sin que haya ninguna intervención mía o contrato de por medio. El agente me comenta que eso es así y que no hay mas vueltas que darle, por tanto, le solicito que me remitan una carta o documento en el que se me confirme que la respuesta oficial de Vodafone es esa, a fin de presentarlo como prueba donde fuera necesario. El agente me confirma que Vodafone no remite ningún tipo de documento, por lo que paso a preguntarle su nombre completo. El agente solo me facilita su nombre de pila y cuando la insisto en solicitarle su apellido la llamada se cuelga inesperadamente.

Aun así no entiendo porque me aparece 24€ si la tarifa son 15€, e intentando acceder a el servicio Mi Vodafone para comprobar las facturas, veo que la pagina esta inaccesible. Por tanto vuelvo a llamar a Vodafone para solicitar más información y dar de baja el servicio. El agente me comunica que el servicio de gestión interna esta caído y que deja un aviso para que en cuanto este disponible se me de de baja el servicio. Como no es posible acceder a mis facturas, el agente no es capaz de darme la información sobre la facturación en ese momento. Le pregunto si es cierto que si vuelvo a conectar mi SIM al terminal se me volverá a dar de alta la tarifa de datos y el me confirma que “en principio si”.

Al de una hora recibo un mensaje en el que se me confirma la baja del servicio de datos. Pero hoy estoy con unas facturas en las que se me ha cobrado unos servicios que no uso y la duda de que pasara si vuelvo a conectar mi SIM o de otra persona a este terminal.

Esta mañana iré a la oficina del consumidor a informarme con lo que actualizare este post con mas información a lo largo de la mañana.

Actualización [16/03/2010 14:00]:

He llamado de nuevo a Vodafone y no se si el articulo habrá tenido efecto o ha sido que ayer les pille en una hora mala, pero la chica que me ha atendido muy amablemente me ha pasado a anular la tarifa y a abonarme la diferencia. En cuanto a los 24€ me han confirmado lo que alguien ya había dicho en algún post de menéame: son lo 15€ + 9€ de consumo mínimo que luego se descuentan.

Por ultimo estaría bien que Vodafone aclarara cual es su política o que redefiniera su protocolo de actuación en estos casos. Sí entiendo que ante los problemas que podrían surgir de facturas astronómicas, esta sea la mejor solución para ellos, pero no es la mejor solución para todos sus clientes. Desde el que no sabe ni que tiene un Android hasta el que hace ingeniería inversa.

Iker Noticias , , , , ,

Usar/Crear Filtros para las plantillas de django/Google App Engine

Jueves, 11 de Marzo de 2010

Una de los temas mas interesante en Google App Engine es la posibilidad de usar plantillas. En la página de GAE existen ejemplos sencillos de cómo utilizar plantillas.El problema empieza cuando dentro de esas plantillas quieres hacer tratamiento de los datos para mostrar los datos correctamente. En esta articulo intentaremos explicar como usar esos filtros y como crear propios.

Como habéis podido ver en el ejemplo de la pagina de GAE, la forma de mostrar un valor en la plantilla es usando la sintaxis {{ variable }}. En la mayoría de los casos dichas variables serán de tipo string o integer por lo que su visualización no tendrá mayor problema. Pero por ejemplo en el caso de variables tipo datetime u otro tipo de objeto propio, el sistema de plantillas no es capaz de mostrar el contenido de dichas variables, ya que solo es capaz de mostrar valores tipo string o integer.

Para los tipos de datos mas comunes existen ya filtros por defecto como es el caso de los valores datetime. La forma de aplicar un filtro es la siguiente:

{{variable|filtro}}

Y en algunos casos:

{{variable|filtro:argumento}}

En el caso de los valores datetime que hemos comentado antes, para mostrar un valor de fecha deberemos usar el filtro date de la siguiente manera:

{{mydatevar|date:"j"}}

Esto seria equivalente a ejecutar una función date(mydatevar,”j”) y lo que estoy haciendo es mostrar el día del mes (código %j) similar a como se hace en otros lenguajes de programación.

Aquí podéis encontrar un listado con los principales filtros predeterminados en django

El problema es cuando estas funciones no son suficientes para hacer lo que nosotros queremos, o queremos tratar tipos de objetos poco comunes o propios.

Por ejemplo imaginemos que queremos tenemos un libro de visitas donde los usuarios puede escribir entradas, e indican su dirección de correo. Pero no queremos que esa dirección de correo sea visible para que no pueda ser rastreada por spammers, por lo que optamos por mostrar solo los 5 primeros caracteres de el nombre de usuario de la cuenta de correo mas tres puntos suspensivos (algo parecido a lo que se hace en las listas de distribución). Es decir para estoesunaprueba@gmail.com nos generara una dirección del tipo estoe…@gmail.com.

Por tanto nuestra función en python seria algo así como:

def securemail (mail):
        return mail.split(‘@’)[0][:5]+”…@”+ mail.split(‘@’)[1]

Es decir, dividimos la dirección en usuario y dominio con la función split y el carácter @, y generamos una nueva dirección con los primeros 5 caracteres de el usuario mas tres puntos suspensivos la arroba y el dominio.

Para poder usar esta función en nuestras plantillas haremos lo siguiente. Crearemos un script customfilters.py donde guardaremos todas nuestros filtros. Dicho script tendrá la siguiente forma

from google.appengine.ext import webapp
from datetime import datetime
 
register = webapp.template.create_template_register()
 
def securemail (mail):
        return mail.split(‘@’)[0][:5]+”…@”+ mail.split(‘@’)[1]
               
register.filter(securemail)

Para importar los filtros en nuestra aplicación añadiremos la siguiente sentencia justo después de los imports.

webapp.template.register_template_library(‘customfilters’)

De esta forma podremos usar nuestro filtro de la siguiente manera:

{{mail|securemail}}

Imaginemos que damos la opción al usuario que la función securemail muestre su cuenta de dos modos, uno, el por defecto que es el funcionamiento explicado anteriormente, y otro, que hace que solo se muestre el usuario sin el dominio. Por tanto deberemos definir un parámetro en la función para poder elegir el tipo de ofuscación. La función en este caso nos quedaría así:

def securemail (mail,default=true):
        if default:
                return mail.split(‘@’)[0][:5]+”…@”+ mail.split(‘@’)[1]
        else:
                return mail.split(‘@’)[0]

Por tanto si la variable mail tomara el valor estoesunaprueba@gmail.com este seria el resultado para las diferentes expresiones:

{{mail|securemail}} #estoe…@gmail.com
{{mail|securemail:true}} #estoe…@gmail.com
{{mail|securemail:false}} #estoesunaprueba

De esta forma podemos controlar y procesar la información a mostrar en nuestra plantilla cuando esta se trata de un objeto no string (o integer).

Iker Google App Engine, Tecnologia , , , , , , , ,

Consulta tu PageRank de Google con Python

Viernes, 5 de Marzo de 2010

A todos los que os interese el SEO seguramente habréis consultado alguna vez el PageRank de vuestra pagina. La forma mas sencilla de obtenerlo es instalando la ToolBar de Google en vuestro navegador. Pero seguramente si queréis realizar un seguimiento de vuestra pagina a lo largo del tiempo necesitareis automatizar un proceso que consulte el PageRank. La API de acceso al PageRank de google no es abierta, pero googleando un poco (o con Wireshark) es posible obtener el modo de consultar este dato. Parece que Google no le interesa que consultemos este dato, por lo que modifica la API bastante a menudo. En este artículo, te muestro una implementación en Python de un cliente para consultar el PageRank de una pagina, usando la API mas actual.

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# GPL (C) 2010 Iker Perez de Albeniz
# ported in Python from the Php code by HM2K (http://www.hm2k.com/projects/pagerank)
# http://www.ikeralbeniz.net/2010/03/05/contulta-tu-pagerank-de-google-con-python/

import sys
import urllib
 
from urllib import urlencode
from pprint import pprint

def strToNum(Str, Check, Magic):
        Int32Unit = 4294967296
        length = len(Str);
        for i in range(0,length):
            Check *= Magic;
            if (Check >= Int32Unit):
                Check = (Check – Int32Unit * int(Check/Int32Unit))
                if Check < -2147483648:
                    Check = Check + Int32Unit
                   
            Check += ord(Str[i])
        return Check
   
def hashURL(string):
        check1 = strToNum(string, 0×1505, 0×21)
        check2 = strToNum(string, 0, 0×1003F)
 
        check1 >>= 2
        check1 = ((check1 >> 4) & 0×3FFFFC0 ) | (check1 & 0×3F)
        check1 = ((check1 >> 4) & 0×3FFC00 ) | (check1 & 0×3FF)
        check1 = ((check1 >> 4) & 0×3C000 ) | (check1 & 0×3FFF)
 
        T1 = ((((check1 & 0×3C0) << 4) | (check1 & 0×3C)) <<2 ) | (check2 & 0xF0F )
        T2 = ((((check1 & 0xFFFFC000) << 4) | (check1 & 0×3C00)) << 0xA) | (check2 & 0xF0F0000 )
 
        return (T1 | T2);
   
def checkHash(hashnum):
        checkByte = 0;
        flag = 0;
 
        HashStr = ‘%s’ % hashnum
        length = len(HashStr)
 
        for i in range(0,length):
            Re = int(HashStr[(length – 1)-i])
            if (1 == (flag % 2)):
                Re += Re
                Re = int((Re / 10) + (Re % 10))

            checkByte += int(Re)
            flag = flag + 1

        checkByte %= 10
        if (0 != checkByte):
            checkByte = 10 – checkByte
            if (1 == (flag % 2) ):
                if (1 == (checkByte % 2)):
                    checkByte += 9
               
                checkByte >>= 1
        return ‘7%s%s’ %(checkByte,HashStr)

def getCh(url):
    return checkHash(hashURL(url))

def main():
   
    response = "Error: No URL defined.\nUsage: googrng.py <url> [[proxyuser:proxypass@]proxyhost:poxyport]"
    if len(sys.argv) > 1:
        myurl = sys.argv[1]
        url = "http://toolbarqueries.google.es/search?features=Rank&sourceid=navclient-ff&client=navclient-auto-ff&googleip=O;208.117.235.17;97&iqrn=8VdB&querytime=4P&orig=0X557&swwk=-1&ch=%s&q=info:%s" %(getCh(myurl),urllib.quote_plus(myurl))
        if len(sys.argv) > 2:
                proxies = {‘http’: ‘http://’+sys.argv[1]}
                f = urllib.urlopen(url, proxies=proxies)
        else:
                f = urllib.urlopen(url)
        response = f.read()
        f.close()
    print response

if __name__ == "__main__":
    main()

Iker Noticias , ,

Primeros pasos con Buzz (segunda parte): Un widget de Buzz para Wordpress

Jueves, 11 de Febrero de 2010

En el articulo anterior analizábamos la API de acceso a Buzz. Una vez analizada ya podemos ver como integrar Buzz en nuestra pagina. Para eso vamos a utilizar la API de Google para leer feeds y un script propio que lo que hará es mostrarnos el código HTML de los comentarios en in iframe refrescándolo cada 1 segundo. De este modo es posible crear un widget de Buzz para nuestro wordpress.

Antes de nada hay que tener en cuenta dos aspectos importantes:

  • Al estar usando librerías Ajax de Google es necesario que solicites una clave API propia:
    <script type=”text/javascript” src=”http://www.google.com/jsapi?key=ABQIAAAAMGph6fpNzf-ET0oBGVVHJxRpfcICevY5tQgqnPHEJCivekQnPxSD1FOWXFY6-VJtM6TmsT-tOJc9mg“></script>
  • En el lector de RSS debes indicar el RSS de tu cuanta de Buzz en el articulo anterior te explicamos como obtenerla.

    var feed = new google.feeds.Feed(“http://buzz.googleapis.com/feeds/111738004311961586383/public/posted”);

sample.html

<html>
        <head>
                <script type="text/javascript" src="http://www.google.com/jsapi?key=ABQIAAAAMGph6fpNzf-ET0oBGVVHJxRpfcICevY5tQgqnPHEJCivekQnPxSD1FOWXFY6-VJtM6TmsT-tOJc9mg"></script>
                <script type="text/javascript" src="buzz.js"></script>
        </head>
        <body>
                <div id="buzz" style="width:300px;background-color:#e1f3fa;">
                        <h1 style="font:20px Verdana;Color:#2193c5;margin:7px;">Iker.perez</h1>
                        <hr style="border: 1px dotted #CCCCCC;margin:5px 7px 0px 7px;">
                        <iframe id="buzz_msg_box" style="margin:0px 7px 0px 7px;border:0px; width:286px; height:450px;background-color:#ffffff;"></iframe>
                        <hr style="border: 1px dotted #CCCCCC;margin:0px 7px 0px 7px;">
                        <img src="buz.png" style="margin: 7px" width="100px">
                </div>
        </body>
</html>

buzz.js

google.load("feeds", "1");
var Editor;
window.onload = function()
{
Editor = document.getElementById(‘buzz_msg_box’).contentWindow.document;
Editor.designMode = "on";

}

function initialize() {
var feed = new google.feeds.Feed("http://buzz.googleapis.com/feeds/111738004311961586383/public/posted");
feed.setNumEntries(20);
feed.load(function(result) {
if (!result.error) {
var alltest = "";
var simplepost = "";
for (var i = 0; i < result.feed.entries.length; i++) {
simplepost = "";
var entry = result.feed.entries[i];

simplepost +’                <div id="message" style="font: 12px Verdana;"><b>+entry.publishedDate.split(" -")[0]+:</b><br/>+entry.content+</div>\r\n’;
simplepost = simplepost +<hr style="border: 1px dotted #CCCCCC;"/>\r\n’;
//entry.title+"<br>"+;
alltest = alltest + simplepost ;

}
Editor.body.innerHTML = alltest;
}
});
}

function reloadComments() {
google.setOnLoadCallback(initialize);
setTimeout(‘reloadComments(),1000);
}

reloadComments();


Ikalbeniz



Iker Noticias , , , , , ,

Primeros pasos con Buzz

Jueves, 11 de Febrero de 2010

Ha llegado Buzz y a primera vista lo que parece es un Twitter avanzado o un Facebook simplificado, como se vea. Pero mas allá de esta primera aproximación, me interesaba concer que funcionalidades se escondian tras esta nueva funcionalidad de Google. Por tanto el mejor sitio para empezar a buscar es el propio Google y su portal de APIs.

http://code.google.com/intl/es-ES/apis/buzz/

Actualmente solo existen dos opciones de integración disponibles:

  • De Buzz a tu Web
  • De tu Web a Buzz

De Buzz a tu Web

Buzz permite generar un RSS con tus comentarios en Buzz con lo que es posible generar plugins al estilo Twitter para tu blog. La forma de acceder a dicho RSS es la siguiente:

http://buzz.googleapis.com/feeds/{user_id}/public/posted

El user id es posible obtenerlo dirigiéndote a “Perfil de Google”..

En mis caso la dirección de mi perfil es la:

http://www.google.com/profiles/111738004311961586383

Por lo que mi user_id es 111738004311961586383 y mi url de RSS

http://buzz.googleapis.com/feeds/111738004311961586383/public/posted

De tu Web a Buzz

Buzz automáticamente permite que se integren en Buzz tus aplicaciones de Google, es decir, se generará un comentario cada vez que añadas una imagen a Picasa o subas un video a Youtube..

Si quieres que se genere un comentario cada vez que añades una entrada a tu blog debes conectar tu blog y Buzz bidireccionalmente:

Por un lado debes añadir una etiqueta en la cabecera de tu pagina de la siguiente manera:

<link rel=”me” type=”text/html” href=”{user_id}”/>

En mi caso será de la siguiente manera

<link rel=”me” type=”text/html” href=”http://www.google.com/profiles/111738004311961586383″/>

Además debes añadir tu Web como Web de confianza,  para ello dirígete a tu perfil de Google:

http://www.google.com/profiles/me/editprofile

y en la sección Enlaces añade un enlace a tu Web

Una vez terminado este proceso cada entrada nueva será comentada en tu Buzz.

Listo!

segunda parte »

Iker Tecnologia , , , , ,

Sencillo Mirror de imágenes para tu Blog usando Google App Engine

Lunes, 25 de Enero de 2010

Muchos de los Hostings que usamos para albergar nuestras webs tienen una limitación de ancho de banda mensual. Por tanto es bastante interesante disponer de un sistema de almacenamiento de imágenes que nos permita disponer de dichos archivos sin consumir ancho de banda de nuestro posting. En este artículo voy a explicar como realizar una pequeña aplicación para tener nuestro mirror de imágenes.

En este articulo no voy a dar por echo que el lector conoce y se maneja en el entorno Google App Engine por tanto me centrare en explicar el código utilizado.

main.py

import cgi
import os
from google.appengine.api import users
from google.appengine.ext import webapp
from google.appengine.ext.webapp.util import run_wsgi_app
import google.appengine.ext.webapp.util
from google.appengine.ext import db
from google.appengine.ext.webapp import template

class Mirror(db.Model):
 name = db.TextProperty()
 mime = db.TextProperty()
 picture = db.BlobProperty(default=None)

class GetImage(webapp.RequestHandler):
 def get(self,name):
  image = getImageFile(name)
  if (movie and movie.picture):
   self.response.headers['Content-Type'] = image.mime
   self.response.out.write(image.picture)
  else:
   self.response.out.write(“<!DOCTYPE HTML PUBLIC \”-//IETF//DTD HTML 2.0//EN\”>\r\n”)
   self.response.out.write(“<html>\r\n\t<head>\r\n”)
   self.response.out.write(“\t\t<title>404 Not Found</title>\r\n”)
   self.response.out.write(“\t</head>\r\n\t<body>\r\n”)
   self.response.out.write(“\t\t<h1>Not Found</h1>\r\n”)
   self.response.out.write(“\t\t<p>The requested URL /%s was not found on this server.</p>\r\n”%name)
   self.response.out.write(“\t</body>\r\n</html>\r\n”)

def getImageFile(name):
 images = Mirror.all()
 for image in images:
  if image.name == name:
   return image
 return None

class MainHandler(webapp.RequestHandler):

 def get(self):
  images = Mirror.all()
  template_values = {
   ’error’: “”,
   ’images’: images,
  }
  path = os.path.join(os.path.dirname(__file__), ‘form.html’)
  self.response.out.write(template.render(path, template_values))

 def post(self):
  newimage = Mirror()
  imagedata = self.request.get(“image”)
  newimage.picture = db.Blob(imagedata)
  newimage.name = self.request.POST[u'image'].filename
  newimage.mime = self.request.POST[u'image'].type
  newimage.put()
  self.redirect(“/”)

def main():
 application = webapp.WSGIApplication([('/', MainHandler),(r'/(.*)', GetImage)],debug=True)
 run_wsgi_app(application)

if __name__ == ‘__main__’:
 main()

Comos sabéis la aplicación que subimos a los servidores de Google corren en una SandBox donde no es posible escribir en disco, por tanto usaremos el sistema de almacenamiento de GAE para almacenar las imágenes. Por tanto primero de todo deberemos definir un modelo de datos.

class Mirror(db.Model):
 name = db.TextProperty()
 mime = db.TextProperty()
 picture = db.BlobProperty(default=None)

En este caso definimos la estructura Mirror con sus propiedades name (nombre de la imagen), mime (mime de la imagen) y picture (la imagen en bruto).

Comos sabéis el sistema de paths de GAE es gestionado a través de SGIApplication por tanto para poder acceder a las imágenes almacenadas deberemos definir una política de paths. En este caso he definido la siguiente:

application = webapp.WSGIApplication([('/', MainHandler),(r'/(.*)', GetImage)],debug=True)
run_wsgi_app(application)

Es decir en caso de acceder a / se nos mostrara la pagina principal a través de la clase MainHandler y en caso de que se nos muestre / se nos mostrara el archivos a través de la classe GetImage.

La Clase MainHandler

class MainHandler(webapp.RequestHandler):

def get(self):
 images = Mirror.all()
 template_values = {
  ’error’: “”,
  ’images’: images,
 }
 path = os.path.join(os.path.dirname(__file__), ‘form.html’)
 self.response.out.write(template.render(path, template_values))

def post(self):
 newimage = Mirror()
 imagedata = self.request.get(“image”)
 newimage.picture = db.Blob(imagedata)
 newimage.name = self.request.POST[u'image'].filename
 newimage.mime = self.request.POST[u'image'].type
 newimage.put()
 self.redirect(“/”)

La clase MainHandler en caso de se accedida mediante GET mostrara el formulario HTML (form.html) y un listado de imágenes almacenadas, para hacer mas legible el código he optado por usar la funcionalidad de platillas que ofrece GAE.

El formulario envía su mismo path la imagen utilizando el método POST por tanto en el tetrodo POST de la clase MainHandler donde se almacenara la imagen enviada.

La Clase GetImage

class GetImage(webapp.RequestHandler):
 def get(self,name):
 image = getImageFile(name)
 if (movie and movie.picture):
  self.response.headers['Content-Type'] = image.mime
  self.response.out.write(image.picture)
 else:
  self.response.out.write(“<!DOCTYPE HTML PUBLIC \”-//IETF//DTD HTML 2.0//EN\”>\r\n”)
  self.response.out.write(“<html>\r\n\t<head>\r\n”)
  self.response.out.write(“\t\t<title>404 Not Found</title>\r\n”)
  self.response.out.write(“\t</head>\r\n\t<body>\r\n”)
  self.response.out.write(“\t\t<h1>Not Found</h1>\r\n”)
  self.response.out.write(“\t\t<p>The requested URL /%s was not found on this server.</p>\r\n”%name)
  self.response.out.write(“\t</body>\r\n</html>\r\n”)

La clase getImage recoge en el parámetro nombre de la función get el resultado de la expresión regular definida en el path r’(.*)’. Por tanto en este caso name será el nombre del archivo. Mediante la función getImageFile recorremos la base de datos y buscamos el archivo solicitado.

def getImageFile(name):
 images = Mirror.all()
 for image in images:
  if image.name == name:
   return image
 return None

Si existe el archivo este es mostrado modificando la cabecera Content-Type con el mime del archivo para que el navegador lo muestre correctamente. En caso contrario se muestra un mensaje de error.

form.html

<!DOCTYPE HTML PUBLIC “-//IETF//DTD HTML 2.0//EN”>
<html>
<head>
<title>Upload File</title>
</head>
<body>
<h1>Select File to Upload</h1>
<form action=”" method=”POST” enctype=”multipart/form-data” >
<input name=”image” type=”file” size=”42″ />
<input type=”submit” value=”Upload”>
</form>
<H1>Index of Files</H1>
<PRE>
<IMG SRC=”/blank.gif” ALT=”     “> <A HREF=”?N=D”>Name</A>
<HR>
{% for image in images %}
<IMG SRC=”/image2.gif” ALT=”[IMG]“> <A HREF=”/{{image.name}}”>{{image.name}}</A>
{% endfor %}
</PRE>
<HR>
</body>
</html>

Se trata de un ejemplo sencillo, no hay validación de imágenes duplicadas. Además seria posible enviar un código de control a través de la petición POST para evitar que nos suban imágenes de terceros o incluso usar el sistema de loging de Google.

Iker Tecnologia , , , , , , , , , , ,

Manifiesto “En defensa de los derechos fundamentales en internet”

Miércoles, 2 de Diciembre de 2009

Ante la inclusión en el Anteproyecto de Ley de Economía sostenible de modificaciones legislativas que afectan al libre ejercicio de las libertades de expresión, información y el derecho de acceso a la cultura a través de Internet, los periodistas, bloggers, usuarios, profesionales y creadores de Internet manifestamos nuestra firme oposición al proyecto, y declaramos que:

  1. Los derechos de autor no pueden situarse por encima de los derechos fundamentales de los ciudadanos, como el derecho a la privacidad, a la seguridad, a la presunción de inocencia, a la tutela judicial efectiva y a la libertad de expresión.
  2. La suspensión de derechos fundamentales es y debe seguir siendo competencia exclusiva del poder judicial. Ni un cierre sin sentencia. Este anteproyecto, en contra de lo establecido en el artículo 20.5 de la Constitución, pone en manos de un órgano no judicial -un organismo dependiente del ministerio de Cultura-, la potestad de impedir a los ciudadanos españoles el acceso a cualquier página web.
  3. La nueva legislación creará inseguridad jurídica en todo el sector tecnológico español, perjudicando uno de los pocos campos de desarrollo y futuro de nuestra economía, entorpeciendo la creación de empresas, introduciendo trabas a la libre competencia y ralentizando su proyección internacional.
  4. La nueva legislación propuesta amenaza a los nuevos creadores y entorpece la creación cultural. Con Internet y los sucesivos avances tecnológicos se ha democratizado extraordinariamente la creación y emisión de contenidos de todo tipo, que ya no provienen prevalentemente de las industrias culturales tradicionales, sino de multitud de fuentes diferentes.
  5. Los autores, como todos los trabajadores, tienen derecho a vivir de su trabajo con nuevas ideas creativas, modelos de negocio y actividades asociadas a sus creaciones. Intentar sostener con cambios legislativos a una industria obsoleta que no sabe adaptarse a este nuevo entorno no es ni justo ni realista. Si su modelo de negocio se basaba en el control de las copias de las obras y en Internet no es posible sin vulnerar derechos fundamentales, deberían buscar otro modelo.
  6. Consideramos que las industrias culturales necesitan para sobrevivir alternativas modernas, eficaces, creíbles y asequibles y que se adecuen a los nuevos usos sociales, en lugar de limitaciones tan desproporcionadas como ineficaces para el fin que dicen perseguir.
  7. Internet debe funcionar de forma libre y sin interferencias políticas auspiciadas por sectores que pretenden perpetuar obsoletos modelos de negocio e imposibilitar que el saber humano siga siendo libre.
  8. Exigimos que el Gobierno garantice por ley la neutralidad de la Red en España, ante cualquier presión que pueda producirse, como marco para el desarrollo de una economía sostenible y realista de cara al futuro.
  9. Proponemos una verdadera reforma del derecho de propiedad intelectual orientada a su fin: devolver a la sociedad el conocimiento, promover el dominio público y limitar los abusos de las entidades gestoras.
  10. En democracia las leyes y sus modificaciones deben aprobarse tras el oportuno debate público y habiendo consultado previamente a todas las partes implicadas. No es de recibo que se realicen cambios legislativos que afectan a derechos fundamentales en una ley no orgánica y que versa sobre otra materia.

Iker Noticias , , , , , ,