Los Usuarios (Parte I)

Empezamos nueva categoría en el blog dedicada a nuestros queridos usuarios :)

Estaba tranquilo en la oficina viendo un video en YouTube sobre las muertes en Star Wars (Algo así como 2.005.000 millones de muertes) y llegó una usuaria con un papel en la mano.

Dentro de mis funciones, es mi deber minar la BD en busca de personas con enfermedades raras. Obviamente, cuando llegó la usuaria con el papel en mano automáticamente asumí que me iba a pedir los datos de X persona… la primera con ebola en la ciudad de Iquique.

Pero no. En el papel tenía nada más que un link a youtube:

-”Mario, cómo puedo tener este video en mi carpeta?”
-”Mmm crea un link a la página, o lo descarga directo desde YouTube”
-”Ya, quiero eso. Cómo lo descargo?”
-(Yo, con cara de: “para qué me pregunta si me va a pedir a mi que lo haga”) “Mándeme ese mismo enlace por correo y yo lo descargo”
-”Ah, pero no se cómo mandarlo…”
-”De la misma manera en que lo copió para imprimirlo en ésta hoja… y me lo manda por correo”
-”Ya ! Ok, te lo mando ahora”

Y como podrán estar pensando … lo que llegó por correo fue un word adjunto con el link del video dentro …

Captura de pantalla 2014-10-27 a las 9.00.59

Publicado en Usuarios | Deja un comentario

En busca de un cochino sonido en un cochino juego en un cochino programa en un cochino celular

La cosa es así: Escuché el sonido de un pollito, como esos de goma, que me quedó gustando. Quise que me lo mandaran para ponerlo como tono cuando llegara una notificación al celular (WP 8.1 … ahora se puede ;) 8) ). La cosa es que el sonido venía de un juego … no de algo que se pueda enviar fácil y bonito.

Buscando el juego (Mr. Flap) en google encontré su .APK y la descargué.

Los que han desarrollado para android más o menos saben lo que sigue… para el resto, seguir los pasos ;)

  1. Descargar el APK y cambiar la extensión a .zip
  2. Al descomprimir tenemos distintas carpetas, la que nos importa es res o resources.
  3. En mi caso, el sonido se encontraba aquí Captura de pantalla 2014-05-02 a la(s) 11.46.10
  4. Lo siguiente es enviarlo al equipo (En mi caso un Lumia 920) usando el software de Windows:
    1. Únicamente se pueden usar .mp3 o .wma … por lo que, el .wav no me sirve… Lo convierto online aquí.
    2. Lo abro con iTunes, click derecho y obtener información. Al fondo, le agrego el género de ringtoneCaptura de pantalla 2014-05-02 a la(s) 11.59.07
    3. Ahora, el programa me lo reconoce y lo puedo enviar al equipo ;) Captura de pantalla 2014-05-02 a la(s) 12.00.53
  5. Con el archivo en el teléfono, vamos a las configuraciones y luego “Ringtones y Sonidos”:
    1. Bajamos hasta el final y nos lleva a los sonidos por aplicación: wp_ss_20140502_0003
    2. Siguiente, abrimos la aplicación a la que vamos a asignar el sonido: wp_ss_20140502_0001
    3. Por último, buscamos el sonido :D wp_ss_20140502_0002
  6. Y eso fue todo :D Simple para los que hacemos esto… pero un poco más complicado para la gente común y silvestre.

Espero les sirva ;)

Publicado en Tutoriales, Windows Phone | Etiquetado , , | 1 comentario

Flask y CouchDB, Guardando Información (III)

Que siga la conga !

Hoy vamos a tomar datos desde un formulario y guardarlos en CouchDB (En mi caso usando Cloudant)

Entonces, tenemos un formulario así:

