Programacion Interactiva

Descubre una Nueva y Poderosa Herramienta.

FrameWork de Nueva Generacion

Acceso a tu Informacion desde cualquier Dispositivo con Navegador.

Enfoque en el Backend

Frontend de forma facil con Odoo y XML.

Creacion de Verticales

Creacion de nuevas Verticales Conquistando nuevos Mercados.

Tu marca aqui mismo

Llega a miles de personas.

Publicidad

jueves, 9 de junio de 2016

Trabajando con Symfony2 y Odoo (OpenERP)

Symfony2 & Odoo (OpenERP)



    Symfony es un completo framework diseƱado para optimizar, gracias a sus caracterĆ­sticas, el desarrollo de las aplicaciones web. Para empezar, separa la lógica de negocio, la lógica de servidor y la presentación de la aplicación web. Usa un entorno de desarrollo MVC (Modelo Vista Controlador) similar al Framework de Odoo, este framework se usa para el desarrollo de aplicaciones en PHP.

1.1. Instalación de LAMP

LAMP son las siglas de linux apache mysql php. Symfony necesita de un servidor LAMP para poder funcionar. A continuación veremos como instalar un servidor LAMP en nuestro sistema. En primer lugar instalaremos apache:
$ sudo apt-get install apache2

Posteriomente instalamos php:
$ sudo apt-get install php5 libapache2-mod-php5 php-cli php-mysql
y reiniciamos apache:
$ sudo service apache2 restart
por Ćŗltimo instalamos mysql:
$ sudo apt-get install mysql-server mysql-client libmysqlclient-dev
durante el proceso de instalación nos pedirÔ que asignemos contraseña al usuario root de mysql.
Adicionalmente, podemos instalar también phpmyadmin para ayudarnos con la configuración de mysql:
$ sudo apt-get install phpmyadmin
y creamos un enlace simbólico para acceder:
$ sudo ln -s /usr/share/phpmyadmin /var/www
Ahora podremos acceder mediante la url 192.168.0.122/phpmyadmin.

1.2. Instalación de composer

Composer es un gestor de dependencias para un proyecto php. Para instalar composer primero debemos instalar curl
$ sudo apt-get install curl
Posteriomente instalamos composer:
$ curl -s https://getcomposer.org/installer | php
Si todo ha funcionado bien, en el directorio donde te encuentras veras un nuevo fichero llamado composer.phar. Para comprobar que se ha instalado correctamente, ejecuta el siguiente comando que muestra el menĆŗ de opciones de Composer:
$ php composer.phar
Instalar Composer de esta manera es correcto, pero te obliga a realizar una nueva instalación para cada proyecto Symfony2. Si tienes muchos proyectos, es mucho mejor que instales Composer de forma global en tu ordenador, para que todos los proyectos utilicen la misma versión de Composer.
Para instalar Composer globalmente, mueve el archivo composer.phar a algĆŗn directorio ejecutable del sistema, como por ejemplo:
$ sudo mv composer.phar /usr/local/bin/composer
Comprueba que todo funciona bien ejecutando el comando composer sin opciones desde cualquier directorio del sistema. La instalación global de Composer también facilita su mantenimiento, ya que sólo hay que ejecutar el siguiente comando para actualizar la versión de Composer de todos los proyectos:
$ sudo composer self-update

1.3. Instalación de Symfony

Gracias a composer la instalación de Symfony se reduce a un simple comando de consola:
php composer.phar create-project symfony/framework-standard-edition nuestra_ruta/ 2.3.6
por ejemplo:
php composer.phar create-project symfony/framework-standard-edition /home/user/openerp/ 2.3.6
En caso de haber instalado composer globalmente:
composer create-project symfony/framework-standard-edition nuestra_ruta/ 2.3.6
El proceso de instalación nos ira pidiendo los datos de configuración de nuestro servidor. Podemos introducirlos en el momento o introducirlos a mano en el fichero app/config/parameters.yml
Una vez instalado, hay que borrar el bundle AcmeDemo:
Eliminar carpeta AcmeBundle de src
Eliminar $bundles[] = new AcmeDemoBundleAcmeDemoBundle(); del fichero app/AppKernel.php
Eliminar bloque referente AcmeDemo en app/config/routing_dev.yml

2. Conectar Symfony con OpenErp

Ya tenemos instalado Symfony en nuestro sistema, ahora vamos a ver como realizar la conexión con nuestro OpenERP.

2.1. Crear bundle conexión OpenERP

Un bundle se Symfony es el equivalente de un módulo de OpenERP, contiene todos los ficheros que proporcionan una nueva funcionalidad a nuestra aplicación web.
Para generar un bundle, debemos ejecutar en el directorio de nuestro proyecto Symfony:
$ php app/console generate:bundle
Esto nos mostrara un asistente para generar nuestro bundle:
Bundle Namespace: Openerp/ConnectBundle
Bundle Name: ConnectBundle
Target directory: Pulsamos enter (valor por defecto)
Configuration format: yml
Do you want to generate the whole directory structure?: pulsamos enter (valor por defecto)
Do you confirm generator?: pulsamos enter (valor por defecto)
Confirm automatic update of your kernel?: Pulsamos enter (valor por defecto)
Si vamos a la carpeta src de nuestro proyecto, podremos ver como se ha generado el nuevo Bundle, OpenERP.

