Permalink
Browse files

Spanish: Updated Ch. 00, 02 and 14 to 5th edition

  • Loading branch information...
1 parent e8e9f7a commit d616275fdeb9332bfa57265cf8a45d47b7f657e5 @spametki spametki committed Mar 28, 2013
@@ -1,18 +1,26 @@
-``web2py`` fué lanzado en 2007 y ahora, después de cuatro años de continuo desarrollo, hemos llegado a una muy necesaria cuarta edición del libro. Durante este tiempo, ``web2py`` ha logrado la atención de miles de usuarios y más de 100 desarrolladores. Nuestro esfuerzo colectivo ha creado uno de los más completos marcos de desarrollo "de código libre" en existencia.
+Creo que la habilidad para crear fácilmente aplicaciones web de alta calidad es de una importancia crítica para el desarrollo de una sociedad abierta y libre. Esto evita que los jugadores más pesados puedan monopolizar la libre circulación de la información.
-Originalmente empecé ``web2py`` como una herramienta para enseñar. Creo que la habilidad para construir aplicaciones web de alta calidad es de crítica importancia en una sociedad cada vez más libre y abierta. Previene que los grandes "jugadores" monopolicen el caudal de información. Esta motivación continúa siendo válida y es mucho más importante hoy en día.
-En general, el propósito de cualquier marco de desarrollo orientado a la web, es hacer el desarrollo de manera fácil, rápida y ayudar al desarrollador para que no cometa equivocaciones, especialmente en materia relacionada a la seguridad. En ``web2py`` abordamos estos inconvenientes con nuestras tres metas principales:
+Por esa razón, comencé el proyecto ``web2py`` en 2007, inicialmente como herramienta de aprendizaje con el fin de facilitar el desarrollo web, para que fuera más rápido y más seguro. Con el tiempo, se ha ganado el afecto de miles de usuarios idóneos, y de cientos de desarrolladores. Nuestro esfuerzo colectivo ha creado uno de los marcos de desarrollo de código abierto más completo para el desarrollo web empresarial.
-''Fácil uso'': es la meta primaria de ``web2py``. Para nosotros, esto significa reducir el tiempo de desarrollo y aprendizaje. Esto explica por qué ``web2py`` es un entorno de desarrollo completo y sin dependencias. No requiere instalación y no tiene archivos de configuración. Todo funciona instantáneamente, incluyendo un servidor web, una base de datos y un IDE entorno de desarrollo basado en web, que da acceso a todas las funciones. La API incluye 12 objetos principales, que son fáciles de utilizar y memorizar. También puede interoperar con la mayoría de los servidores web, bases de datos y todas las librerías de Python.
-''Rápido'': la rapidez en el desarrollo es nuestra segunda meta. Cada función en ``web2py`` tiene un comportamiento por defecto (que puede ser modificado). Por ejemplo, tan pronto como hayas especificado tu modelo de datos, vas a tener acceso a un panel de administración de base de datos. ``web2py`` también genera automáticamente formularios para sus datos, y permite exponer dichos datos en HTML, XML, JSON, RSS, etc.
+Como resultado, en 2011, ``web2py`` ganó el Premio Bossie para el Mejor Sofware de Desarrollo de Código Abierto, y en el 2012 ganó el Premio Anual a las Mejores Tecnologías de InfoWorld.
-''Seguridad'': está en la esencia de ``web2py``, y todas nuestra metas aquí son las de mantener bajo llave su sistema y la información de manera segura. Por ejemplo, nuestra capa de abstracción elimina todo posible ataque de inyección de SQL (''SQL injection''). El lenguaje de plantillas es un factor de prevención contra las vulnerabilidades ''Cross Site Scripting''. Los formularios generados por ``web2py`` proveen validación de los campos y protegen de los ataques ''Cross Site Request Forgery''. Las contraseñas y claves siempre son guardadas de forma encriptada. Las sesiones son por defecto almacenadas y cifradas del lado del servidor para prevenir su manipulación.
-``web2py`` siempre ha sido desarrollado desde la perspectiva del usuario, y es constantemente optimizado para que sea más ágil y rápido, conservando siempre la compatibilidad hacia atras.
+Como verás a lo largo de los capítulos que siguen, ``web2py`` intenta bajar la barrera de ingreso al desarrollo web centrándose en tres metas principales:
-``web2py`` es software libre. Si has obtenido beneficios usándolo, entonces nosotros esperamos que también contribuyas a la sociedad en la forma que creas mejor.
-En 2011 la revista "Infoworld", evaluó seis de los entornos de desarrollo más populares basados en Python, y eligió a web2py como el mejor. También en 2011, web2py ganó el premio ''Bossie'' para el mejor software de desarrollo de código abierto.
+''Fácil uso''. Esto implica reducir el tiempo empleado en aprender y desplegar así como también los costos de desarrollo y mantenimiento. Es por esto que ``web2py`` es un marco completamente integrado y sin dependencias. No requiere de instalación y no tiene archivos de configuración. Todo funciona instantáneamente, incluyendo un servidor web, la base de datos y un entorno de desarrollo para navegador que provee de acceso a las características principales. La API incluye solamente 12 objetos del núcleo, que son fáciles de usar y memorizar. Puede interactual con la mayor parte de los servidores web y bases de datos y con todas librerías de Python.
+
+
+''Desarrollo ágil''. Cada función de ``web2py`` tiene un comportamiento por defecto (que se puede sobreescribir). Por ejemplo, ni bien hayas especificado tus modelos de datos, tendrás acceso a la interfaz administrativa de la base de datos para navegador. Además, ``web2py`` genera automáticamente los formularios para tus datos y te permite exponer fácilmente los datos en HTML, XML, JSON, RSS, etc. ``web2py`` provee de algunos widget de nivel alto como la wiki y el grid para crear aplicaciones avanzadas rápidamente.
+
+
+''Seguridad''. La Capa de Abstracción de la Base de Datos (DAL) elimina las inyecciones de SQL. El lenguaje de plantillas previene las vulnerabilidades de secuencia de comandos en sitios cruzados o (''Cross Site Scripting''). Los formularios generados por ``web2py`` proveen de validación de campos y bloquean las falsificaciones de solicitud en sitios cruzados (CSRF). Las contraseñas siempre se almacenan codificadas. Las sesiones se almacenan del lado del servidor para prevenir la manipulación de los cookie (''Cookie Tampering''). Los cookie se identifican con UUID para evitar el secuestro de sesiones o ''Session Hijacking''.
+
+
+``web2py`` fue construido pensando en la perspectiva del usuario y es constantemente optimizado internamente para que sea más rápido y ligero, pero siempre conservando la ''compatibilidad hacia atrás''.
+
+
+Puedes usar ``web2py`` en forma gratuita. Si te beneficias usándolo, espero que eso te incentive a ''agradecerlo'' contribuyendo a la sociedad en la forma que tu elijas.
@@ -79,16 +79,7 @@ y, como "1" es un entero, obtenemos una descripción de la clase ``int`` y de to
En forma similar, podemos obtener una lista de métodos del objeto "1" con el comando ``dir``:
``
>>> dir(1)
-['__abs__', '__add__', '__and__', '__class__', '__cmp__', '__coerce__',
-'__delattr__', '__div__', '__divmod__', '__doc__', '__float__',
-'__floordiv__', '__getattribute__', '__getnewargs__', '__hash__', '__hex__',
-'__index__', '__init__', '__int__', '__invert__', '__long__', '__lshift__',
-'__mod__', '__mul__', '__neg__', '__new__', '__nonzero__', '__oct__',
-'__or__', '__pos__', '__pow__', '__radd__', '__rand__', '__rdiv__',
-'__rdivmod__', '__reduce__', '__reduce_ex__', '__repr__', '__rfloordiv__',
-'__rlshift__', '__rmod__', '__rmul__', '__ror__', '__rpow__', '__rrshift__',
-'__rshift__', '__rsub__', '__rtruediv__', '__rxor__', '__setattr__',
-'__str__', '__sub__', '__truediv__', '__xor__']
+['__abs__', ..., '__xor__']
``:code
### Tipos
@@ -520,8 +511,8 @@ BaseException
+-- SyntaxWarning
+-- UserWarning
+-- FutureWarning
- +-- ImportWarning
- +-- UnicodeWarning
+ +-- ImportWarning
+ +-- UnicodeWarning
``:code
Para una descripción detallada de cada una, consulta la documentación oficial de Python.
@@ -745,7 +736,8 @@ He aquí una clase más complicada:
>>> class MiClase(object):
>>> z = 2
>>> def __init__(self, a, b):
->>> self.x = a, self.y = b
+>>> self.x = a
+>>> self.y = b
>>> def sumar(self):
>>> return self.x + self.y + self.z
>>> miinstancia = MiClase(3, 4)
@@ -21,17 +21,160 @@ Aquí explicamos como hacer esto para Windows:
- Crea tu aplicación como usalmente lo haces.
- Usando **admin**, compila tu aplicación(one click)
- Usando **admin**, empaqueta la aplicación compilada(another click)
-- Descomprime esto en la carpeta "myapp" y comienza ahí (two clicks)
+- Descomprime esto en la carpeta "miapp" y comienza ahí (two clicks)
- Carga usando **admin** el anterior paquete de la app compilada con el nombre "init" (one click)
-- Crea un archivo "myapp/start.bat" que contenga "cd web2py; web2py.exe"
-- comprime la carpeta miaplicacion en un archivo "myapp.zip"
-- distribuye y/o vende "myapp.zip"
+- Crea un archivo "miapp/start.bat" que contenga "cd web2py; web2py.exe"
+- comprime la carpeta miaplicacion en un archivo "miapp.zip"
+- distribuye y/o vende "miapp.zip"
-Cuando los usuarios descompriman "myapp.zip" y hagan click "run" ellos verán tu aplicación en lugar de la aplicación "welcome".
+Cuando los usuarios descompriman "miapp.zip" y hagan click "run" ellos verán tu aplicación en lugar de la aplicación "welcome".
No tiene requerimientos del lado del usuario, ni incluso tener python pre-instalado.
Para binarios en Mac el proceso es el mismo pero no hay necesidad de crear el archivo "bat".
+
+### WingIDE, Rad2Py, y Eclipse
+
+``WingIDE``:inxx ``Eclipse``:inxx ``Rad2Py``:inxx
+
+Puedes usar web2py con entornos de desarrollo de terceros como WingIDE, Rad2Py, y Eclipse.
+
+He aquí una captura de pantalla que ilustra el uso de web2py con WingIDE:
+
+[[image @///image/wingide.png center 480px]]
+
+En general, el problema con estos IDE (salvo el caso de Rad2Py que fue diseñado específicamente para que funciones con web2py) es que no entienden el contexto en que los modelos y controladores se ejecutan y por lo tanto la autocompleción no funciona en forma instantánea.
+
+Para que la autocompleción funcione el truco normalmente consiste en editar tus modelos y controladores agregando el siguiente código:
+
+``
+if False:
+ from gluon import *
+ request = current.request
+ response = current.response
+ session = current.session
+ cache = current.cache
+ T = current.T
+``:code
+
+Esto no modifica el funcionamiento ya que nunca se ejecutará pero hace que el IDE lo analice y entienda de dónde vienen los objetos del espacio de nombres global (el módulo ``gluon``), lo que a su vez hace que funcione la autocompleción.
+
+
+### SQLDesigner
+
+Hay un software llamado SQLDesigner que permite la creación de modelos de web2py en forma visual y con esa información se genera el código automáticamente. Aquí se muestra una captura de pantalla:
+
+
+[[image @///image/designer.png center 480px]]
+
+
+La versión de SQLDesigner que funciona con web2py se puede encontrar en:
+
+``https://github.com/elcio/visualdal``
+
+
+### Publicación de una carpeta
+
+Consideremos el problema de compartir carpetas y subcarpetas en la web. web2py lo hace realmente fácil. Sólo debes usar un controlador como el siguiente:
+
+``
+from gluon.tools import Expose
+def micarpeta():
+ return dict(archivos=Expose('/ruta/a/micarpeta'))
+``:code
+
+
+que puedes procesar en una vista con ``{{=archivos}}``. Esto creará una interfaz para visualizar archivos y carpetas, y navegar a través de la estructura de árbol de los archivos. Se crearán vistas previas de las imágenes.
+
+El prefijo con la ruta "/ruta/a/micarpeta" se ocultará a los visitantes. Por ejemplo un archivo llamado "/ruta/a/micarpeta/a/b.txt" se reemplazará por "base/a/b.txt". El prefijo "base" se puede especificar usando el argumento ``basename`` de la función Expose. Puedes especificar una lista de extensiones a listar con el parámetro ``extensions``, el resto de los archivos se ocultará. Por ejemplo:
+
+``
+def micarpeta():
+ return dict(archivos=Expose('/ruta/a/micarpeta', basename='.',
+ extensions=['.py', '.jpg']))
+``:code
+
+
+Los archivos y carpetas que contengan la palabra "private" en la ruta o tengan un nombre de archivo que comience con "." o que termine con "~" siempre se ocultan.
+
+### Pruebas funcionales
+
+web2py viene con un módulo ``gluon.contrib.webclient`` que permite realizar pruebas funcionales (''functional testing'') de aplicaciones locales y remotas de web2py. En realidad, este módulo no es específico de web2py y se puede usar para realizar pruebas e interacción en forma programática con cualquier aplicación web, si bien está preparado para trabajar con sesiones y repuestas de aplicaciones de web2py.
+
+
+He aquí un ejemplo de uso. El programa a continuación crea un cliente, conecta con la acción "index" para establecer una sesión, registra un nuevo usuario, luego cierra la sesión y vuelve a autenticarse usando las nuevas credenciales:
+
+``
+from gluon.contrib.webclient import WebClient
+
+cliente = WebClient('http://127.0.0.1:8000/welcome/default/',
+ postbacks=True)
+
+cliente.get('index')
+# registro
+datos = dict(first_name = 'Homero',
+ last_name = 'Simpson',
+ email = 'homero@web2py.com',
+ password = 'prueba',
+ password_two = 'prueba',
+ _formname = 'register')
+cliente.post('user/register', data=datos)
+
+# cerrar sesión
+cliente.get('user/logout')
+
+# autenticarse nuevamente
+datos = dict(email='homero@web2py.com',
+ password='prueba',
+ _formname = 'login')
+cliente.post('user/login',data=datos)
+
+# comprobar registro y si el acceso fue exitoso
+cliente.get('index')
+assert('Bienvenido Homero' in cliente.text)
+``:code
+
+El constructor de WebClient toma un prefijo URL como argumento. En el ejemplo ese parámetro es "http://127.0.0.1:8000/welcome/default/". No realiza ningún intercambio de datos en la red. El argumento ``postbacks`` es por defecto ``True`` y le indica al cliente cómo debe manejar las respuestas de web2py.
+
+
+El objeto WebClient ``client`` tiene dos métodos:
+``get`` y ``post``. El primer argumento siempre es un postfijo URL.
+El URL completo para una solicitud POST o GET se compone simplemente concatenando el prefijo y el postfijo. El propósito de esto es simplemente hacer que la sintaxis sea más breve para las comunicaciones intensivas entre el cliente y el servidor.
+
+
+``data`` es un parámetro específico de las solicitudes POST que contiene un diccionario de los datos a enviarse. Los formularios de web2py tienen un campo oculto ``_formname`` y su valor se debe especificar cuando existe más de un formulario en la página. Los formularios de web2py también contienen un campo oculto ``_formkey`` que está diseñado para prevenir los ataques CSRF. Este campo es manejado en forma automática por el WebClient.
+
+
+Tanto ``cliente.get`` como ``cliente.post`` aceptan los siguientes argumentos adicionales:
+- ``headers``: un diccionario de encabezados HTTP opcionales.
+- ``cookies``: un diccionario de cookies opcionales HTTP.
+- ``auth``: un diccionario de parámetros que se deben pasar a ``urllib2.HTTPBasicAuthHandler().add_password(**auth)`` para el acceso por el sistema de autenticación básico (''basic authentication''). Para más información acerca de este tema se puede consultar la documentación de Python para el módulo urllib2.
+
+
+El objeto ``client`` en el ejemplo mantiene una conversación con el servidor especificado en el constructor por medio de solicitudes GET y POST. Este maneja automáticamente las cookie y las envía de regreso para actualizar las sesiones. Si detecta que se ha generado una nueva cookie de sesión aunque se esté usando actualmente otra, interpretará que se produjo una falla en la sesión y genera una excepción. Si el servidor devuelve un error HTTP, también generará una excepción. Si, en cambio, el servidor devuelve un error HTTP, pero además la respuesta contiene un ticket de web2py, devolverá una excepción conteniendo el código del ticket.
+
+
+El objeto client mantiene un registro o ''log'' de las solicitudes en ``cliente.history`` y el estado asociado con la última solicitud exitosa.
+El estado se compone de:
+- ``cliente.status``: el código de estado devuelto
+- ``cliente.text``: el contenido de la página
+- ``cliente.headers``: un diccionario de encabezados recuperados
+- ``cliente.cookies``: un diccionario de los cookie recuperados
+- ``cliente.sessions``: un diccionario de sesiones con la forma ``{nombredeapp: id_sesión}``.
+- ``cliente.forms``: un diccionario de formularios web2py detectados en el ``cliente.text``. El diccionario tiene la forma ``{_formname, _formkey}``.
+
+El objeto WebClient no realiza ningún análisis o conversión del contenido del ``cliente.txt`` devuelto por el servidor pero esto se puede hacer fácilmente con alguno de los módulos de terceros como BeautifulSoup. Por ejemplo, aquí se muestra un programa que demuestra cómo se pueden buscar todos los link en una página descargada por el cliente y comprobarlos:
+
+``
+from BeautifulSoup import BeautifulSoup
+dom = BeautifulSoup(cliente.text)
+for link in dom.findAll('a'):
+ nuevo_cliente = WebClient()
+ nuevo_cliente.get(link.href)
+ print nuevo_cliente.status
+``:code
+
+
### Construyendo un web2py minimalista
A veces necesitamos implementar web2py en un servidor con muy poca memoria RAM. En este caso nosotros queremos disminuir web2py a su mínima expresión.
@@ -68,7 +211,7 @@ page = urllib.urlopen('http://www.web2py.com').read()
Esto es usualmente correcto, pero el modulo ``urllib`` no funciona sobre "Google App Engine". Google provee una diferente API para descargar URLs que solamente funciona en GAE. en orden de hacer tu código portable, web2py incluye una función ``fetch`` que funcióna en GAE así mismo en otras instalaciones de Python
``
-from google.tools import fetch
+from gluon.tools import fetch
page = fetch('http://www.web2py.com')
``:code
@@ -134,7 +277,7 @@ def listar_elementos():
Nota que este código selecciona uno o más item de los que necesita, 20+1. el elemento extra dice a la vista si existe la siguiente página.
-Aquí es la vista "default/list_items.html":
+Aquí es la vista "default/listar_elementos.html":
``
{{extend 'layout.html'}}
@@ -152,7 +295,7 @@ Aquí es la vista "default/list_items.html":
{{pass}}
``:code
-En esta manera podemos obtener la paginación con un sólo "select" por acción,y que un "select" sólo obtenga una fila más de lo que necesita.
+De esta manera podemos obtener la paginación con un sólo "select" por acción, y que ese "select" sólo obtenga una fila más de lo que se necesita.
### httpserver.log y el Formato del archivo de bitácora.
``httpserver.log``:inxx
@@ -298,7 +441,7 @@ Una vez que tienes tu llave de la API, puedes aceptar tarjetas de crédito, con
from gluon.contrib.stripe import Stripe
stripe = Stripe(api_key)
d = stripe.charge(amount=100,
- currency='usd',
+ currency='usd',
card_number='4242424242424242',
card_exp_month='5',
card_exp_year='2012',
@@ -312,7 +455,7 @@ elif:
La respuesta, ``d``, es un diccionario que puedes explorar tu mismo. El número de tarjeta usado en el ejemplo es un sandbox y siempre será exitoso. Cada transacción está asociada a un identificador almacenado en ``d['id']``.
-Stripe también permite verificar una transaccion tiempo después:
+Stripe también permite verificar una transaccion en otro momento:
``
d = Stripe(key).check(d['id'])
@@ -325,7 +468,7 @@ r = Stripe(key).refund(d['id'])
if r.get('refunded',False):
# el reembolso se realizó con éxito
elif:
- # error is in d.get('error','unkown')
+ # error is in d.get('error','unknown')
``
Stripe hace sencillo mantener la contabilidad dentro de tu aplicación.
@@ -4,7 +4,7 @@
03: Resúmen
04: El núcleo
05: Las vistas
-06: La capa de abstracción de datos
+06: La capa de abstracción de la base de datos
07: Formularios y validadores
08: Correo y SMS
09: Control de acceso

0 comments on commit d616275

Please sign in to comment.