Archivo de la categoría: Ajax

PRISM y el problema de las tecnologías “impersonales”

Hay un film que vi hace un tiempo, llamado “21 Blackjack“, inspirado en una historia real (The MIT blackjack team), no solamente habla de unos chicos tratando de estafar en “Las Vegas” y un “anticuado” Laurence Fishburne intentando capturarlos, es la lucha entre la tecnología de reconocimiento de rostro de los Casinos de las Vegas y un Cole Williams (personaje de Laurence Fishburne) que debe demostrar con sus habilidades, que no puede ser reemplazado por “máquinas que leen rostros pero no intenciones”.

El problema de las tecnologías “impersonales” es que no hay inteligencia artificial que pueda detectar “intenciones”, “motivaciones personales” o simplemente, un gusto por comer quinua.

El “Escándaldo PRISM”

No sé cual es el escándalo detrás de PRISM, desde la época de la telefonía digital todas las llamadas desde y hacia USA son filtradas y “grabadas” preventivamente, sólo que la paranoia del 11 de Septiembre y Homeland Security les dió ideas para buscar culpables hasta debajo de las piedras.

Aunque las computadoras aún no saben decir, culpables de qué …

Las Quinuas terroristas

En computación, se conoce como “falso positivo”, cuando un sistema retorna como “problema” algo que no es problema, es normal incluso en sistemas de seguridad, pero ¿qué pasa si quien genera un “falso positivo” es un sistema de vigilancia anti-terrorista?, pues acá las consecuencias.

Una mujer de Nueva York (Michele Catalano), interesada por cómo cocinar lentejas y Quinua, realiza busquedas intensivas en Internet sobre “la mejor olla de presión”, mientras, su esposo busca sobre “morrales y mochilas hechas en casa” y para colmo, su hijo de 20 años de edad, luego del bombardeo de los medios con la portada de la revista “Rolling Stone” sobre Dzhokhar Tsarnaev (el principal el implicado en el atentado de  Boston) se pone a buscar y leer información sobre el atentado terrorista, se imaginarán, Ollas de presión, la vida de Dzhokhar Tsarnaev y mochilas es una combinación explosiva de buscar en Google.

El incidente, un “falso positivo” que parece sacado de la serie “Person of Interest”, causó que una computadora acusara a Catalano y su familia de “posibles criminales terroristas”. Catalano indicó que fuerzas especiales anti-terroristas (que por cierto, no indicaron el organismo) los visitaron “no muy amablemente” para que explicaran su comportamiento sospechoso, además que explicaran “qué rayos es esa cosa llamada Quinua producida en un país como Bolivia”.

Al final del día, el FBI ha “aclarado” que las búsquedas personales no fueron las causantes sino las laborales del esposo de Catalano, sin embargo, lo que queda de este ejemplo es básico, aún no se puede confiar en las computadoras, muchos “falsos positivos” de comportamiento causarán allanamientos como estos y verdaderos actos terroristas quedarán en lo oculto, porque al final del día, ¿qué idiota búsca como hacer una bomba de olla de presión por google? …

[Trac] Instalando SCM Trac en Debian Wheezy y derivados (Ubuntu, Mint, Canaima)

Preámbulo

Un amigo me solicitó la bitácora de instalación de Trac en Debian Wheezy, había tenido algunos detalles utilizando Trac y postgreSQL 9, por lo que decidí publicarla para que más personas pudieran aprovecharla, sin embargo, como el Wiki de GNU de Venezuela no está operativo (donde estaba la versión Squeeze) entonces publicaré toda la guía por acá.

Instalación de Trac

Trac funciona en el modo “instancia”, cada instancia requiere de su propia base de datos y de su propia carpeta (instancia), pero comparten un único punto en el servidor web, aunque Trac utiliza por defecto sqlite para la base de datos, utilizaremos postgreSQL.

La instalación se realiza en una distribución Debian-based pero puede ser realizada en cualquier distribución GNU/Linux que posea python-setuptools y el comando easy_install (o pip).

Instalación de dependencias

  • Instalar las dependencias en Debian Wheezy (o distribución compatible con aptitude | apt-get):
aptitude install apache2 python2.7-setuptools python-genshi python-pybabel python-psycopg2 python2.7-psycopg2 libapache2-mod-wsgi python-babel babel-1.4.0 postgresql-8.4 subversion git mercurial bzr