<form class="form-horizontal" method="post" action="/Admin/Nuevo/Ramo">
    <fieldset>
        <legend>Nuevo Ramo</legend>
        <div class="form-group">
            <label class="col-md-4 control-label" for="txt_nombre_ramo">Nombre Ramo</label>
            <div class="col-md-5">
                <input id="txt_nombre_ramo" name="txt_nombre_ramo" type="text" placeholder="Ej: Inglés I" class="form-control input-md" required>
            </div>
        </div>
        <div class="form-group">
            <label class="col-md-4 control-label" for="txt_pass_ramo">Contraseña</label>
            <div class="col-md-6">
                <input id="txt_pass_ramo" name="txt_pass_ramo" type="password" class="form-control input-md">
            </div>
        </div>
        <div class="form-group">
            <div class="col-md-4">
                <button id="btn_guardar" name="btn_guardar" class="btn btn-primary">Guardar</button>
            </div>
        </div>
    </fieldset>
</form> 

Como ven, el formulario apunta a: /Admin/Nuevo/Ramo , y la ruta definida es así:

@app.route('/Admin/Nuevo/<Item>', methods=['POST'])
def AdminNuevo(Item):
    from flask import request
    if(Item == 'Ramo'):
        nombre, passw = request.form['txt_nombre_ramo'], request.form['txt_pass_ramo']
        from Auxiliares.validador import Validador
        respuesta = Validador.IngresoRamo(nombre, passw)
        if(respuesta):
            from DAO.ramoDAO import RamoDAO
            rdao = RamoDAO()
            rdao._Guardar(respuesta)
        else:
            return "Campos no pueden quedar vacíos"

Lo nuevo aquí es que, para recibir parámetros enviados desde el formulario, necesitamos usar request. Las variables las obtenemos como: request.form['nombre_variable'] .

Lo siguiente que tengo, es una llamada a una función que me valida los campos y devuelve un objeto Ramo o un False (dependiendo):

def IngresoRamo(cls, NombreRamo, PassRamo):
    """Comprobar que no vengan vacíos"""
    if(NombreRamo and PassRamo):
        from Clases.ramo import Ramo
        return Ramo(Nombre = NombreRamo, Pass = PassRamo)
    else:
        return False 

A su vez, y aquí viene lo importante, la clase Ramo tiene lo siguiente:

from couchdbkit import Document, StringProperty

class Ramo(Document):


    Nombre = StringProperty(required = True)
    Pass = StringProperty(required = True)

Importamos Document y StringProperty y creamos la clase Ramo como un Document.

Por último, para guardar en la BD:

from couchdbkit import Server


class RamoDAO():

    server = None
    db = None


    def __init__(self):
        self.server = Server('https://usuario:pass@usuario.cloudant.com')
        self.db = self.server.get_or_create_db('notas_st')


    def _Guardar(self, Ramo):
        Ramo.set_db(self.db)
        Ramo.save()

Y con esto nos conectamos a la BD e insertamos el registro. Si vamos a la página: Captura de pantalla 2014-04-18 a la(s) 23.30.52 Y como pueden ver, couchdbkit mágicamente nos agrega el doc_type dependiendo de la clase del objeto ingresado ;)

Publicado en CouchDB, Python | Etiquetado , , , | Deja un comentario

Flask, Templates (II)

Seguimos !

Una de las características de Flask, es que “hereda” casi todo de Django, pero sin tanto jaleo. A veces no queremos matar moscas a cañonazos :) Una de esas cositas que tiene de Django son las templates o plantillas: Jinja2.

Si bien Jinja2 tiene muchas cosas que incorporar para hacernos la vida más simple, aquí vamos a ver las más básicas… así como para soltarnos :D

Usando la estructura básica de una página en Bootstrap, tendríamos algo así (Base.html):

<!DOCTYPE html>
<html lang="es">
    <head>
        {% block meta %}
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <meta name="description" content="Aplicación para ver las notas y progreso">
        <meta name="author" content="Mario Cares">
        {% endblock meta %}
        <title>Visor Notas</title>
        {% block css %}
            <link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='css/bootstrap.min.css') }}">
        {% endblock css %}
    </head>
    <body>
        <div class="container">
        {% block contenido %}{% endblock contenido %}
        </div>
        {% block js %}
            <script src="{{ url_for('static', filename='js/jquery-1.11.0.min.js') }}"></script>
            <script src="{{ url_for('static', filename='js/bootstrap.min.js') }}"></script>
        {% endblock js %}
    </body>
</html>

Notar que no utilizamos nada complicado, simplemente el esqueleto básico con los css y js que siempre usamos.

