25/7/13

JasperReport (Web de interes)


Descargar JasperReport, iReport y otros componentes...

iReport Web interesantes:
- Solución al problema de los parámetros dinámicos.


Java, jsp, xhtml (Web interesante)


JSP WEBs Interesantes
- Manual JSP
- Desarrollo de Aplicaciones Web con JSP y XML
- Crear sitios y aplicaciones web en JSP con Java

Python (Web interesante)

Python WEBs Interesantes

En el siguiente blog: http://codigosimportantes.blogspot.com.es podemos encontrar varios ejemplos codificados en python:
- Capturar foto con Python
- Enviar archivo por correo con Python
- Mostrar ventana con texto en pygame
- Grafico torta con mathplotlib + python
- ... algunos más ...


Aqui podéis encontrar una guia de Python Guia de Python bastante completa.

Información para la conexión a base de datos mendiante MySQL.

Otro blog bastante interesante es este http://ztux.blogspot.com.es/, en el podemos encontrar ejemplos codificados en python como estos:
- Agenda en Python usando MySQL v1.5
- Simular "Switch" en Python
- Generador de Passwords en C++ y Python 


De Scrapy podemos ver los ejemplos que hay en http://doc.scrapy.org/en/latest/intro/tutorial.html.

Conociendo JasperReport Ireport


JasperReport es una de las mejores herramientas de creación de informes complejos compatible con cualquier aplicación Java (incluyendo J2EE, apliaciones WEB...) y con la librería propia de Jasper Reports.

Está desarrollada 100% en Java y se distribuye bajo la licencia GNU General Public License.”

Se pueden obtener diseños en la pantalla, para la impresora o achivos con formato s PDF, HTML, RTF, XLS, CSV y XML. 

... en construccion ... 

24/7/13

Python - Código Descargar Imágenes


Buenas a todos, después de darle muchas vueltas a unos cuantos de programitas que encontre, he realizado este pequeño programa.

Nos pide una URL y el nombre del directorio a crear, donde descargara todas las imágenes de dicha URL.
 
'''
Created on 23/07/2013

@author: aaguilar
'''

import urllib
import urllib2
import re
import sys
import os
from os.path import basename
from urlparse import urlsplit
 

EXTENSIONS = ['.jpg','.png','.gif','.jpeg']

def download_images_from_url(url):

    fichero = raw_input("Ingrese nombre del fichero donde descargar las imagenes >")    
    #Almaceno el directorio actual para volver al terminar
    directorioOriginal = os.getcwd()
    #Creamos el nuevo directorio
    directorio = os.path.join(fichero)
    if not os.path.isdir(directorio):
        os.mkdir(directorio)
    os.chdir(directorio)
       
    if not url.lower().startswith('http://') and not url.lower().startswith('https://'):
        url = 'http://%s'%url
        print 'Descargando imagenes desde %s...'%url
        print
        urlContent = urllib2.urlopen(url).read()

        # Busqueda del tag img en la pagina web.
        # HTML image tag: <img src="url" alt="some_text"/>

        imgUrls = re.findall('img .*?src="(.*?)"', urlContent)
        print "+--------------------------------------+"
        print "+ Descarga de imagenes                 +"
        print "+--------------------------------------+"
        print "+                                      +"
        print "+ Web:",url,(" "*(31-len(url)))+"+"
        print "+ Cantidad de imagenes: ",len(imgUrls),(" "*(13-len(str(len(imgUrls)))))+"+"
        print "+                                      +"
        print "+--------------------------------------+"
        print
 

        #Recorremos todas las imagenes
        for i in range(len(imgUrls)):
            if not imgUrls[i].lower().startswith('http://') and not url.lower().startswith('https://'):
                imgUrls[i] = url+"/"+imgUrls[i]
             

            nombreImagen = imgUrls[i][imgUrls[i].rfind('/')+1:len(imgUrls[i])]
            #llamamos al método que la descarga        
            download(imgUrls[i],nombreImagen,directorio)
                       
    print "Imagenes descargadas correctamente en > " + os.getcwd()
    os.chdir(directorioOriginal) # vuelve al directorio inicial
   
                       