Nota: si utiliza postgresql-9.1 con Trac < 0.12.2 tendrá que realizar una correción en el código fuente de Trac para poder crear instancias en schemas de postgreSQL 9.

Nota: Si se instala babel posterior a la instalación de Trac, deberá reinstalar trac y actualizar sus instancias.

  • Opcionalmente, podemos actualizar setuptools (requiere conexión a Internet)
easy_install -U setuptools

Instalación de Trac

  • Vía apt-get:
    apt-get install trac trac-bzr trac-git trac-graphviz trac-mercurial trac-odtexport trac-wikiprint
  • ó via easy_install:
easy_install Babel==0.9.5 Genshi==0.6
easy_install Trac
  • También podemos descargar el fuente e instalarlo manualmente:
    wget -c http://ftp.edgewall.com/pub/trac/Trac-0.12.2.tar.gz
    tar xvf Trac-0.12.2.tar.gz
    cd Trac-0.12.2
    python ./setup.py install

Nota: si deseamos instalar (o descargar) la versión de pruebas ejecutamos:

  • Usando easy_install:
easy_install Trac==dev
  • Descargando:
    svn co http://svn.edgewall.org/repos/trac/trunk trac
    cd trac
    python ./setup.py install

Por ultimo, luego de instalado, verificamos que tenemos la última versión:

trac-admin --version

Luego de instalado Trac, procedemos a configurar una instancia.

Configuración de una instancia

Preparación de la DB de postgreSQL

Agregar las siguientes líneas al archivo pg_hba.conf:

archivo: /etc/postgresql/{version}/main/pg_hba.conf

local tracdb tracuser password
host tracdb tracuser 127.0.0.1/32 md5
host tracdb tracuser [subnet]/24 md5
#para poder iniciar sesion en red:
host all all [subnet]/24 md5

Donde [subnet] se reemplaza por la subnet de la red local; ejemplo:

local tracdb tracuser password
host tracdb tracuser 127.0.0.1/32 md5
host tracdb tracuser 192.168.1.0/24 md5
#para poder iniciar sesion en red:
host all all 192.168.1.0/24 md5

Y en postgresql.conf modificamos:

listen_addresses = '*'

Nota: solo necesario si el postgreSQL y el Trac estarán en diferentes equipos.

  • Iniciar una consola y ejecutar:
su postgres
  • E iniciar una consola de postgreSQL:
    >psql
  • En la consola de postgreSQL, crear la DB:
  • Para crear una DB en > 8.4 ejecutar:
    CREATE DATABASE tracdb
      WITH ENCODING='UTF8'
           TEMPLATE=template0
           LC_COLLATE='C'
           LC_CTYPE='C'
           CONNECTION LIMIT=-1;
  • para 8.3 o inferior:
    CREATE DATABASE tracdb 
    WITH ENCODING='UTF8' 
    TEMPLATE=template0 
    LC_COLLATE 'C' 
    LC_CTYPE 'C';
  • Crear el usuario necesario para gestionar la DB:
create user tracuser password 'clavesecreta';
  • Y garantizar los permisos necesarios sobre la DB de trac:
    grant all on database tracdb to tracuser;
  • Salimos del postgresql:
postgres=# \q

Y reiniciamos el postgreSQL:

/etc/init.d/postgresql restart

Ya estamos listos para crear una instancia de Trac.

(Opcional) Preparación de Trac con postgreSQL 9.1

Nota: cambios iniciales para Trac 0.12 y postgreSQL 9.1

Si se intenta crear una instancia de Trac en postgreSQL 9.1 utilizando un schema personalizado (no “public”), Trac devolverá un error por un detalle en el uso de psycopg (la librería python para conectarse a Trac), dicho error se ve así:

Traceback (most recent call last):
  File "/usr/lib/python2.7/dist-packages/trac/admin/console.py", line 422, in do_initenv
    options=options)
  File "/usr/lib/python2.7/dist-packages/trac/env.py", line 213, in __init__
    self.create(options)
  File "/usr/lib/python2.7/dist-packages/trac/env.py", line 401, in create
    DatabaseManager(self).init_db()
  File "/usr/lib/python2.7/dist-packages/trac/db/api.py", line 146, in init_db
    connector.init_db(**args)
  File "/usr/lib/python2.7/dist-packages/trac/db/postgres_backend.py", line 98, in init_db
    params)
  File "/usr/lib/python2.7/dist-packages/trac/db/postgres_backend.py", line 87, in get_connection
    params)
  File "/usr/lib/python2.7/dist-packages/trac/db/postgres_backend.py", line 212, in __init__
    cnx.cursor().execute('SET search_path TO %s', (self.schema,))