Desde arriba, tenemos el primer block. Cada block debe tener un nombre único. En mi caso, el primero se llama meta y encierra todas las etiquetas meta que tiene la página. Y para terminar el block, simplemente un endblock y el nombre correspondiente

Y así hasta el último que es js.

También tenemos un url_for que nos sirve para buscar un archivo en la carpeta static y obtener su ruta relativa sin tener que lidiar con los ../../ de las carpetas.

Ahora, para usar las templates, las llamamos desde nuestro archivo de rutas. Primero tenemos el import desde flask y luego lo llamamos:

from flask import Flask, render_template

app = Flask(__name__)


@app.route('/')
def index():
    if True:
        return render_template('Generales/Login.html')


if __name__ == '__main__':
    app.debug = True
    app.run()

Si se fijan, estoy llamando a otra template Login.html y no a Base.html que definimos arriba. Y es aquí donde entra la magia de esto. La estructura de Login.html es así:

{% extends "Generales/Base.html" %}
{% block css %}
    {{ super() }}
    <link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='css/singin.css') }}">
{% endblock css %}
{% block contenido %}
    <form class="form-signin" role="form" method="post">
        <h2 class="form-signin-heading">Iniciar Sesión</h2>
        <input type="text" name="txt_rut_alumno" class="form-control" placeholder="Rut Alumno" required autofocus>
        <input type="password" name="txt_password" class="form-control" placeholder="Contraseña" required>
        <button class="btn btn-lg btn-primary btn-block" type="submit">Ingresar</button>
    </form>
{% endblock contenido %}

Lo primero que tenemos es un extends, que funciona de la misma manera … estamos diciendo que nuestra plantilla base será … Base.html, y por lo tanto tendremos su estructura y podremos usar los blocks que ella tiene definida.

Es por eso que tenemos un {% block css %}, siendo que dijimos que el nombre era único. Esto significa que podríamos sobreescribir (un @override) el block css de la plantilla madre… Pero, el {{ super() }} nos permite obtener todo lo que el block original tiene, y después agregar todo lo que tengamos nosotros como plantilla hija. En nuestro ejemplo, al block original que tiene 2 css y le vamos a agregar un 3º . Esto será válido únicamente en el archivo Login.html.

Nuestra plantilla Base.html tenía definido el block contenido sin nada dentro. En Login.html sobreescribimos nuestro dicho block con lo que nosotros como plantilla tenemos.

También podemos realizar includes en el caso que queramos agregar el contenido de una plantilla en otra (plantilla Administrador.html):

{% extends "Generales/Base.html" %}
{% block contenido %}
<!-- Nav tabs -->
<ul class="nav nav-tabs">
    <li class="active"><a href="#home" data-toggle="tab">Home</a></li>
    <li><a href="#ramos" data-toggle="tab">Ramos</a></li>
    <li><a href="#alumnos" data-toggle="tab">Alumnos</a></li>
    <li><a href="#settings" data-toggle="tab">Settings</a></li>
</ul>

<!-- Tab panes -->
<div class="tab-content">
    <div class="tab-pane fade in active" id="home">...</div>
    <div class="tab-pane" id="ramos">
        {% include "Admin/AdminRamo.html" %}
    </div>
    <div class="tab-pane fade" id="alumnos">
        {% include "Admin/AdminAlumno.html" %}
    </div>
    <div class="tab-pane" id="settings">...</div>
</div>
{% endblock contenido %}

Por último, podemos enviar variables a nuestras plantillas de la siguiente manera:

@app.route('/')
def index():
    if True:
        return render_template('Generales/Login.html', Mensaje = "Error", OtroMensaje = u"Algo no funcionó")

Donde Mensaje y OtroMensaje son las variables a enviar con el contenido de cada una. OtroMensaje tiene una u antes del string para poder jugar con tildes y caracteres especiales, por lo que además deben agregar # -*- coding: utf-8 -*- al principio del archivo.

Para poder ocupar dichas variables, en nuestra template escribimos:

<h1>{{ Mensaje }}</h1>
<h2>{{ OtroMensaje }}</h2>

Y eso sería todo :D

Publicado en Python | Etiquetado , | Deja un comentario

Empezando con Flask, Routes (I)

Eso.

Aquí en mi ciudad, Iquique (Chile), la semana pasada tuvimos un dos terremotos y la universidad en la que hago clases virtualmente se vino abajo. Uno de los ramos que enseño es para los que recién entran, el año 1 de la carrera de Informática. A ellos les tengo que enseñar Python … y la verdad es que andaba oxidado 8O … así que para “refrescar” la memoria empecé a buscar algún micro-framework para crear aplicaciones web, llegando a Flask.

Aquí en el blog escribí sobre Slim, para PHP. Flask es lo mismo, pero para Python.

Es tan sencillo como:

from flask import Flask

app = Flask(__name__)


@app.route('/')
def hello_world():
    return 'Hello World!'


if __name__ == '__main__':
    app.run()

Lanzando por consola, la salida nos dice:
* Running on http://127.0.0.1:5000/
Y a esa dirección debemos ir.

Lo único que tenemos es el “Hello World!” y nada más.

Agregamos una nueva ruta con lo siguiente:

@app.route('/Nuevo')
def Nuevo():
    return "Nuevo :D"

Reiniciamos la aplicación, y al entrar en http://127.0.0.1:5000/Nuevo tenemos la nueva página.

Si declaramos una ruta como: @app.route(‘/Usuario/<nombre>’) , estamos creando una variable nombre, la que cambiará con el link que se llame.

@app.route('/Usuario/<nombre>')
def mostrar_usuario(nombre):
    return 'El nombre del usuario es %s' % nombre

Por defecto, todas las rutas responden al método GET, por lo que si enviamos un formulario por POST a cualquier ruta, no funcionará, ya que la ruta POST aún no ha sido definida.

Para definir rutas, tan simple como:

@app.route('/login', methods=['GET', 'POST'])
def login():
    if request.method == 'POST':
        logica_para_validar_usuario()
    else:
        mostrar_el_formulario_del_login()

Eso por ahora, seguimos más tarde con las Templates

Publicado en Python | Etiquetado , | 2 comentarios

CouchDB (Parte II)

En la entrada anterior vimos un poco (por decir NADA) de CouchDB, nos conectamos a Cloudant e insertamos un registro … más que eso no hicimos 8O … principalmente porque aún no entiendo casi nada de ésta cosa … es muy enredado :P

Ahora vamos a ver más cosillas.

CouchDB no tiene Tablas o Colecciones

Así, tal cual. Una DB es un contenedor que no tiene divisiones, por lo que tenemos documentos juntos. La idea es que no estén revueltos. Es “extraño” cuando menos… pero bue, así lo hicieron :D

Para “solucionar” el tema, a cada documento (objeto) le agregamos un campo para definir el tipo. Algo así:

public class Usuario {

    private String Nombre,
        Pass,
        Mail,
        Tipo;
    private Date FechaRegistro;

    public Usuario(String nombre, String mail, String pass) throws
            UnsupportedEncodingException, NoSuchAlgorithmException {
        Nombre = nombre;
        setPass(pass);
        Mail = mail;
        Tipo = "Usuario";
        FechaRegistro = new Date();
    }
}

Y con ésto podemos deferenciar entre documentos cuando ocupemos vistas.

Vistas

Más que guardar y mantener la información, lo más importante es como verla o recuperarla. Aquí entran las vistas, ya que CouchDB no “tiene” formas para hacer querys (al estilo MongoDB, por ejemplo).

Siguiendo el ejemplo anterior, tenemos algo así: Captura de pantalla 2014-01-25 a la(s) 13.30.58 Y si queremos crear un login de usuarios ? Porque, ya los tenemos registrados…

Las vistas en realidad son índices secundarios (el primario es el campo _id). Por ejemplo, queremos indexar por el Mail de cada persona: Captura de pantalla 2014-01-25 a la(s) 14.34.15Ésta función lo que hace es recorrer TODOS los documentos en nuestra DB (en el parámetro doc). Luego, comprobamos que indexe únicamente documentos con el tipo Usuario. Por último generamos el key & value: siendo el Mail del documento la llave y el documento en si el valor.

Y terminamos de ésta manera: Captura de pantalla 2014-01-25 a la(s) 14.49.28 Entonces podemos hacer la query preguntando por la key (en éste caso el Mail) : Captura de pantalla 2014-01-25 a la(s) 14.52.03 Y qué pasa si queremos consultar por el mail y la pass ? En ese caso, modificamos la key y quedamos con:

function(doc) {
  if(doc.Tipo && doc.Tipo == "Usuario"){
    emit([doc.Mail, doc.Pass], doc);
  }
}

De ésta manera, tenemos una llave compuesta entre el mail y la pass Captura de pantalla 2014-01-25 a la(s) 15.00.44 Ahora, saltamos al login desde nuestra aplicación.

Vistas desde Java

Tenemos un login con nada más que el mail y la pass Captura de pantalla 2014-01-25 a la(s) 16.10.37 Entonces, en el Servlet tengo algo así:

Map<String, String> Params = new HashMap<String, String>();
Params.put("Target", "Mail");
Params.put("Param", request.getParameter("mail"));
for(Usuario Us : (List <Usuario>)U.GET(Params)){
  out.write(Us.toString());
}

Que, en resumen, le pide al DAO(U) que le entrege todos los usuarios en un List<Usuario> que tengan el Mail ingresado en el formulario (ojo que no usamos la pass).

UsuarioDao (el objeto U de recién) a su vez tiene lo siguiente:

public Object GET(Map<String, String> M) {
  if(M.get("Target").equals("Mail")){
    return dbClient.view("vistas/Por_Mail"). //Nombre de la Vista
      includeDocs(true).
      key(M.get("Param")). //El parámetro key en la vista
      query(Usuario.class); //La clase a la que se va a Des.Serializar
  }
  return null;
} 

Entonces, revisamos qué nos piden (en éste caso, que Target sea Mail -consultar por Mail) y devolvemos el List<Usuario>.

Si estamos consultando a Cloudant, Captura de pantalla 2014-01-25 a la(s) 16.24.45 fijarse en Nombre del contenedor de Vistas y Nombre de Vista. Juntando éstos dos formamos el nombre “completo” de la vista.

Listo :D Captura de pantalla 2014-01-25 a la(s) 16.29.37Y si queremos llamar la vista por mail y pass, simplemente agregamos un valor más al campo key:

public Object GET(Map<String, String> M) {
  if(M.get("Target").equals("Mail")){
    return dbClient.view("vistas/Por_Mail"). //Nombre de la Vista
      includeDocs(true).
      key(M.get("Param1"), M.get("Param2")). //El parámetro key en la vista, ahora con 2 valores
      query(Usuario.class); //La clase a la que se va a Des.Serializar
  }
  return null;
} 

Genial :D !

Eso por ahora ;)

Publicado en CouchDB, Java, JavaScript | Etiquetado , | Deja un comentario

CouchDB (Parte I)

Luego de una laaaarga temporada sin entradas nuevas, comenzamos el 2014 con ésto :D

Como saben soy usuario de MongoDB (hasta tengo un diploma para Java :D ) pero siempre quiero aprender nuevas tecnologías, en éste caso relacionadas con las BDs -> Documentos.

Fue así como llegué a CouchDB ;)

Pueden instalarlo en sus equipos, o usarlo desde la internes con Cloudant Captura de pantalla 2014-01-18 a la(s) 18.17.14 (de aquí en adelante, todo lo hago por Cloudant, no por cliente “instalable”)

Para usar Cloudant deben registrarse. El “hosting” es gratis hasta que nuestras BDs comiencen a pedir más gears (openshift style).

Entonces, empezamos conectando a Cloudant desde Java. Para eso, vamos a ocupar LightCouch . Lo podemos instalar desde Maven, siguiendo: Captura de pantalla 2014-01-18 a la(s) 18.30.34Y listo, lo tenemos agregado.

Ahora, imaginemos que tenemos un registro de usuarios con 3 campos: Captura de pantalla 2014-01-20 a la(s) 0.06.14Y queremos registrar los usuarios en CouchDB (por Cloudant). Empezamos por crear el POJO simple con los 3 campos + la fecha de registro.