connect

2.2. Generar entidad datos OpenERP

Una opción de configuración que podemos utilizar para no tener que introducir los datos de conexión en cada acceso, es generar una entidad de conexión a OpenERP para almacenar los parÔmetros de conexión. Una entidad es un fichero php que se encarga de interactuar con la base de datos de nuestro proyecto.
Para generar esta entidad debemos ejecutar en el directorio de nuestro proyecto Symfony el siguiente comando:
$ php app/console doctrine:generate:entity
Esto nos mostrara un asistente para generar nuestra entidad:
The Entity shortcut name: ConnectBundle:OpenERP
Configuration format (yml, xml, php, or annotation) [annotation]: pulsamos enter 

New field name (press  to stop adding fields): server
Field type [string]: pulsamos enter
Field length [255]: 100

New field name (press  to stop adding fields): bda
Field type [string]: pulsamos enter
Field length [255]: 100

New field name (press  to stop adding fields): username
Field type [string]: pulsamos enter
Field length [255]: 100

New field name (press  to stop adding fields): password
Field type [string]: pulsamos enter
Field length [255]: 255

New field name (press  to stop adding fields): pulsamos enter

Do you want to generate an empty repository class [no]? No 

Do you confirm generation [yes]? Yes
Con esto ya hemos generado el código de nuestra endidad, el cual podremos ver en la carpeta Entity de nuestro bundle.
Si queremos mapear esta entidad con nuestra base de datos, debemos ejecutar el siguiente comando en la consola:
$ php app/console doctrine:schema:create
Una vez creada la entidad, podemos crear datos de conexión para nuestra entidad mediante el phpmyadmin indicando la url de nuestro servidor, la base de datos a la cual nos vamos a conectar, el usuario y la contraseña.

2.3. Generar controlador OpenERP

Un controlador es un fichero que incluye la funcionalidad de nuestro bundle. Normalmente un controlador accede a la entidad de nuestro bundle, para acceder a la información de nuestra base de datos, y devuelve una vista, que muestra en pantalla esta información. Vamos a generar un controlador nuevo para conectar a OpenERP.
El primer paso serĆ­a descargar la liberia de conexion a OpenERP de la siguiente url https://github.com/tejastank/openerp-php-connector e incluirla en la carpeta controller de nuestro bundle.
require_once __DIR__.'/openerp/openerp.class.php';
En este ejemplo la libreria de conexión a OpenERP se ha guardado en la carpeta openerp del controlador.
Con todo esto, podemos desarrollar nuestra conexión simple mediante el siguiente controlador:
<?php
    namespace OpenerpConnectBundleController;

    use SymfonyBundleFrameworkBundleControllerController;
    use OpenerpConnectBundleEntityOpenerp;
    use SymfonyComponentHttpFoundationRequest;

   require_once __DIR__.'/openerp/openerp.class.php';

   class DefaultController extends Controller
   {

       public function indexAction($name)
        {
           return $this->render('ConnectBundle:Default:index.html.twig', array('name' => $name));
       }

       public function loginAction(Request $request)
       {

           $openerp = new Openerp();
           $form = $this->createFormBuilder($openerp)
             ->add('username', 'text')
             ->add('password', 'password')
             ->getForm();

           if ($request->isMethod('POST')) 
           {
                $form->bind($request);
              if ($form->isValid()) 
              {
                    $em = $this->getDoctrine()->getManager();
                    $shop = $em->getRepository('ConnectBundle:Openerp')->findOneBy(array('id' => 1));
                 $rpc = new OpenERP();
                 $uid = $rpc->login($shop->getUsername(), $shop->getPassword(), $shop->getBda());
                 $name = $rpc->read(array($uid), array('name'), 'res.users');
                 return $this->render('ConnectBundle:Default:welcome.html.twig', array(
                    'name' => $name[0]['name'],));
              }
           }
          return $this->render('ConnectBundle:Default:login.html.twig', array(   
          'form' => $form->createView(),
            ));
       }
    }
Este controlador genera un formulario simple para introducir el usuario y contraseƱa de un usuario de OpenERP. Una vez validado el formulario, busca el nombre del usuario que se ha conectado y devuelve una pĆ”gina con el mensaje “Bienvenido” mas el nombre de este usuario.

Las vistas para este controlador son las que se devuelven en el return:
return $this->render('ConnectBundle:Default:login.html.twig', array('form' => $form->createView(),));
return $this->render('ConnectBundle:Default:welcome.html.twig', array('name' => $name[0]['name'],));
Y se deben crear en la carpeta Resources/views del bundle, conteniendo el siguiente código:
<!-- login.html.twig -->
<form action="{{ path('portada')}}" method="post" {{ form_enctype(form)}}>
{{ form_widget(form)}}
<input type="submit"/>
</form>
<!-- welcome.html.twig -->
<h1>Bienvenido {{ name}}</h1>
Por último, hay que crear el path del controlador. Para ello hay que añadir las siguientes líneas en el fichero routing.yml que se encuentra en la carpeta app/config de nuestro proyecto:
portada:
path: /
defaults: { _controller: ConnectBundle:Default:login}
Ahora si accedemos a 192.168.0.122/symfony/web/app_dev.php podremos ver nuestro formularĆ­o de acceso.