DataError: invalid value for parameter "search_path": "weyu"
DETAIL:  schema "weyu" does not exist

Es un error en el archivo /usr/lib/python2.7/dist-packages/trac/db/postgres_backend.py, dicho error ya está corregido en versiones posteriores de Trac y existe un patch para dicho archivo:

  • Parche que está en la incidencia #10406 de Trac:

 http://trac.edgewall.org/attachment/ticket/10406/10406-search-path-r10830.patch

Si desean hacer los cambios ustedes mismos, las líneas a cambiar son:

Línea 34:

34	 	    from psycopg2 import ProgrammingError as PGSchemaError <- eliminar esta
 	34	    from psycopg2 import DataError, ProgrammingError <- agregar esta

Línea 214:

214	 	        except PGSchemaError: <- eliminar esta
 	214	        except (DataError, ProgrammingError): <- agregar esta

Con esta correción podrán crear instancias en postgreSQL 9.1.

Creando un ambiente base (environment Trac)

  • Creamos el árbol de proyectos:
mkdir /srv/{repositorios,trac,proyectos} -p
  • Nos dirigimos a la carpeta de proyectos:
cd /srv/proyectos
  • Inicializamos la primera instancia de trac (se llamará documentacion)
trac-admin /srv/proyectos/documentacion initenv
  • Se inicia un script que realliza una serie de preguntas:
Project Name [My Project]> Documentacion GNU/Linux
  • Conexión a la DB:
Database connection string [sqlite:db/trac.db]>
  • forma del database connection string
    ''{database}://{usuario}:{contraseña}@{host}:{port}/{database}?schema={schema}''

Ejemplo:

postgres://tracuser:clavesecreta@localhost:5432/tracdb?schema=documentacion

Nota: de usar el schema “public”, simplemente no pasar la opcion schema: ejemplo:

postgres://tracuser:clavesecreta@localhost/tracdb
  • Si deseamos usar unix-sockets:

postgres://user:pass@/dbname?host=/path/to/unix/socket/dir&schema=schemaname

Ejemplo:

postgres://tracuser:clavesecreta@/tracdb?host=/var/run/postgresql/.s.PGSQL.5432/dir&schema=documentacion

— Al terminar la configuración de trac, podemos iniciar las pruebas:

  • ejecutamos:

tracd –port 8000 /srv/proyectos/documentacion

Y apuntamos nuestro navegador a:

 http://host:8000/documentacion

Luego de chequeado, procedemos a configurar nuestra instancia de Trac.

Configuración de Apache y Trac

Debemos crear un ambiente web (www) con WSGI del Trac para apache, para ello desplegamos en la carpeta web (/srv/trac/www’) el sitio web:

trac-admin /srv/proyectos/weyu deploy /srv/trac/www/

Creamos el virtualHost para multiples proyectos de trac, creamos un archivo en:

/etc/apache2/sites-availables/trac.site

<VirtualHost *:80>
# administrador del servidor
ServerAdmin jesuslara@DOMINIO
# nombre del vhost
ServerName proyectos.DOMINIO
# alias del servidor
ServerAlias trac.DOMINIO
DocumentRoot /srv/trac/www/htdocs/

        <Directory />
                Options FollowSymLinks
                AllowOverride None
        </Directory>

WSGIScriptAlias / /srv/trac/www/cgi-bin/trac.wsgi

    <Directory /srv/trac/www>
        WSGIApplicationGroup %{GLOBAL}
        SetEnv trac.env_parent_dir /srv/proyectos
        Order deny,allow
        Allow from all
    </Directory>

    ErrorLog /srv/trac/www/log/apache-error.log
    CustomLog /srv/trac/www/log/access.log combined

</VirtualHost>
  • Creamos el directorio para los logs de apache:
mkdir /srv/trac/www/log && chown www-data.www-data /srv/trac/www/ -R
  • Modificamos el archivo trac.wsgi /srv/trac/www/cgi-bin/trac.wsgi:

Este queda:

#!/usr/bin/python
# -*- coding: utf-8 -*-

import sys
sys.stdout = sys.stderr

import os
import trac.db.postgres_backend
trac.db.postgres_backend.PostgreSQLConnection.poolable = False