public class Usuario {

    private String Nombre,
        Pass,
        Mail;
    private Date FechaRegistro;

    public Usuario(String nombre, String pass, String mail) {
        Nombre = nombre;
        Pass = pass;
        Mail = mail;
        FechaRegistro = new Date();
    }

    public String getNombre() {
        return Nombre;
    }

    public void setNombre(String nombre) {
        Nombre = nombre;
    }

    public String getPass() {
        return Pass;
    }

    public void setPass(String pass) {
        Pass = pass;
    }

    public Date getFechaRegistro() {
        return FechaRegistro;
    }

    public String getMail(){
        return Mail;
    }

    public void setMail(String mail){
        Mail = mail;
    }

    public void setFechaRegistro(Date fechaRegistro) {
        FechaRegistro = fechaRegistro;
    }
}

Eso hasta ahora. Para que sea corto :P lo insertamos directamente desde nuestro servlet (o lo que sea que estén usando).

Primero, la información para conectarse al servidor (cloudant en mi caso):

CouchDbClient dbClient = new CouchDbClient(
  "cajamonte", //nombre BD
   true, //crear la BD si no existe
   "http", //protocolo: http o https
   "mariocares.cloudant.com", //host
    5984, //puerto
    "mariocares", //usuario
    "123456" //contraseña
); 

Y con esto ya estamos conectados. Siempre esto en un try/catch para ver por qué NO pudimos conectar.

Insertamos un registro:

Response resp = dbClient.save(
  new Usuario(
    request.getParameter("txt_usuario"),
    request.getParameter("txt_email"),
    request.getParameter("txt_pass")
  )
);

Mostramos el ID y Rev generados

out.write("<h1>Insertado con ID: " + resp.getId()+"</h1>");
out.write("<h2>REV: " + resp.getRev()+"</h2>");

Listo ! es así de simple :D Captura de pantalla 2014-01-20 a la(s) 0.47.35Y en Cloudant Captura de pantalla 2014-01-20 a la(s) 0.49.20Como documento Captura de pantalla 2014-01-20 a la(s) 0.50.52Eso por ahora ;)

Publicado en CouchDB, Java, Tutoriales | Etiquetado , , | 3 comentarios

Los números de 2013

Los duendes de las estadísticas de WordPress.com prepararon un informe sobre el año 2013 de este blog.

Aquí hay un extracto:

La sala de conciertos de la Ópera de Sydney contiene 2.700 personas. Este blog ha sido visto cerca de 57.000 veces en 2013. Si fuera un concierto en el Sydney Opera House, se se necesitarían alrededor de 21 presentaciones con entradas agotadas para que todos lo vean.

Haz click para ver el reporte completo.

Publicado en Uncategorized | Deja un comentario

jSONP

Eso …

Resulta que aquí en el trabajo, mi jefe tiene un sistema en un servidor distinto al mio. Dicho sistema tiene registrado unos usuarios.

Mi sistema (uno nuevo que estoy haciendo) necesita usar info de los usuarios registrados en el otro sistema, pero al estar en un sistema distinto las peticiones que realizaba el mio al de mi jefe no funcionaban x_X Captura

Entonces buscando por internes, encontré una solución: Agregar header(“Access-Control-Allow-Origin: *”); a la respuesta de la página en php… peeeero Captura

Si bien podía hacer la petición, no recibía respuesta :( Y entonces encontré una solución que funcionaba como correspondía ;)

En vez de utilizar un

$.post(
    "http://saludcormudesi.cl/unisag/ws.php",
    {
        checkLogin:"1",
        id: "174321167",
        key: "123456"
    },
    function(data){
        alert(data)
    }
);

común y silvestre entraba a escena el tipo de petición jsonp.

Primero, en el servidor la cosa cambia un poco. Nuestra respuesta (independiente de la salida) queda así:

echo $_GET['callback'].'('.json_encode($respuesta).')'; 

Y en nuestro código en cliente:

$.ajax({
    dataType: 'jsonp',
    data: {
        checkLogin:"1",
        id: "23213",
        key: "123456"
    },
    jsonp: 'callback',
    url: "http://saludcormudesi.cl/unisag/ws.php",
    success: function (jsonData) {
            alert(jsonData.Usuario);
    },
    error: function(errorObj) {
            alert(errorObj.statusText);
    }
});

Lo importante aquí es el valor que le demos al atributo jsonp que si se fijan es el mismo que tiene la respuesta del servidor (callback). Entonces, la respuesta queda como jQuery1102007699555391445756_1385385681812({“Existe”:1,”Usuario”:”Mario Cares”})

Lo que hace jsonp es transformar todo en una función. Cada petición tiene un id específico que va en el atributo callback. Entonces al recibir la respuesta, se ejecuta la función dentro de la petición y tadaaaa , funciona de las mil maravillas. Tanto así que no es necesario agregarle el header en el php :) Captura

Referencias:

http://www.funcion13.com/2012/04/12/como-realizar-peticiones-ajax-cross-domain-jsonp-jquery/

Publicado en JavaScript, php, Tips | Deja un comentario

MySQL DataSource en JBoss

Estoy desarrollando una app en OpenShift y esta vez quise escribirla en Java.

Toda la vida he trabajado con GlassFish … pero en OS no tienen soporte para dicho server … así que la única opción que quedaba era usar Tomcat o JBoss … nunca he usado ninguna de las 2… pero me fui con la última.

Pude levantar el servidor y mandar info desde un jsp a un servlet sin ningún problema. El problema comenzó al tratar de crear un pool de conexiones para MySQL… estuve bastante rato tratando de hacerlo…. así que lo siguiente es un tuto para lograrlo :)

Descargar el driver MySQL para Java

Simple, desde aquí. Mi versión (a la fecha) es mysql-connector-java-5.1.27-bin.jar .

Mover driver a carpeta JBoss

Una vez que descargamos el driver y lo descomprimimos, creamos las carpetas para el mismo (siempre dentro de modules) : com/mysql/main  lo copiamos/movemos a la carpeta recién creada. Mi ruta completa es así: /home/luk0s/.Programas/jboss-eap-6.1/modules/com/mysql/main . Ahora, creamos el archivo module.xml y tenemos algo así. main_013

Editar archivo module.xml

Agregamos lo siguiente al archivo:

<?xml version="1.0" encoding="UTF-8"?>

<module xmlns="urn:jboss:module:1.0" name="com.mysql">
  <resources>
    <resource-root path="mysql-connector-java-5.1.27-bin.jar"/>
  </resources>
  <dependencies>
    <module name="javax.api"/>
  </dependencies>
</module>

Donde com.mysql corresponden a las carpetas y path tiene el nombre del archivo.

Referenciarlo desde Servidor

Ahora que tenemos el módulo creado, tenemos que referenciarlo para poder utilizarlo. Para eso editamos el archivo standalone.xml dentro de raiz_jboss/standalone/configuration .

Bajamos hasta el tag de <drivers> y agregamos lo siguiente:

<driver name="mysql" module="com.mysql" />

Siendo com.mysql el nombre de nuestro módulo antes creado.

Agregando referencia como DataSource

Lo siguiente es, y sin salir de standalone.xml es subir hasta <datasources> y agregar el siguiente item:

<datasource jndi-name="java:/mydb" pool-name="taxionline_pool" enabled="true" jta="true" use-java-context="true" use-ccm="true">
    <connection-url>jdbc:mysql://localhost:3306/BASE_DE_DATO</connection-url>
    <driver>mysql</driver>
    <security>
        <user-name>NOMBRE_USUARIO</user-name>
        <password>PASSWORD</password>
    </security>
    <statement>
        <prepared-statement-cache-size>100</prepared-statement-cache-size>
        <share-prepared-statements/>
    </statement>
</datasource>

Reemplazando donde corresponda por nuestros datos

Levantando servidor

Por último, iniciamos el servidor y en el output deberíamos tener algo así: Guake!_014Y en la consola de administración: Área de trabajo 1_015

Espero les sirva :)

Link base: https://zorq.net/b/2011/07/12/adding-a-mysql-datasource-to-jboss-as-7/

Publicado en MySQL, Tutoriales | Etiquetado , | 1 comentario