def download(url, NOMBRE,directorio):
    try:
        furl = urllib2.urlopen(url)
        f = file(NOMBRE,'wb')
        f.write(furl.read())
        f.close()
        print "Descarga completada -->",NOMBRE
        print
        print
    except:
        print 'Unable to download file'
 

#Comenzamos
try:

    if __name__ == '__main__':
        args = sys.argv
               
        if len(args) < 2:
            url = raw_input("Ingrese URL >")
            download_images_from_url(url)
            print
        else:
            download_images_from_url(args[1])
            print       
        exit(0)

       
except Exception, e:
    print e
finally:
    print "Operacion Finalizada."


Os presento ahora una modificación que he realizado en el código, para solucionar que hay web que si detectan que no es un navegador el que realiza la petición, no nos permite recorrerla. Por otro lado subsanamos el problema que puede darse cuando las imagenes no tienen extensión, lo solucionamos añadiendole una por defecto, además añadimos un tratamiento por si el nombre de la imagen es relativo y tiene caracteres especiales, le damos un nombre aleatorio a la imagen.

'''
Created on 26/07/2013

@author: aaguilar
'''

import urllib
import urllib2
import re
import sys
import os
import time
from os.path import basename
from urlparse import urlsplit

EXTENSIONS = ['.jpg','.png','.gif','.jpeg']

def download_images_from_url(url):
   
    print url
   
    fichero = raw_input("Ingrese nombre del fichero donde descargar las imagenes >")


    #Almaceno el directorio actual para volver al terminar
    directorioOriginal = os.getcwd()
    directorio = os.path.join(fichero)

    #Creamos el nuevo directorio    
    if not os.path.isdir(directorio):
        os.mkdir(directorio)
    os.chdir(directorio)
       
    if not url.lower().startswith('http://') and not url.lower().startswith('https://'):
        url = 'http://%s'%url
   
    print 'Descargando imagenes desde %s...'%url
    print url
    #urlContent = urllib2.urlopen(url).read()
   
   
    values = {'name' : 'Yo'}
    data = urllib.urlencode(values)
    headers = {'User-agent': 'Mozilla/5.0' }
    req = urllib2.Request(url, data, headers)
    response = urllib2.urlopen(req)
    urlContent = response.read()


   
# Busqueda del tag img en la pagina web.
    # HTML image tag: <img src="url" alt="some_text"/>
   

    imgUrls = re.findall('img .*?src="(.*?)"', urlContent)
    print "+--------------------------------------+"
    print "+ Descarga de imagenes                 +"
    print "+--------------------------------------+"
    print "+                                      +"
    print "+ Web:",url,(" "*(31-len(url)))+"+"
    print "+ Cantidad de imagenes: ",len(imgUrls),(" "*(13-len(str(len(imgUrls)))))+"+"
    print "+                                      +"
    print "+--------------------------------------+"
    print
       
    # download all images
    contador = 0

  #Recorremos todas las imagenes
     for i in range(len(imgUrls)):
        print imgUrls[i]
        if not imgUrls[i].lower().startswith('http://') and not url.lower().startswith('https://'):
            imgUrls[i] = "http:"+imgUrls[i]
       
        nombreImagen = imgUrls[i][imgUrls[i].rfind('/')+1:len(imgUrls[i])]
 

        #Tratamos imagenes cuyo nombre tienen caracteres especiales
        if ('>' in nombreImagen or '<' in nombreImagen or '|' in nombreImagen or ':' in nombreImagen or '*' in nombreImagen or '"' in nombreImagen or '/' in nombreImagen  or '?' in nombreImagen or
'\\' in nombreImagen):
            contador = contador +1
            nombreImagen = "imagen"+str(contador)+".jpg"

        #Tratamos imagenes que no indican el formato
        elif '.' not in nombreImagen:
            contador = contador +1
            nombreImagen = "nombreImagen"+".jpg"


        #llamamos al método que la descarga          
        download(imgUrls[i],nombreImagen,directorio)
                       
    print "Imagenes descargadas correctamente en > " + os.getcwd()
    os.chdir(directorioOriginal) # vuelve al directorio inicial
   
                       