os.environ['TRAC_ENV_PARENT_DIR'] = '/srv/proyectos/'

def application(environ, start_request):
    if not 'trac.env_parent_dir' in environ:
        environ.setdefault('trac.env_path', '/srv/proyectos/documentacion')
    if 'PYTHON_EGG_CACHE' in environ:
        os.environ['PYTHON_EGG_CACHE'] = environ['PYTHON_EGG_CACHE']
    elif 'trac.env_path' in environ:
        os.environ['PYTHON_EGG_CACHE'] = \
            os.path.join(environ['trac.env_path'], '.egg-cache')
    elif 'trac.env_parent_dir' in environ:
        os.environ['PYTHON_EGG_CACHE'] = \
            os.path.join(environ['trac.env_parent_dir'], '.egg-cache')
    from trac.web.main import dispatch_request
    return dispatch_request(environ, start_request)

Apache debe acceder al directorio de proyectos:

chown www-data.www-data /srv/proyectos -R
  • Y al directorio trac/htdocs:
chown www-data.www-data /srv/trac -R
  • Reiniciamos apache:
/etc/init.d/apache2 restart
  • Y ya podemos acceder a nuestra instancia vía la ruta del  virtualhost:

 http://host/documentacion

Quedando el directorio así:

.
|-- proyectos
|   `-- documentacion
|       |-- attachments
|       |-- conf
|       |-- htdocs
|       |-- log
|       |-- plugins
|       `-- templates
|-- repositorio
|   `-- documentacion
`-- trac
    `-- www
        |-- cgi-bin
        |-- htdocs
        |   |-- common
        |   |   |-- css
        |   |   |-- guide
        |   |   `-- js
        |   `-- site
        `-- log

(opcional) Configuración de múltiples ambientes (instancias)

Aunque se puede crear una base de datos para cada instancia, utilizaremos una única base de datos postgreSQL y schemas por cada instancia de Trac.

  • Inicializamos una nueva instancia:
trac-admin /srv/proyectos/lyx-book/ initenv
  • Configuramos la instancia:
Project Name [My Project]> Lyx Book

Database connection string [sqlite:db/trac.db]> postgres://tracuser:clavesecreta@localhost:5432/tracdb?schema=lyx
  • Propietario www-data a la carpeta del proyecto:
chown www-data.www-data /srv/proyectos -R
  • reiniciamos apache:
/etc/init.d/apache2 restart
  • Y ya podemos ver la nueva instancia en la lista de instancias:
  • al acceder al vhost, veremos la lista de instancias:

 http://host/

— Lista de instancias:

—————————————-

Available Projects

—————————————-

Autenticación inicial del Trac

La autenticación inicial se realizará vía htpasswd (en próximo artículo, agregaré la autenticación openldap).

  • Agregamos un usuario de sistema, para administrar el trac
useradd administrador
  • Creamos el archivo inicial para autenticar los usuarios con Trac
htpasswd -c /srv/trac/www/.htpasswd administrador
  • nota: inicialmente autenticamos con el usuario administrador, con la contraseña que le asignemos.
  • Y agregamos la entrada de autenticación al vhost del trac:
        <Location />
                AuthType Basic
                AuthName "Trac"
                AuthUserFile /srv/trac/www/.htpasswd
                Require valid-user
        </Location>
  • Luego, agregamos la info de autenticación via HTPASSWD al archivo de configuración de la instancia:
  • nota: el archivo de configuración de la instancia está en /srv/proyectos/{instancia}/conf/trac.ini, ejemplo:

archivo: /srv/proyectos/documentacion/conf/trac.ini

  • Agregamos la autenticación vía htpasswd:
[account-manager]
account_changes_notify_addresses =
password_file = /srv/trac/www/.htpasswd
password_format = htpasswd
password_store = HtPasswdStore
  • Le damos privilegios de TRAC_ADMIN al usuario administrador:
trac-admin /srv/proyectos/documentacion
  • Aparece la consola de la instancia de Trac:
-
Welcome to trac-admin 0.12.2
Interactive Trac administration console.
Copyright (C) 2003-2011 Edgewall Software

Type:  '?' or 'help' for help on commands.

Trac [/srv/proyectos/documentacion]>
  • Y en la consola ejecutamos el siguiente comando:
permission add administrador TRAC_ADMIN
  • Salimos de la consola:
>exit
  • Ejecutamos el upgrade de la instancia:
trac-admin /srv/proyectos/weyu upgrade
  • Y reiniciamos apache:
/etc/init.d/apache2 restart

Y ya podemos entrar al trac como el usuario administrador:

 http://host/documentacion/admin/

Ahora podemos personalizar ciertas opciones como incorporar plugins o agregar temas.

Incorporar un Tema a Trac

Para incorporar un tema a Trac, se debe primeramente incorporar el  http://trac-hacks.org/wiki/ThemeEnginePlugin Theme Engine Plugin

Instalación del Theme Engine Plugin

  • Descargamos el gestor de temas:
svn co http://trac-hacks.org/svn/themeengineplugin/0.11/ theme-engine
  • compilamos e instalamos:
cd theme-engine
python setup.py install
  • Habilitamos el theme engine plugin en el archivo conf/trac.ini
[components]
themeengine.* = enabled
  • Y reiniciamos el apache:
    /etc/init.d/apache2 restart

Ya podemos instalar un nuevo tema.

Instalar un Tema

  • Descargamos el tema que necesitamos:
svn co http://trac-hacks.org/svn/pydotorgtheme/0.11/ pydotorgtheme
  • Habilitamos el tema como plugin en el archivo conf/trac.ini
  • Se agregan a la sección ![components] del archivo trac.ini:
    pydotorgtheme.* = enabled
  • Habilitamos el tema en la sección ![theme] del archivo conf/trac.ini
[theme]
theme = PyDotOrg
  • Reiniciamos apache:
/etc/init.d/apache2 restart

Y ya contamos con un nuevo tema instalado.

Instalando un plugin de Trac

Para instalar un plugin de trac por la vía de la descarga, primero, ubicamos y descargamos la fuente;

  • Descargamos, el plugin de Mercurial
svn co http://svn.edgewall.com/repos/trac/plugins/0.12/mercurial-plugin
  • Nos movemos a la carpeta:
    cd mercurial-plugin
  • Ejecutamos la instalación del plugin:
python setup.py install
  • Y luego incorporamos dicho plugin al ‘conf/trac.ini’
[components]
tracext.hg.backend.*
  • Nota: podremos saber el nombre del componente a agregar en el archivo “setup.py > packages”.

Algunos plugins solicitarán actualizar (upgrade) de la instancia, para ello:

  • Ejecutamos en una cónsola:
trac-admin /srv/proyectos/documentacion upgrade
  • Y reiniciamos apache:
    /etc/init.d/apache2 restart

Configuración de repositorios

La configuración de repositorios (directorios donde se almacena código fuente versionado gracias a un VCS) depende de cada software de VCS utilizado, por defecto Trac gestiona Subversion, pero puede habilitarse para otros VCS.

Subversion

  • Instalamos subversion
aptitude install subversion libapache2-svn
  • Creamos la carpeta para el proyecto que deseamos versionar:
mkdir /srv/repositorio/proyecto-svn
  • Creamos el ambiente del proyecto SVN:
svnadmin create /srv/repositorio/proyecto-svn
  • Y le damos privilegio a apache para leerlo:
chown www-data.www-data /srv/repositorio -R
  • Entramos en el environment del trac:
trac-admin /srv/proyectos/documentacion
  • Agregamos el repositorio:
repository add proyecto-svn /srv/repositorio/proyecto-svn svn
  • nota: la sintaxis es: repository add {nombre} {ruta} {tipo}
  • Y ejecutamos la sincronización:
Trac> repository resync proyecto-svn 

Resyncing repository history for proyecto-svn ... 
0 revisions cached. 
Done.
  • Podemos ejecutar la resincronización de todos los repositorios existentes ejecutando:
repository resync '*'

Mercurial (Hg)

  • Instalamos el soporte a mercurial en nuestra distribución:
aptitude install mercurial
  • Descargamos el plugin
svn co http://svn.edgewall.com/repos/trac/plugins/0.12/mercurial-plugin
  • E instalamos el plugin de mercurial:
    cd mercurial-plugin
    python setup.py install
  • Configuramos el plugin de mercurial (hg) en el trac.ini
[components]
tracext.hg.backend.*
  • agregamos la configuración del plugin mercurial
    [hg]
    # -- Show revision number in addition to the changeset hash (defaults to yes)
    show_rev = yes
    # -- Changeset hash format
    node_format = short
  • Reiniciamos el environment de trac y apache:
trac-admin /srv/proyectos/documentacion upgrade && /etc/init.d/apache2 restart