Con todo esto hemos conseguido generar un bundle de conexión a OpenERP que puede ser incluido en otros bundles facilitando con esto acceder a los datos de OpenERP.

3. Conexión OpenERP con Symfony

Symfony funciona como un servicio rest, el cual nos permite acceder a la información mediante una url que accede a un método definido en un controlador. A continuación veremos un ejemplo de como conectar OpenERP con Symfony.
En primer lugar vamos a crear un módulo de OpenERP que genere una vista con un boton que nos permita enviar todos los productos de nuestro sistema a Symfony.
Definimos la clase:
class symfony(osv.osv_memory):
 _name = 'symfony'
symfony()
Con su vista asociada:
<?xml version="1.0" encoding="UTF-8"?>
    <openerp>
        <data>
            <record id="sync_products_form" model="ir.ui.view">
                <field name="name">sync.products.form</field>
                <field name="model">symfony</field>
                <field name="type">form</field>
                <field name="arch"type="xml">
                    <form string = "Sync Products">
                        <button name="sync_products" string="Sync" type="object" icon="gtk-apply"/>
                    </form>
                </field>
           </record>
         <record id="action_sync_products" model="ir.actions.act_window">
              <field name="name">Sync Products</field>
              <field name="type">ir.actions.act_window</field>
              <field name="res_model">symfony</field>
              <field name="view_type">form</field>
              <field name="view_mode">form</field>
              <field name="view_id" ref="sync_products_form"/>
              <field name="target">new</field>
          </record>
          <menuitem id="menu_sync_product" name="Sync Products"
          parent="stock.menu_stock_product" sequence="6"
          action="action_sync_products"/>
      </data>
    </openerp>
Y el metódo de sincronización:
def sync_products(self, cr, uid, ids, context = None):
   product_obj = self.pool.get("product.template")
      product_ids = product_obj.search(cr, uid, [], context = context)
   products = []

   for product in product_obj.browse(cr, uid, product_ids, context = context):
       product_dict = {}
        product_dict['name'] = product.name
                product_dict['list_price'] = product.list_price
                product_dict['standard_price'] = product.standard_price
                product_dict['description'] = product.description
                products.append(product_dict)

    products_json = json.dumps(products)
    url = "http://192.168.0.122/symfony/web/app_dev.php/get_products"
        f = urllib2.urlopen(url, products_json)
    response = f.read()
    f.close()
Como podemos observar el mƩtodo recupera todos los productos que tenemos en el sistema, los codifica en json y los envia al controlador get_products.
El siguiente paso seria definir este controlador en nuestro sistema Symfony:
public function get_productsAction()
{
    $em = $this->getDoctrine()->getManager(); 
    $products = json_decode($this->get('request')->getContent(), true);
        foreach ($products as $p)
       {
        $product = new Product();
                $product->setName($p['name']);
                $product->setListPrice($p['list_price']);
                $product->setStandardPrice($p['standard_price']);
                $product->setDescription($p['description']);
                $em->persist($product);
   }
   $em->flush();
      return new Response("ok");
}
Y aƱadirlo a nuestro routing.yml:
getProducts:
    path: /get_products
    defaults: { _controller: ConnectBundle:Default:get_products}
Como podemos observar en el código de nuestro controlador, existe una nueva entidad llamada Product que es la que se encarga de almacenar los productos. Para generarla utilizaremos la consola de Symfony:
$ php app/console doctrine:generate:entity

The Entity shortcut name: ConnectBundle:Product
Configuration format (yml, xml, php, or annotation) [annotation]: 
pulsamos enter

New field name (press  to stop adding fields): name
Field type [string]: 
pulsamos enter

Field length [255]: 
pulsamos enter

New field name (press  to stop adding fields): list_price
Field type [string]: decimal

New field name (press  to stop adding fields): standard_price
Field type [string]: decimal

New field name (press  to stop adding fields): description
Field type [string]: text

New field name (press  to stop adding fields): 
pulsamos enter

Do you want to generate an empty repository class [no]? 
pulsamos enter

Do you confirm generation [yes]? 
pulsamos enter
Por Ćŗltimo, actualizamos el esquema de nuestra base de datos.
$ php app/console doctrine:schema:update --force
Con esto ya podemos ejecutar nuestro módulo de OpenERP y realizar la conexión que nos importara todos los productos.
productos

4. Conclusiones

Como hemos podido observar en este artículo, la conexión a OpenERP con Symfony es muy sencilla. Debemos incluir la librería de conexión de php a OpenERP en un nuevo bundle de conexión. Este nuevo bundle podra ser incluido en otros bundles facilitando con esto el acceso de Symfony a OpenErp.

En cuanto a la conexión de OpenErp con Symfony, también hemos podido comprobar que es bastante sencilla ya que Symfony actua como un servicio rest muy facil de acceder. Simplemente debemos llamar desde OpenErp al método de Symfony que queramos acceder.

En resumen, generar un nuevo proyecto web con Symfony que acceda a OpenERP es muy sencillo, lo cual nos permite generar proyectos como tiendas online mediante el respaldo de OpenERP.

viernes, 27 de mayo de 2016

Solucion al Error bundle 'web.assets_common' o error lessc

Solución de Errores lessc y web.assets_common




    Últimamente las nuevas librerĆ­as de Odoo 9 para mejorar el ambiente (interfaz) web tienen una serie de conflictos con el Sistema Operativo, en ocasiones podemos ver errores como la imagen anterior, errores 404, errores 500, etc., las causas pueden ser muchas pero la mayorĆ­a se basan en la librerĆ­a nodejs y npm, para dar solución a este error debemos ejecutar los siguientes comandos:

  1. sudo apt-get install nodejs
  2. sudo apt-get install npm
  3. sudo npm install -g less
  4. sudo npm install -g less-plugin-clean-css
  5. sudo ln -s /usr/local/bin/lessc /usr/bin/lessc
  6. sudo ln -s /usr/bin/nodejs /usr/bin/node


Listo, solo debemos reiniciar el servicio de Odoo y refrescar el navegador web, en ocasiones sera necesario tener que eliminar los archivos temporales y la cache del navegador.

Nota: Estos comandos solo funcionan para los Sistemas derivados de debĆ­an (Ubuntu Server, Ubuntu Desktop, Linux Mint, erc..)

jueves, 26 de mayo de 2016

¿Por que hay tantos Pythons?

Python es asombroso.


Sorprendentemente, esa es una declaración bastante ambigua. ¿A quĆ© me refiero con ‘Python’?, ¿Me refiero a la interfaz abstracta de Python?, ¿Me refiero a CPython, la implementación comĆŗn de Python (y no confundir con Cython, que son similares en sus nombres)?, ¿O me refiero a algo completamente distinto? Tal vez me estĆ© refiriendo indirectamente a Jython, o IronPython, o PyPy. O tal vez me he ido al extremo y estoy hablando de RPython o RubyPython (los cuales son cosas muy, muy distintas).
Mientras las tecnologías mencionadas anteriormente son llamadas de formas parecidas y referenciadas de la misma manera, algunas de ellas sirven para propósitos completamente distintos (o, al menos, operan de maneras completamente distintas).
A lo largo de mi tiempo trabajando con Python, me topé con toneladas de estas herramientas .*ython. Pero no hasta hace poco me tomé el tiempo de entender qué es lo que son, cómo funcionan y por qué son necesarias (a sus maneras).
En este artículo, voy a empezar desde cero y recorreré varias implementaciones de Python, concluyendo con una introducción detallada a PyPy, el cual creo es el futuro del lenguaje.
Todo empieza con entender que es lo que ‘Python’ realmente es.
Si tienes un buen entendimiento sobre código binario, mĆ”quinas virtuales y parecidos, siĆ©ntete libre de saltarte esta parte.

“Python es interpretado o compilado?”

Este es un punto común de confusión para principiantes en Python.
La primera cosa que hay que saber es que ‘Python’ es una interfaz. Existe una especificación sobre lo que Python deberĆ­a hacer y cómo deberĆ­a comportarse (cómo con cualquier interfaz). Y hay mĆŗltiples implementaciones (como en cualquier interfaz).
Lo segundo que hay que saber es que ‘interpretado’ y ‘compilado’ son propiedades de una implementación, no de una interfaz.
Entonces, la pregunta no estĆ” realmente bien formada.
¿Python es interpretado o compilado? La pregunta no estĆ” realmente bien formada.
Dicho esto, para la implementación mĆ”s comĆŗn (CPython: escrito en C, usualmente llamado simplemente ‘Python’, y seguramente lo que estĆ”s usando si no tienes idea de lo que estoy hablando), la respuesta es:interpretado, con algunas partes compiladas. CPython compila** el código fuente de Python a *bytecode, y en ese momento interpreta ese bytecode, ejecutĆ”ndolo sobre la marcha.
Nota: no es una ‘compilación’ en sentido tradicional de la palabra. Normalmente, decimos que ‘compilar’ es tomar el código de alto nivel y convertirlo en código binario. Pero es un tipo de ‘compilación’.
Veamos la respuesta un poco mƔs de cerca, ya que nos permitirƔ entender algunos de los conceptos que surgirƔn mƔs adelante en el artƭculo.

Bytecode vs. código binario

Es muy importante entender la diferencia entre bytecode y código binario (o nativo), tal vez mejor ilustrada con ejemplos:
  • C compila a código binario, que luego es ejecutado directamente en tu procesador. Cada instrucción le indica a tu CPU que mueva cosas alrededor.
  • Java compila a bytecode, que luego es ejecutado en la mĆ”quina virtual de Java(Java Virtual Machine, ó JVM), una abstracción de una computadora que ejecuta programas. Cada instrucción es entonces manejada por la JVM, que interactĆŗa con tu computadora.
En tĆ©rminos breves: código binario es mĆ”s rĆ”pido, pero bytecode es mĆ”s portable y seguro.
El código binario se ve distinto, dependiendo de tu mÔquina, pero bytecode se ve igual en todas las maquinas. Se podría decir que el código binario estÔ optimizado para tu configuracion.
Volviendo a CPython, el proceso en el conjunto de herramientas sucede de la siguiente manera:
  1. CPython compila tu código Python a bytecode
  2. Ese bytecode es entonces ejecutado en la MƔquina Virtual CPython
Los principiantes asumen que Python es compilado a raíz de los archivos .pyc. Hay alguna verdad en esto: el archivo .pyc es bytecode compilado, que es después interpretado. Entonces si haz ejecutado código Python y ya tienes un archivo .pyc disponible, el mismo va a ejecutarse mÔs rÔpido la segunda vez ya que no necesitarÔ recompilar el bytecode.