def download(url, NOMBRE,directorio):
    try:
        furl = urllib2.urlopen(url)
        #f = file("%s.png"%NOMBRE,'wb')
        f = file(NOMBRE,'wb')
        f.write(furl.read())
        f.close()
        print "Descarga completada -->",NOMBRE
        print
        print
       
    except:
        print 'Unable to download file'

#Comenzamos
 try:
    if __name__ == '__main__':
        args = sys.argv
               
        if len(args) < 2:
            url = raw_input("Ingrese URL >")
            print time.asctime()
            download_images_from_url(url)
            print
        else:
            download_images_from_url(args[1])
            print
       
        exit(0)

except Exception, e:
    print e
finally:
    print "Operacion Finalizada."
    print time.asctime()
   
     
   
               
    


Mejorar consultas SQL

Antes de nada, debemos tener en cuenta a la hora de realizar una consulta:

- Evitar hacer joins innecesarios

- Al hacer select, es conveniente no usar "Select * from" , nos traeremos solo los campos que vams a necesitar, porque el gestor debe leer primero la estructura de la tabla antes de ejecutar la sentencia.

- Mucho cuidado con el order by, group by o between que consumen bastantes recursos.

- Las subconsultas suelen necesitar mucho tiempo de proceso.

- Las condiciones (tanto de filtro como de join) deben ir siempre en el orden en que esté definido el índice. Si no hubiese índice por las columnas utilizadas, se puede estudiar la posibilidad de añadirlo, ya que tener índices extra sólo penaliza los tiempos de inserción, actualización y borrado, pero no de consulta.

- Los filtros de las consultas deben ser lo más específicos y concretos posibles. Es decir: es mucho más específico poner WHERE campo = 'a' que WHERE campo LIKE '%a%'. Es muy recomendable utilizar siempre consultas que filtren por la clave primaria u otros campos indexados.

- Evitar la condiciones IN ( SELECT…) sustituyéndolas por joins: cuando se utiliza un conjunto de valores en la clausula IN, se traduce por una condición compuesta con el operador OR. Esto es lento, ya que por cada fila debe comprobar cada una de las condiciones simples. Suele ser mucho más rápido mantener una tabla con los valores que están dentro del IN, y hacer un join normal. Por ejemplo, esta consulta:
     
                                                                    SELECT *
                                                                      FROM datos
                                                                    WHERE campo IN ('a', 'b', 'c', 'd', ... , 'x', 'y', 'z');

Se puede sustituir por la siguiente consulta, siempre que la tabla "letras" contenga una fila por cada   valor contenido en el conjunto del IN:
                                                                    SELECT *                                                                              FROM datos d, letras l                              
                                                                     WHERE d.campo = l.letra;

También hay que tener cuidado cuando se mete un SELECT dentro del IN, ya que esa consulta puede retornar muchas filas, y se estaría cayendo en el mismo error. Normalmente, una condición del tipo "WHERE campo IN (SELECT...)" se puede sustituir por una consulta con join.

- Una condición negada con el operador NOT desactiva los índices

- Una consulta cualificada con la cláusula DISTINCT debe ser ordenada por el servidor aunque no se incluya la cláusula ORDER BY.

- Para comprobar si existen registros para cierta condición, no se debe hacer un SELECT COUNT(*) FROM X WHERE xxx, sino que se hace un SELECT DISTINCT 1 FROM X WHERE xxx. De este modo evitamos al servidor que cuente los registros. 

A la hora de diseñar una tabla:
  • Normalizar las tablas, al menos hasta la tercera forma normal, para asegurar que no hay duplicidad de datos y se aprovecha al máximo el almacenamiento en las tablas. Si hay que desnormalizar alguna tabla piensa en la ocupación y en el rendimiento antes de proceder.
  • Los primeros campos de cada tabla deben ser aquellos campos requeridos y dentro de los requeridos primero se definen los de longitud fija y después los de longitud variable.
  • Ajusta al máximo el tamaño de los campos para no desperdiciar espacio.
  • Es muy habitual dejar un campo de texto para observaciones en las tablas. Si este campo se va a utilizar con poca frecuencia o si se ha definido con gran tamaño, por si acaso, es mejor crear una nueva tabla que contenga la clave primaria de la primera y el campo para observaciones.

22/7/13

Python - MySQL

En esta entrada vamos a realizar operaciones con una base de datos de MySQl. y con un fichero de texto plano.

Vamos a comenzar realizando operaciones con MySQL, creaemos una tabla, insertaremos un par de registros, los recuperaremos y visualizaremos.

En mi caso he creado un base de datos con MySQL Workbench 5.2, la he denominado "deusto".

Para poder trabajar con MySQL tendremos que intalar MySQLdb de esta página (última versión), bastara con descargarlo e instalarlo por defecto en el directorio de Python donde hemos instalado Python.

Una vez instalado ya podremos utilizar MySQLdb:

'''
Created on 22/07/2013

@author: aaguilar
'''


# Importa librerias de MySQL
 import MySQLdb

# La función connect devuelve un objeto de tipo Connection en función de los parámetros que le informemos
bbdd = MySQLdb.connect(host="localhost", # your host, usually localhost
                       user="root", # your username
                       passwd="root", # your password
                       db="deusto") # name of the data base

 print bbdd
 

# Las distintas operaciones que podemos realizar con la base de datos se realizan a través de un objeto Cursor.
c = bbdd.cursor()
 

# creemos una nueva tabla empleados en la base de datos
c.execute("""create table empleados(dni text,
             nombre text,
             departamento text)""")
 

# insertemos un par de tuplas en nuestra nueva tabla
c.execute("""insert into empleados
             values ('123456789-A','Javier Carrasco','Contabilidad')""")

c.execute("""insert into empleados
              values ('123456710-B','Manuel Aguilar','Contabilidad')""")
 

# Realizamos un commit para que las tuplas insertadas sean almacenadas
bbdd.commit()
 

# Realizamos una consulta sobre la tabla que hemos creado
c.execute("""select * from empleados""")
 

# Recorremos las tuplas que recuperamos en la consulta
for resultado in c.fetchall():
    print resultado
 

# Cerramos la conexión y el cursor
c.close()
bbdd.close()



Ahora vamos a probar otro ejemplo para realizar pruebas mas sencillas, donde en lugar de trabajar con una base de datos MySQL, vamos a trabajar sobre un fichero de texto plano.

Ppara ello utilizaremos SQLite, es una base de datos Open Source minimalista. Se caracteriza por:
 - No tener ningún demono por detras, los datos se almacenan en un único fichero, 
 - Es realmente pequeña, no exige practicamente recursos, no tiene depedencias.
 - Funcionalidad muy limitada, en comparación con otras bases de datos.
 - Multiplataforma
 - Utilizada por aplicaciones de escritorio.

Veamos el ejemplo con SQLite:
'''
Created on 22/07/2013

@author: aaguilar
'''

# Importa librerias de SQLite
import sqlite3 as dbapi
print dbapi.apilevel
print dbapi.threadsafety
print dbapi.paramstyle


# La función connect devuelve un objeto de tipo Connection que representa la conexión con el servidor.
# Siendo deusto.dat el nombre del fichero
 bbdd = dbapi.Connection("deusto.dat")

 print bbdd
 

# Las distintas operaciones que podemos realizar con la base de datos se realizan a través de un objeto Cursor.
c = bbdd.cursor()
 

# creemos una nueva tabla empleados en la base de datos
c.execute("""create table empleados(dni text,
             nombre text,
             departamento text)""")
 

# insertemos un par de tuplas en nuestra nueva tabla
c.execute("""insert into empleados
             values ('123456789-A','Javier Carrasco','Contabilidad')""")

c.execute("""insert into empleados
              values ('123456710-B','Manuel Aguilar','Contabilidad')""")
 

# Realizamos un commit para que las tuplas insertadas sean almacenadas
bbdd.commit()
 

# Realizamos una consulta sobre la tabla que hemos creado
c.execute("""select * from empleados""")
 

# Recorremos las tuplas que recuperamos en la consulta
for resultado in c.fetchall():
    print resultado
 

# Cerramos la conexión y el cursor
c.close()
bbdd.close()




Un saludo a todos.