Y ya tenemos configurado el soporte para Mercurial en Trac, ahora procedemos a agregar un repositorio:

  • Para agregar un repositorio Hg (Mercurial) creamos:
mkdir /srv/repositorio/hg/gnu
  • Nos movemos al directorio:
cd /srv/repositorio/hg/gnu/
  • Iniciamos Mercurial en la carpeta
    hg init
  • Y actualizamos:
    hg update
    0 files updated, 0 files merged, 0 files removed, 0 files unresolved
  • Entramos en el environment del trac:
trac-admin /srv/proyectos/documentacion
  • Agregamos el repositorio:
>repository add gnu-hg /srv/repositorio/hg/gnu hg
  • Y ejecutamos la re-sincronización:
    Trac [/srv/proyectos/documentacion]> repository resync gnu-hg
    Resyncing repository history for gnu... 
    0 revisions cached.
    Done.

GIT

Configurando Git

  • Instalamos lo necesario para git:
    aptitude install git git-core git-daemon-run
  • instalamos el plugin de GIT
    easy_install http://github.com/hvr/trac-git-plugin/tarball/master
  • Reiniciamos apache:
    /etc/init.d/apache2 restart
  • Agregamos la sección GIT al trac.ini
    [git]
    cached_repository = false
    persistent_cache = false
    shortrev_len = 7
    wiki_shortrev_len = 7
    git_bin = /usr/bin/git
    trac_user_rlookup = true
    use_committer_id = false
    use_committer_time = false
  • Y habilitamos el plugin (trac.ini)
    [components]
    tracext.git.* = enabled
  • Tambien agregamos la posibilidad de tener GIT post-commit hooks:
    [components]
    tracopt.ticket.commit_updater.committicketreferencemacro = enabled
    tracopt.ticket.commit_updater.committicketupdater = enabled
  • Y cambiamos esto (en el trac.ini):
    repository_sync_per_request = (default)

    — por esto:

    repository_sync_per_request =

Ya configurado GIT, creamos un repositorio.

Creación de un repositorio GIT

  • Creamos la carpeta:
mkdir /srv/repositorios/lyx-book
  • La convertimos en un repositorio git vacio:
    git --bare init
  • Nota: el directorio debe ser de tipo “bare”, ya que Trac debe tener acceso a los archivos de control (HEAD y config) de GIT y no solo el directorio .git/
  • Incorporamos los archivos necesarios, ejecutamos su adhesión al GIT:
    git add .
  • Ejecutamos el primer commit del repositorio:
    git commit -a -m 'first commit'
  • Verificamos su estado:
    git status
    # On branch master
    nothing to commit (working directory clean)
  • Cargamos la consola de la instancia:
    trac-admin /srv/proyectos/documentacion
    
    Welcome to trac-admin 0.12.2
    Interactive Trac administration console.
    Copyright (C) 2003-2011 Edgewall Software
    
    Type:  '?' or 'help' for help on commands.
    
    Trac [/srv/proyectos/documentacion]>
  • Incorporamos el repositorio:
repository add lyx-book /srv/repositorio/lyx-book git
  • Ejecutamos la sincronización:
    repository resync lyx-book

Conclusiones

Trac es una excelente herramienta  de SCM (Source Code Management) ya que combina Wiki, Gestión de incidencias (ticket, bug-tracking), gestión de código VCS y se le pueden incorporar plugins de terceros que incluyen desde un foro hasta un blog.

Jquery UI: usando draggables y droppables

En algún momento te haz preguntado; ¿Como obtengo el objeto, que estoy arrastrando con el ratón usando jquery.ui?; la pregunta es facil de responder y trataremos de explicar algunas cosas sobre draggables y dropables para entender mejor.

El concepto para comenzar a utilizar ui.draggables y ui.droppables es sencillo; simplemente creen un par de DIV (de ejemplo); cada uno con un nombre distinto (pueden, opcionalmente, agregarle el classname “draggable” o “droppable” para llegarle por selectores CSS como siempre se puede en jquery) y posicionenlos en cualquier area separada de pantalla (sea usando position: absolute o porque los han colocado dentro de tablas o celdas separadas).

Ahora viene la magia! detrás de jquery: para arrastrar simplemente declaren al DIV1 draggable:

$(“#dragged”).draggable();

Opcionalmente, pueden decirle al objeto draggable que genere un “clon”; esto es, que cuando se inicia el arrastre del objeto; no se arrastra al DIV1, sino a un “clon” del DIV1.

$(“#dragged”).draggable({
helper: ‘clone’
});