Maquinas virtuales alternativas: Jython, IronPython, y mƔs






Cómo mencionĆ© anteriormente, Python tiene varias implementaciones. De vuelta, como mencionĆ© antes, la mĆ”s comĆŗn es CPython. Ɖsta es una implementación de Python escrita en C y es considerada la implementación ‘por defecto’.
¿Pero, quĆ© pasa con las alternativas? Una de las mĆ”s prominentes es Jython, una implementación en Java que utiliza la JVM. Mientras CPython produce bytecode para ser corrido en la VM de CPython, Jython produce bytecode de Java para correr en la JVM (esto es lo mismo que es producido cuando se compila un programa en Java).
“¿Por quĆ© usarĆ­a alguna vez una implementación alternativa?”, podrĆ­as preguntar. Bueno, para empezar, esasdiferentes implementaciones juegan muy bien con diferentes conjuntos de tecnologĆ­as.
CPython hace muy fĆ”cil el escribir extensiones C para tu código Python porque al final es ejecutado por un intĆ©rprete de C. Por otro lado, Jython, facilita trabajar con otros programas en Java: puedes importar cualquier clase de Java sin mayor esfuerzo, evocando y utilizando tus clases Java dentro tus programas Jython. (Nota aparte: si no pensaste en esto detalladamente, es una locura. Estamos en un punto donde puedes mezclar y triturar diferentes lenguajes y compilarlos todos en una misma esencia. Como fue mencionado por Rostin, los programas que mezclan código Fortran y C estĆ”n desde hace un tiempo. AsĆ­ que, por supuesto que esto no es algo necesariamente nuevo. Pero sigue siendo genial.)
Cómo ejemplo, esto es código Jython vÔlido:
[Java HotSpot(TM) 64-Bit Server VM (Apple Inc.)] on java1.6.0_51
>>> from java.util import HashSet
>>> s = HashSet(5)
>>> s.add("Foo")
>>> s.add("Bar")
>>> s
[Foo, Bar]
IronPython es otra implementación popular de Python, escrita enteramente en C# y apuntando a la tecnologĆ­a .NET. En particular, corre con lo que se podrĆ­a llamar la MĆ”quina Virtual .NET,Common Language Runtime (CLR)de Microsoft, comparable con la JVM.
Podrías decir que Jython : Java :: IronPython : C#. Corren en sus respectivas VMs, puedes importar clases C# en tu código IronPython y clases Java desde tu código Jython, etc.
Es totalmente posible sobrevivir sin tocar alguna vez una implementación de Python no-CPython. Pero hay ventajas que se obtienen desde el cambio, muchas de ellas son dependientes de la tecnologĆ­a que uses. ¿Usas muchos lenguajes basados en la JVM? Jython puede ser para tĆ­. ¿Todo lo que haces es sobre la tecnologĆ­a .NET? Tal vez debas probar IronPython (y tal vez ya lo hayas hecho).
Por cierto: mientras que esto no serĆ­a una razón para usar una implementación diferente, nota que estas implementaciones sĆ­ difieren en comportamiento mĆ”s allĆ” de como tratan tu código fuente en Python. Sin embargo, esas diferencias son comĆŗnmente menores, y se disuelven o emergen con el tiempo mientras estas implementaciones se encuentran bajo un activo desarrollo. Por ejemplo, IronPython usa cadenas Unicode por defecto; Sin embargo, CPython, por defecto usa ASCII para versiones 2.x (fallando con un error de codificaciónUnicodeEncodeError para caracteres no-ASCII), pero sĆ­ soporta cadenas Unicode por defecto para las versiones 3.x.

Compilación Justo-a-Tiempo: PyPy y el futuro

Por lo tanto, tenemos una implementación de Python escrita en C, una en Java una en C#. El próximo paso lógico: una implementación de Python escrita en… Python. (El lector educado encontrarĆ” esta notación levemente engaƱosa).
Aquí es donde las cosas se ponen confusas. Primero, discutamos sobre compilación Justo-a-Tiempo (Just-in-Time, ó JIT).

JIT: El por qué y el cómo

Recordemos que el código binario es mucho mĆ”s rĆ”pido que bytecode. Bueno, ¿y si pudiĆ©ramos compilar algunas partes de nuestro bytecode y luego correrlo como código nativo? TendrĆ­amos que pagar algĆŗn precio al compilar a bytecode (por ej., tiempo), pero si el resultado fuese mĆ”s rĆ”pido, eso serĆ­a genial! Esa es la motivación de la compilación JIT, una tĆ©cnica hĆ­brida que mezcla los beneficios de los interpretadores y los compiladores. En tĆ©rminos bĆ”sicos, JIT quiere utilizar compilación para acelerar un sistema interpretado.
Por ejemplo, un enfoque común tomado por la compilación JIT:
  1. Identificar bytecode que es ejecutado frecuentemente.
  2. Compilar a código binario.
  3. Almacenar el resultado en memoria cachƩ.
  4. Siempre que el mismo bytecode sea encontrado para ejecutar, en vez de usarlo, ejecutar el código binario precompilado y cosechar los beneficios (por ej., aumentos de velocidad)
De esto se trata PyPy: llevar JIT a Python (mira el ApĆ©ndice para ver esfuerzos anteriores). Hay, por supuesto, otros objetivos: PyPy apunta a ser multiplataforma, bajo en consumo de memoria e independiente del conjunto de tecnologĆ­as. Pero JIT realmente se vende por si solo. Como promedio de un puƱado de pruebas de tiempo, se dice que mejora el rendimiento a un factor de 6.27. Para un mayor anĆ”lisis, vĆ©ase este cuadro del PyPy Speed Center:

PyPy es difĆ­cil de entender

PyPy tiene un gran potencial, y a estas alturas es muy compatible con CPython (asĆ­ que puede correr Flask, Django, etc.).
Pero hay mucha confusión alrededor de PyPy (vĆ©ase, por ejemplo, esta propuesta sin sentido para crear unPyPyPy…). En mi opinión, eso es principalmente porque PyPy es actualmente dos cosas:
  1. Un intĆ©rprete de Python escrito en RPython (no Python (he mentido antes). RPython es un subconjunto de Python con tipos estĆ”ticos. En Python, es “prĆ”cticamente imposible” razonar rigurosamente acerca de tipos (¿Por que es tan difĆ­cil? Bueno, considera el hecho que:
     x = random.choice([1, "foo"])
    
    serĆ­a código Python vĆ”lido (crĆ©ditos a Ademan). ¿De quĆ© tipo es x? ¿Cómo podemos razonar acerca de tipos de variables cuando los tipos ni siquiera son estrictamente forzados?). Con RPython, sacrificas algo de flexibilidad, pero a cambio es muchĆ­simo mĆ”s fĆ”cil razonar sobre manejo de memoria y demĆ”s, lo cual permite optimizaciones.
  2. Un compilador que compila código RPython para varios objetivos y agrega JIT. La plataforma por defecto es C, por ej., un compilador RPython-a-C, pero también puedes apuntar a JVM y otros.
Únicamente para mayor claridad, me referiré a ellos como PyPy (1) y PyPy (2).
¿Por quĆ© necesitarĆ­as esas dos cosas, y por quĆ© bajo el mismo techo? PiĆ©nsalo de esta manera: PyPy(1) es un intĆ©rprete escrito en RPython. Entonces toma el código Python del usuario y lo compila a bytecode. Pero el interpretador en sĆ­ (escrito en RPython) tiene que ser interpretado por otra implementación de Python para poder correr, ¿Verdad?
Bueno, podrĆ­amos simplemente usar CPython para correr el intĆ©rprete. Pero eso no serĆ­a lo suficientemente rĆ”pido.
En cambio, la idea es que usemos PyPy(2) (también conocido cómo RPython Toolchain)-Set de herramientas RPython) para compilar al interpretador de PyPy a código que otra plataforma (por ej., C, JVM o CLI) pueda correr en nuestra mÔquina, agregando también JIT. Es mÔgico: PyPy agrega dinÔmicamente JIT a un interpretador, generando su propio compilador! (De vuelta, esto es una locura: estamos compilando un interpretador y agregando otro compilador independiente por separado).
Al final, el resultado es un ejecutable independiente que interpreta el código fuente Python y explota las optimizaciones de JIT. Que es lo que justamente queríamos! Es un gran bocado, pero tal vez este diagrama ayude:
Reiterando, la verdadera belleza de PyPy es que podemos escribir nosotros mismos un puƱado de interpretadores Python distintos en RPython sin preocuparnos por JIT (salvo algunas sugerencias). PyPy entonces implementarĆ­a JIT por nosotros usando el set de herramientas de RPython/PyPy(2).
De hecho, si nos ponemos aĆŗn mĆ”s abstractos, podrĆ­as, teóricamente, escribir un interpretador para cualquierlenguaje, alimentar a PyPy con Ć©l, y obtener un JIT para ese lenguaje. Esto es porque PyPy se enfoca en optimizar el interpretador actual, en vez de los detalles del lenguaje que estĆ” interpretando.
Podrías, teóricamente, escribir un interpretador para *cualquier* lenguaje, alimentar a PyPy con él, y obtener un JIT para ese lenguaje.
Divagando un poco, me gustarĆ­a mencionar que JIT en sĆ­ mismo es absolutamente fascinante. Usa una tĆ©cnica llamada tracing (ó seguimiento), la cual se ejecuta de la siguiente manera:
  1. Correr el interpretador e interpretar todo (sin agregar nada de JIT)
  2. Perfilar levemente el código interpretado.
  3. Identificar operaciones que hayas realizado antes.
  4. Compilar esos pedazos a código binario.
Para mĆ”s información, este documento es altamente accesible y muy interesante.
Para ir concluyendo: usamos el compilador RPython-a-C de PyPy (u otra plataforma) para compilar el interpretador implementado RPython de PyPy.

Concluyendo

¿Por quĆ© es tan genial? ¿Por quĆ© vale la pena perseguir esta idea tan loca? Creo que Alex Gaynor lo describió muy bien en su blog: “[PyPy es el futuro] porque ofrece mejor velocidad, mĆ”s flexibilidad y es una mejor plataforma para el crecimiento de Python.”
En resumen:

ApƩndice: Otros nombres que tal vez hayas oƭdo

  • Python 3000 (Py3k): nombre alternativo para Python 3.0, un mayor, compatible-con-versiones-anterioreslanzamiento de Python que alcanzó la escena en 2008. El equipo de Py3k predijo que llevarĆ­a alrededor decinco anos para que esta versión sea completamente adoptada. Y mientras que la mayorĆ­a (cuidado: se dice que es anecdótico) de los desarrolladores de Python siguen usando Python 2.x, la conciencia de Py3k entre la gente estĆ” incrementĆ”ndose.
  • Cython: un super set de Python que incluye bindings (ó enlaces)para llamar funciones de C.
    • Objetivo: permitirte escribir extensiones en C para tu código Python
    • AdemĆ”s te permite agregar tipos de variables estĆ”ticos a tu código Python, permitiĆ©ndole que sea compilado y alcanzar rendimiento parecido al de C.
    • Es similar a PyPy, pero no es lo mismo. En este caso, estĆ”s forzado a escribir el código del usuario antes de pasarlo al compilador. Con PyPy, escribes simplemente código Python, y el compilador maneja cualquier optimización.
  • Numba: : un “compilador especializado justo-a-tiempo” que agrega JIT a código Python anotado. En tĆ©rminos mĆ”s bĆ”sicos, le das algunas indicaciones y acelera partes de tu código. Numa viene como parte de la distribución Anaconda,un set de paquetes para manejo y anĆ”lisis de datos.
  • IPython: muy diferente a todo lo que hemos discutido hasta ahora. Es un ambiente de procesamiento para Python. Interactivo y con soporte para herramientas grĆ”ficas y experiencia de navegador, etc.

Enlaces de lenguaje

  • RubyPython: un puente entre las mĆ”quinas virtuales de Ruby y Python. Permite embeber código de Python dentro de tu código de Ruby. Defines donde Python comienza y termina, y RubyPython calcula los datos entre las VMs.
  • PyObjc: enlaces de lenguaje entre Python y Objetive-C, actuando como un puente entre ellos. PrĆ”cticamente, eso significa que puedes utilizar librerĆ­as de Objective-C (incluyendo todo lo que necesitas para crear aplicaciones de OS X) desde tu código Python, y módulos de Python desde tu código Objective-C. En este caso, es conveniente que CPython estĆ© escrito en C, el cual es un subconjunto de Objective-C.
  • PyQt: mientras PyObjc te ofrece una interfaz para los componentes grĆ”ficos de OS X, PyQt hace lo mismo para el framework de QT, permitiendote crear completas interfaces grĆ”ficas, acceso a bases de datos SQL, etc. Otra herramienta dirigida a traer la simplicidad de Python a otros frameworks.

Frameworks JavaScript

  • pyjs (Pyjamas): un framework para crear aplicaciones web y de escritorio en Python. Incluye un compilador Python-a-Javascript, un conjunto de widgets, y algunas herramientas mĆ”s.
  • Brython: una mĆ”quina virtual de Python escrita en JavaScript para permitir que el código de Py3k sea ejecutado en navegadores.

Creditos:
      By CHARLES MARSH 
      Traduccion: Pablo Fabregat, miembro de TransBunko
Fuente Original:

miƩrcoles, 25 de mayo de 2016

Redireccionar Odoo a la Pagina Web Principal de una Base de Datos sin DB Filter

Redirección de una Pagina Web sin enviar a los Visitantes al Login o a la Selección de  la Base de Datos



    Un problema que Ćŗltimamente eh notado en Odoo, es al momento de activar los Portales Web y tener MĆŗltiples Bases de Datos, normalmente envĆ­a a los visitantes a la selección de la Base de Datos y cuando redireccionamos el trafico de un dominio a nuestro servidor Web, este siempre es enviado directamente al login y no a la pagina Web, bueno esto puede resolverse de muchas formas, utilizando subdominios, reverse proxy con nginx y muchas mas, a mi parecer todas eran un poco complejas y necesitaban muchos pasos, me di a la tarea de pensar un poco y modificar el mĆ©todo principal de re direccionamiento de odoo, el cual se encuentra en:

path_addons_odoo/web/controller/main.py

Podemos modificar este archivo con vim, vi, nano, gedit, sublime text, brackets o cualquier editor, simplemente debemos ir al metodo llamado def_login_redirect().

Debemos comentar el metodo quedando de la siguiente forma:


#def login_redirect():
#    url = '/web/login?'
#    # built the redirect url, keeping all the query parameters of the url
#    redirect_url = '%s?%s' % (request.httprequest.base_url, werkzeug.urls.url_encode(request.params))
#    return """<html><head><script>
#        window.location = '%sredirect=' + encodeURIComponent("%s" + location.hash);
#    </script></head></html>
#    """ % (url, redirect_url)

Modificamos el mƩtodo quedando de la siguiente manera:

def login_redirect():
    return """<html><head><script>
        window.location = '%sredirect=' + encodeURIComponent("%s" + location.hash);
    </script></head></html>
    """ % ('/?db=Mi_Base_de_Datos', '')

Notemos  que al final solo debemos enviar la Base a la que  se enviara a los visitantes, esta tambiĆ©n debera contener nuestra pagina Web.

Si vamos a redireccionar el trafico de un dominio externo hacia nuestro servidor Odoo, este debe ser redireccionado de la siguiente manera:

http://odoo.poncesoft.net:8069/?db=Mi_Base_de_Datos&web

El valor Mi_Base_de_Datos corresponde a la misma base a la que redireccionamos el mƩtodo login_redirect()


Nota: Cada uno de los valores para el redireccionamiento de nuestra aplicación, dependerÔ de la instalación de nuestro Servidor Odoo y si utilizamos un servidor Web como Nginx, Apache, etc. o la ejecución nativa de Odoo.

martes, 24 de mayo de 2016

Trabajar con iReport y JDK 8 o 9 en Ubuntu 15.10 o Ubuntu 16.04

Instalar iReport con Ubuntu 15.10 o Ubuntu 16.04 y JDK Update 8 o 9



    Últimamente con cada nueva versión de Ubuntu y Java (JDK, JRE y JVM) viene una serie de problemas con nuestras herramientas de trabajo, un problema muy frecuente es no poder trabajar con iReport y Java Update 8 o 9, debido a que viene predefinido en las ultimas versiones de Linux, bueno me eh dado a la tarea de buscar una solución que permita trabajar el Sistema con esta versión de Java y poder trabajar al mismo tiempo nuestro iReport, antes que nada en nuestro Linux podemos tener una serie de diferentes versiones de Java (JDK o JRE).

La solucion es la siguiente:


  1. Instalar OpenJDK Update 7, para ello ejecutamos los siguientes comandos:
    • sudo add-apt-repository ppa:openjdk-r/ppa
    • sudo apt-get update
    • sudo apt-get install openjdk-7-jdk
  2. Podemos hacer una revisión de la versión que tenemos actualmente en el Sistema:
    • java -versión
  3. En Caso de que la instalación del update 7 de Java modificara la versión establecida por defecto en el Sistema, ejecutaremos:
    • sudo /usr/sbin/update-alternatives --config java
    • Seleccionamos la versión correcta.
  4. Solo falta editar el archivo de arranque llamado ireport, que se encuentra en nuestra carpeta de ejecución en mi caso "/home/german/iReport-3.7.6/bin/ireport", podemos abrirlo con gedit o cualquier otro editor y modificar lo siguiente:
    • Buscamos la linea  --jdkhome '"$jdkhome"'
    • Cambiamos por --jdkhome '"/usr/lib/jvm/java-7-openjdk-amd64"'
    • Guardamos
  5. Listo, volvemos a ejecutar nuestro Reporteador con el comando:
    • ./ireport o dando doble click y ejecutar.

jueves, 12 de mayo de 2016

Pop-Up (Ventanas Emergentes) Odoo

Tipos de Ventanas Emergentes en Odoo


Como podemos crear una ventana Emergente en Odoo?

Muchos hemos tenido la necesidad de poder enviar mensajes para validar procesos en Odoo, esto nos ayuda a evitar errores de programación, el buen funcionamiento de nuestra logica de negocio o flujo de funcional, etc., mencionare 3 formas de poder enviar ventas emergentes para el usuario:

  1. Ventana de Advertencia desde metodos onchange. Uno de los tipos de mensajes que podemos enviar al usuario es desde un mƩtodo onchange (Evento al Cambio), esto nos puede ayudar para dar aviso al usuario que al modificar un valor del formulario este afectara el comportamiento de ese Registro, por ejemplo aƱadir un producto sin existencias en un pedido de Venta o una tarifa invalida para ciertos productos.

    El  código para enviar este tipo de mensajes es directamente desde el return de nuestro mĆ©todo onchange, si recordamos este envĆ­a un diccionario, solo debemos aƱadir el atributo 'warning' :
    return {'value': res, 'warning': warning }
    El atributo warning recibe un subdiccionario compuesto de 2 partes, el titulo y el mensaje, el código es el siguiente:
    warning = {
               'title': "Advertencia!",
               'message': "Cuerpo del Mensaje de Advertencia!"),
                                }
    Como nota, este tipo de mensajes no detiene el flujo del proceso que estemos ejecutando, solo  envĆ­a una Advertencia al usuario.
  2. Exception ORM (Excepciones Odoo). Este tipo de advertencias a diferencia de los metodos onchange, interrumpe completamente el flujo del proceso que se este ejecutando y hace una reversión de lo que hayamos creado, actualizado o borrado.
    Para Ejecutar este tipo de Excepcion, debemos importar la librerĆ­a:
    from openerp.exceptions import except_orm
    
    Posterior a importarla solo debemos integrarla en nuestros metodos, para lanzar una excepcion debemos enviarla de la siguiente forma:
    raise except_orm(_('Error'),
                     _('Mensaje interruptor del Flujo!'))
    Este tipo de errores funcionan para validar parÔmetros necesarios para nuestro metodo, falta de datos, información erronea, etc.

  3. Ventana Emergente con mensajes para el Usuario. Este tipo de mensajes nos sirven para dar una aviso al usuario sobre la finalización de un proceso o la modificación de un registro, el uso que le demos no tiene limites y este tipo de mensajes no interrumpen el flujo del sistema.
    Este mensaje se envĆ­a desde el return de la siguiente manera:
    return {
            'type': 'ir.actions.client',
            'tag': 'action_warn',
            'name': _('Aviso'),
            'context' : context,
            'params': {
               'title': _('Aviso'),
               'text': _(u'Mensaje para el usuario'),
               'sticky': True
           }}