Posteriormente viene la declaración del DIV2, en este caso un contenedor de objetos “arrastrados” (droppable); igual que el anterior, podemos indicar que es droppable:

$(“#dropped”).droppable();

Claro, en este caso podemos contar con ciertas opciones para restringir o personalizar nuestro “droppable”:

accept: “.draggable”, : nos permite indicar que tipo de objeto (referencia a un id o selector) aceptará este droppable

activeClass: ‘droppable-active’, :cuando el droppable tenga dentro de si un “draggable”, cambiará su CSS a este estilo

hoverClass: ‘droppable-hover’, : cuando pasamos por encima (mouseover) el objeto draggable, esta será el estilo CSS aplicado

tolerance: ‘fit’ :tipo de tolerancia con los draggables, puede ser “fit”, si caen completo dentro del droppable, “intersect”, si los bordes del droppable y el draggable se intersectan.

Además, droppable posee una serie de “eventos” que pueden ser funciones callback que ocurren cuando un draggable los libera.

ejemplos:

drop: function(ev, ui) { //ocurre cuando el draggable cae dentro del droppable
},

activate: function(ev, ui) { //ocurre cuando el draggable se activa (comienza a ser arrastrado)
},

deactivate: function(ev, ui) { //ocurre cuando el draggable deja de ser arrastrado
},

como todo evento de droppable, posee 1 referencia implicita y dos parámetros; la referencia implicita es al objeto “this”; que se refiere al objeto droppable;

$(this).append(“”);

o sin necesidad de jquery: var iddrop = this.id;

y ev, que se refiere al gestor de eventos (al DOM Event de la página actual).

con EV podemos obtener ejemplo, las coordenadas de donde ha estado el draggable:

ev.ClientX / evClientY

ahora, quien es ui?, con ese nombre tan críptico, uno no sabe lo que es.

Pues bueno, siguiendo la regla de John Resig (primeras opciones, parámetros, segundas, propiedades, ultimas, callbacks); ese ui debe ser un objeto o una propiedad de droppable; en este caso, UI retorna una referencia al objeto arrastrado (es decir al draggable).

ej.

var id = ui.draggable.element.id;

o

$(ui.draggable.element).

Con lo cual podemos extraer toda la información que necesitemos del elemento que fue arrastrado.

El bloque de código que usé para pruebas fue el siguiente:


$(document).ready(function(){
$("#dragged").draggable({
helper: 'clone'
});
$("#dropped").droppable({
accept: ".draggable",
activeClass: 'droppable-active',
hoverClass: 'droppable-hover',
drop: function(ev, ui) {
//alert(ev.clientX);
$(this).append("<br>Dropped!");
},
deactivate: function(ev, ui) {
alert(ui.draggable.element.id);
$(this).append($(document.createElement('div')).text('deactivate'));
},
tolerance: 'fit'
});
});

Un embuste 2.0

Tal vez algunos de ustedes recibieron un correo que decia algo como:

Tienes que echarle un ojo a mi nuevo vicio.
Estoy tan seguro de que te va a gustar que te he registrado…sólo falta tu confirmación!

http://us1.badoo.com/phenobarbital/in/104063

Ya me cuentas! 😉

Jesus Lara

Esta invitación ha sido enviada con fecha 7/05/07 21:57 a Perico de los palotes <pericopalotes@gmail.com > a petición de Jesus Lara <jesuslarag@gmail.com>.
Si no deseas recibir más mails nuestros, haz clic aquí.

Apenado, les explicaré la situación:

Una "amiga" me comentó de una interesante aplicación web 2.0 para redes sociales que apuntala mucha de su interfaz gráfica a AJAX, de manera interesante y por gran curiosidad decido inscribirme y probar su aplicación; se llama "badoo.com" y es supuestamente una comunidad virtual de perfiles de usuario para que cada quien se describa y diga como es …

Aqui viene lo interesante, la aplicación (como muchas otras, hi5, etc) solicita un mail para que "invites" a tus "amigos" a la nueva comunidad, a diferencia de otros scripts de este tipo donde te presentan la lista de direcciones y tu decides a quien invitar; los seres inventores de esta aplicación se les ocurrió hacerlo de manera automática!, es decir, tomar tooodas mis 500 direcciones y como buen spam, hacerselas llegar a mis jefes, colegas, mi madre, mi hermano en europa, a la infanta helena y como no, a perico de los palotes.

Sin permiso de mi parte (no hay licencia legal que lo permita) convierten mi dirección en un fuerte emisor de spam publicitario de su comunidad y para colmo, al parecer lo venden a otras listas!, porque mi spam se ha mulplicado por 10 desde que estoy suscrito a ellos.

Para colmo de males, estética y de interface estan gachos, interfaces poco intuitivas y javascripts de gran peso hacen dificil la aplicación incluso en un core duo (el exceso de ajax es malo, siempre); no hay muchos botones y a veces no hay forma de conseguir como hacer las cosas.

Para peor colmo, al igual que match y otras comunidades deshonestas, el 70% de los lindos y hermosos cuerpos que se ven en los perfiles son falsos; en una revisión rápida me encontré con cientos de perfiles donde los datos eran falsos (extraidos de gmail o de algunas comunidades vecinas como hi5) y las fotos eran afamadas actrices porno.

O sea, gracias a Dios y estoy en Linux, porque si hubiera estado en winDOS, capaz y hasta me instalan un troyano …

Todo sea por tener 6 millones de usuarios, asi sean falsos … xD

Recompilando PHP y usando JSON

Hace 2 dias recompilé PHP para activar un par de extensiones, entre ellas la tidy html (para limpieza de código html) y la JSON (javascript Serialize Object Notation) para intercambiar (mas que todo objetos) entre el cliente web y el servidor; sin embargo, para mi sorpresa hoy (mejor dicho, ayer a mediados de la tarde) han liberado PHP 5.2.0, que trae a tidy y a json incluidos *by default* con lo cual decidí hacer un upgrade a mi estación de trabajo (este servidor seguirá el ejemplo que el portatil dió en un par de días luego de las pruebas de rigor).

Lo que puedo asegurar luego de las pruebas es que tanto la ampliación de javascript para JSON como la extensión de PHP para JSON son la mar de sencillas de utilizar; en el primer caso con simplemente hacer var sjson = oExample.toJSONString(); entonces contamos con que cualquier string, objeto u array será convertido a la notación JSON:
ej javascript:

var oExample = new Object();
oExample.id = 10;
oExample.className = 20;
oExample.position = 30;
oExample.value = “Jesus”;
oExample.newValue = “Lara”;

es llevado a la forma:
{“id”:10,”className”:20,”position”:30,”value”:”Jesus”,”newValue”:”Lara”}

La cual puede ser enviada facilmente a través de AJAX usando POST.
Del lado del servidor, podemos contar con algo parecido y es que podemos tomar los datos recibidos y con $obj = json_decode($json); obtendremos un objeto con todas las mismas propiedades del objeto javascript, es decir $obj->value o $obj->className.

Pero eso no queda allí, si tomamos cualquier clase y creamos un objeto:

ej php:
class objeto {
public $id = 10;
public $className = 20;
public $position = 30;
public $value = ‘Jesus’;
public $newValue = ‘Lara’;
}
$obj = new objeto();

podemos entonces con $strjson = json_encode($obj); obtener la misma version serializada pero ahora para javascript de un objeto PHP, podemos serializar casi cualquier cosa, exceptuando recursos (como datastreams o conexiones a bases de datos), haciendolo mucho más flexible y potente que las soluciones ajax basadas en XML.

Por cierto, el unico punto en contra a JSON es que no es tan “Human readable” como XML, pero al final de cuentas, tanto JSON como XML son strings para alimentar aplicaciones AJAX y no van a ser vistos por ojos humanos, asi que que importa si el string de JSON es mas complejo (aunque mas compacto) que el XML si nunca lo vamos a ver de frente? …

por cierto, y para terminar, el objeto php serializado que hemos recibido lo podemos devolver a una forma javascript con la siguiente linea de codigo:

var oExample = a.parseJSON();
document.getElementById(“resultado”).innerHTML = oExample.value+’ ‘+oExample.newValue;

Con lo cual como observan, contamos con la flexibilidad de enviar objetos sumamente complejos y grandes cantidades de datos en un solo y unico string sin tener que estar haciendo parsing de una estructura xml (que de por si es bastante engorroso andar pensando en childNodes y getElementsByTagName cuando podemos tener todo en un objeto, DOM queda para otras situaciones).

Les contaré de mis progresos por esta via …

A %d blogueros les gusta esto: