Compare commits

...
16 Commits
Author SHA1 Message Date
mdipierro 63224e8ce6 2.7.3 2013-10-11 18:10:57 -05:00
mdipierro ff7f9568db fixed validation of nagtive integers, thanks Stefan 2013-10-11 18:06:57 -05:00
mdipierro 3635dd8faf fixed problem with Virtual Fields and grid 2013-10-11 17:59:30 -05:00
mdipierro d5fda056ff simplified logic for number validators 2013-10-11 17:07:17 -05:00
mdipierro d8e8d1d597 fixed problem with IS_INT_IN_RANGE for large numbers 2013-10-11 16:59:05 -05:00
mdipierro 59290534bc fixed issue 1708:gae memcache_contrib does not set the time_expire, thanks Nicholas 2013-10-09 11:58:15 -05:00
mdipierro 8fb0b71be6 fixed compilerapp sorting issue, better 2013-10-09 11:31:33 -05:00
mdipierro ddc0fc9949 fixed compilerapp sorting issue, possibly 2013-10-09 11:15:07 -05:00
mdipierro 5428fdbd04 reverted error commit 2013-10-09 09:07:00 -05:00
Massimo 98f2bfbfb6 Merge branch 'master' of github.com:web2py/web2py 2013-10-08 11:39:30 -05:00
Massimo d780d26cc9 merge heads 2013-10-08 11:38:28 -05:00
mdipierro a5711bd933 Merge pull request #244 from timrichardson/issue/1692
fix for Issue 1692 virtual fields in SQLFORM.grid
2013-10-08 09:35:51 -07:00
mdipierro b96cde2f77 Merge pull request #243 from cccaballero/master
more spanish translations
2013-10-08 09:34:16 -07:00
Tim Richardson a3f3ed1298 fix for Issue 1692 virtual fields in forms 2013-10-08 13:31:36 +11:00
mdipierro 5f34193ac7 fixed demo mode 2013-10-07 09:17:51 -05:00
cccaballero 6fe6852a0c more spanish translations
more spanish translations
2013-10-07 09:49:48 -04:00
9 changed files with 164 additions and 157 deletions
+1 -1
View File
@@ -30,7 +30,7 @@ update:
echo "remember that pymysql was tweaked" echo "remember that pymysql was tweaked"
src: src:
### Use semantic versioning ### Use semantic versioning
echo 'Version 2.7.2-stable+timestamp.'`date +%Y.%m.%d.%H.%M.%S` > VERSION echo 'Version 2.7.3-stable+timestamp.'`date +%Y.%m.%d.%H.%M.%S` > VERSION
### rm -f all junk files ### rm -f all junk files
make clean make clean
### clean up baisc apps ### clean up baisc apps
+1 -1
View File
@@ -1 +1 @@
Version 2.7.2-stable+timestamp.2013.10.07.08.39.32 Version 2.7.3-stable+timestamp.2013.10.11.18.10.01
+64 -64
View File
@@ -7,7 +7,7 @@
'%s %%{row} updated': '%s filas actualizadas', '%s %%{row} updated': '%s filas actualizadas',
'%Y-%m-%d': '%Y-%m-%d', '%Y-%m-%d': '%Y-%m-%d',
'%Y-%m-%d %H:%M:%S': '%Y-%m-%d %H:%M:%S', '%Y-%m-%d %H:%M:%S': '%Y-%m-%d %H:%M:%S',
'(requires internet access, experimental)': '(requires internet access, experimental)', '(requires internet access, experimental)': '(requiere acceso a internet, experimental)',
'(something like "it-it")': '(algo como "it-it")', '(something like "it-it")': '(algo como "it-it")',
'@markmin\x01(file **gluon/contrib/plural_rules/%s.py** is not found)': '(file **gluon/contrib/plural_rules/%s.py** is not found)', '@markmin\x01(file **gluon/contrib/plural_rules/%s.py** is not found)': '(file **gluon/contrib/plural_rules/%s.py** is not found)',
'@markmin\x01An error occured, please [[reload %s]] the page': 'An error occured, please [[reload %s]] the page', '@markmin\x01An error occured, please [[reload %s]] the page': 'An error occured, please [[reload %s]] the page',
@@ -17,16 +17,16 @@
'About': 'acerca de', 'About': 'acerca de',
'About application': 'Acerca de la aplicación', 'About application': 'Acerca de la aplicación',
'additional code for your application': 'código adicional para su aplicación', 'additional code for your application': 'código adicional para su aplicación',
'Additional code for your application': 'Additional code for your application', 'Additional code for your application': 'Código adicional para su aplicación',
'admin disabled because no admin password': ' por falta de contraseña', 'admin disabled because no admin password': 'admin deshabilitado por falta de contraseña',
'admin disabled because not supported on google app engine': 'admin deshabilitado, no es soportado en GAE', 'admin disabled because not supported on google app engine': 'admin deshabilitado, no es soportado en GAE',
'admin disabled because unable to access password file': 'admin deshabilitado, imposible acceder al archivo con la contraseña', 'admin disabled because unable to access password file': 'admin deshabilitado, imposible acceder al archivo con la contraseña',
'Admin is disabled because insecure channel': 'Admin deshabilitado, el canal no es seguro', 'Admin is disabled because insecure channel': 'Admin deshabilitado, el canal no es seguro',
'Admin is disabled because unsecure channel': 'Admin deshabilitado, el canal no es seguro', 'Admin is disabled because unsecure channel': 'Admin deshabilitado, el canal no es seguro',
'Admin language': 'Admin language', 'Admin language': 'Lenguaje de administración',
'administrative interface': 'administrative interface', 'administrative interface': 'interfaz administrativa',
'Administrator Password:': 'Contraseña del Administrador:', 'Administrator Password:': 'Contraseña del Administrador:',
'An error occured, please %s the page': 'An error occured, please %s the page', 'An error occured, please %s the page': 'Ha ocurrido un error, por favor %s la página',
'and rename it (required):': 'y renombrela (requerido):', 'and rename it (required):': 'y renombrela (requerido):',
'and rename it:': ' y renombrelo:', 'and rename it:': ' y renombrelo:',
'appadmin': 'appadmin', 'appadmin': 'appadmin',
@@ -35,7 +35,7 @@
'application %(appname)s installed with md5sum: %(digest)s': 'application %(appname)s installed with md5sum: %(digest)s', 'application %(appname)s installed with md5sum: %(digest)s': 'application %(appname)s installed with md5sum: %(digest)s',
'application compiled': 'aplicación compilada', 'application compiled': 'aplicación compilada',
'application is compiled and cannot be designed': 'la aplicación está compilada y no puede ser modificada', 'application is compiled and cannot be designed': 'la aplicación está compilada y no puede ser modificada',
'Application name:': 'Application name:', 'Application name:': 'Nombre de la aplicación:',
'are not used': 'are not used', 'are not used': 'are not used',
'are not used yet': 'are not used yet', 'are not used yet': 'are not used yet',
'Are you sure you want to delete file "%s"?': '¿Está seguro que desea eliminar el archivo "%s"?', 'Are you sure you want to delete file "%s"?': '¿Está seguro que desea eliminar el archivo "%s"?',
@@ -45,13 +45,13 @@
'Are you sure you want to uninstall application "%s"?': '¿Está seguro que desea desinstalar la aplicación "%s"?', 'Are you sure you want to uninstall application "%s"?': '¿Está seguro que desea desinstalar la aplicación "%s"?',
'Are you sure you want to upgrade web2py now?': '¿Está seguro que desea actualizar web2py ahora?', 'Are you sure you want to upgrade web2py now?': '¿Está seguro que desea actualizar web2py ahora?',
'arguments': 'argumentos', 'arguments': 'argumentos',
'at char %s': 'at char %s', 'at char %s': 'en el caracter %s',
'at line %s': 'at line %s', 'at line %s': 'en la línea %s',
'ATTENTION: Login requires a secure (HTTPS) connection or running on localhost.': 'ATENCION: Inicio de sesión requiere una conexión segura (HTTPS) o localhost.', 'ATTENTION: Login requires a secure (HTTPS) connection or running on localhost.': 'ATENCION: Inicio de sesión requiere una conexión segura (HTTPS) o localhost.',
'ATTENTION: TESTING IS NOT THREAD SAFE SO DO NOT PERFORM MULTIPLE TESTS CONCURRENTLY.': 'ATENCION: NO EJECUTE VARIAS PRUEBAS SIMULTANEAMENTE, NO SON THREAD SAFE.', 'ATTENTION: TESTING IS NOT THREAD SAFE SO DO NOT PERFORM MULTIPLE TESTS CONCURRENTLY.': 'ATENCION: NO EJECUTE VARIAS PRUEBAS SIMULTANEAMENTE, NO SON THREAD SAFE.',
'ATTENTION: you cannot edit the running application!': 'ATENCION: no puede modificar la aplicación que se ejecuta!', 'ATTENTION: you cannot edit the running application!': 'ATENCION: no puede modificar la aplicación que se ejecuta!',
'Autocomplete': 'Autocomplete', 'Autocomplete': 'Autocomplete',
'Autocomplete Python Code': 'Autocomplete Python Code', 'Autocomplete Python Code': 'Autocompletar código Python',
'Available databases and tables': 'Bases de datos y tablas disponibles', 'Available databases and tables': 'Bases de datos y tablas disponibles',
'back': 'atrás', 'back': 'atrás',
'breakpoint': 'breakpoint', 'breakpoint': 'breakpoint',
@@ -59,17 +59,17 @@
'browse': 'buscar', 'browse': 'buscar',
'cache': 'cache', 'cache': 'cache',
'cache, errors and sessions cleaned': 'cache, errores y sesiones eliminados', 'cache, errors and sessions cleaned': 'cache, errores y sesiones eliminados',
'can be a git repo': 'can be a git repo', 'can be a git repo': 'puede ser un repositorio git',
'Cannot be empty': 'No puede estar vacío', 'Cannot be empty': 'No puede estar vacío',
'Cannot compile: there are errors in your app. Debug it, correct errors and try again.': 'No se puede compilar: hay errores en su aplicación. Depure, corrija errores y vuelva a intentarlo.', 'Cannot compile: there are errors in your app. Debug it, correct errors and try again.': 'No se puede compilar: hay errores en su aplicación. Depure, corrija errores y vuelva a intentarlo.',
'Cannot compile: there are errors in your app:': 'No se puede compilar: hay errores en su aplicación:', 'Cannot compile: there are errors in your app:': 'No se puede compilar: hay errores en su aplicación:',
'cannot create file': 'no es posible crear archivo', 'cannot create file': 'no es posible crear archivo',
'cannot upload file "%(filename)s"': 'no es posible subir archivo "%(filename)s"', 'cannot upload file "%(filename)s"': 'no es posible subir archivo "%(filename)s"',
'Change admin password': 'cambie contraseña admin', 'Change admin password': 'cambie contraseña admin',
'change editor settings': 'change editor settings', 'change editor settings': 'cambiar la configuración del editor',
'Change Password': 'Cambie Contraseña', 'Change Password': 'Cambie Contraseña',
'check all': 'marcar todos', 'check all': 'marcar todos',
'Check for upgrades': 'Check for upgrades', 'Check for upgrades': 'buscar actualizaciones',
'Check to delete': 'Marque para eliminar', 'Check to delete': 'Marque para eliminar',
'Checking for upgrades...': 'Buscando actulizaciones...', 'Checking for upgrades...': 'Buscando actulizaciones...',
'Clean': 'limpiar', 'Clean': 'limpiar',
@@ -77,21 +77,21 @@
'click here for the administrative interface': 'haga clic aquí para usar la interfaz administrativa', 'click here for the administrative interface': 'haga clic aquí para usar la interfaz administrativa',
'Click row to expand traceback': 'Click row to expand traceback', 'Click row to expand traceback': 'Click row to expand traceback',
'click to check for upgrades': 'haga clic para buscar actualizaciones', 'click to check for upgrades': 'haga clic para buscar actualizaciones',
'click to open': 'click to open', 'click to open': 'click para abrir',
'Client IP': 'IP del Cliente', 'Client IP': 'IP del Cliente',
'code': 'código', 'code': 'código',
'Code listing': 'Code listing', 'Code listing': 'Listado de código',
'collapse/expand all': 'collapse/expand all', 'collapse/expand all': 'contraer/expandir todo',
'commit (mercurial)': 'commit (mercurial)', 'commit (mercurial)': 'confirmar (mercurial)',
'Compile': 'compilar', 'Compile': 'compilar',
'compiled application removed': 'aplicación compilada removida', 'compiled application removed': 'aplicación compilada removida',
'continue': 'continue', 'continue': 'continuar',
'Controllers': 'Controladores', 'Controllers': 'Controladores',
'controllers': 'controladores', 'controllers': 'controladores',
'Count': 'Count', 'Count': 'Count',
'Create': 'crear', 'Create': 'Crear',
'create file with filename:': 'cree archivo con nombre:', 'create file with filename:': 'cree archivo con nombre:',
'Create new application using the Wizard': 'Create new application using the Wizard', 'Create new application using the Wizard': 'Crear nueva aplicación utilizando el asistente',
'create new application:': 'nombre de la nueva aplicación:', 'create new application:': 'nombre de la nueva aplicación:',
'Create new simple application': 'Cree una nueva aplicación', 'Create new simple application': 'Cree una nueva aplicación',
'Create/Upload': 'Create/Upload', 'Create/Upload': 'Create/Upload',
@@ -115,25 +115,25 @@
'delete': 'eliminar', 'delete': 'eliminar',
'delete all checked': 'eliminar marcados', 'delete all checked': 'eliminar marcados',
'delete plugin': 'eliminar plugin', 'delete plugin': 'eliminar plugin',
'Delete this file (you will be asked to confirm deletion)': 'Delete this file (you will be asked to confirm deletion)', 'Delete this file (you will be asked to confirm deletion)': 'Elimine este fichero (se le pedirá confirmación)',
'Delete:': 'Elimine:', 'Delete:': 'Elimine:',
'Deploy': 'Deploy', 'Deploy': 'Deploy',
'Deploy on Google App Engine': 'Instale en Google App Engine', 'Deploy on Google App Engine': 'Instale en Google App Engine',
'Deploy to OpenShift': 'Deploy to OpenShift', 'Deploy to OpenShift': 'Instale en OpenShift',
'Description': 'Descripción', 'Description': 'Descripción',
'design': 'modificar', 'design': 'modificar',
'DESIGN': 'DISEÑO', 'DESIGN': 'DISEÑO',
'Design for': 'Diseño para', 'Design for': 'Diseño para',
'Detailed traceback description': 'Detailed traceback description', 'Detailed traceback description': 'Detailed traceback description',
'details': 'details', 'details': 'detalles',
'direction: ltr': 'direction: ltr', 'direction: ltr': 'direction: ltr',
'Disable': 'Disable', 'Disable': 'Deshabilitar',
'docs': 'docs', 'docs': 'docs',
'done!': 'listo!', 'done!': 'listo!',
'Download': 'Download', 'Download': 'Descargar',
'download files via http:': 'download files via http:', 'download files via http:': 'descargar archivos via http:',
'download layouts': 'download layouts', 'download layouts': 'descargar layouts',
'download plugins': 'download plugins', 'download plugins': 'descargar plugins',
'E-mail': 'Correo electrónico', 'E-mail': 'Correo electrónico',
'EDIT': 'EDITAR', 'EDIT': 'EDITAR',
'Edit': 'editar', 'Edit': 'editar',
@@ -160,7 +160,7 @@
'Expand Abbreviation': 'Expand Abbreviation', 'Expand Abbreviation': 'Expand Abbreviation',
'export as csv file': 'exportar como archivo CSV', 'export as csv file': 'exportar como archivo CSV',
'exposes': 'expone', 'exposes': 'expone',
'exposes:': 'exposes:', 'exposes:': 'expone:',
'extends': 'extiende', 'extends': 'extiende',
'failed to compile file because:': 'failed to compile file because:', 'failed to compile file because:': 'failed to compile file because:',
'failed to reload module': 'recarga del módulo ha fallado', 'failed to reload module': 'recarga del módulo ha fallado',
@@ -176,8 +176,8 @@
'file saved on %(time)s': 'archivo guardado %(time)s', 'file saved on %(time)s': 'archivo guardado %(time)s',
'file saved on %s': 'archivo guardado %s', 'file saved on %s': 'archivo guardado %s',
'filter': 'filter', 'filter': 'filter',
'Find Next': 'Find Next', 'Find Next': 'Buscar próximo',
'Find Previous': 'Find Previous', 'Find Previous': 'Bucar anterior',
'First name': 'Nombre', 'First name': 'Nombre',
'Frames': 'Frames', 'Frames': 'Frames',
'Functions with no doctests will result in [passed] tests.': 'Funciones sin doctests equivalen a pruebas [aceptadas].', 'Functions with no doctests will result in [passed] tests.': 'Funciones sin doctests equivalen a pruebas [aceptadas].',
@@ -224,8 +224,8 @@
'Login to the Administrative Interface': 'Inicio de sesión para la Interfaz Administrativa', 'Login to the Administrative Interface': 'Inicio de sesión para la Interfaz Administrativa',
'Logout': 'fin de sesión', 'Logout': 'fin de sesión',
'Lost Password': 'Contraseña perdida', 'Lost Password': 'Contraseña perdida',
'manage': 'manage', 'manage': 'gestionar',
'Manage': 'Manage', 'Manage': 'Gestionar',
'merge': 'combinar', 'merge': 'combinar',
'Models': 'Modelos', 'Models': 'Modelos',
'models': 'modelos', 'models': 'modelos',
@@ -233,11 +233,11 @@
'modules': 'módulos', 'modules': 'módulos',
'Name': 'Nombre', 'Name': 'Nombre',
'new application "%s" created': 'nueva aplicación "%s" creada', 'new application "%s" created': 'nueva aplicación "%s" creada',
'New application wizard': 'New application wizard', 'New application wizard': 'Asistente para nueva aplicación',
'new plugin installed': 'nuevo plugin instalado', 'new plugin installed': 'nuevo plugin instalado',
'New Record': 'Registro nuevo', 'New Record': 'Registro nuevo',
'new record inserted': 'nuevo registro insertado', 'new record inserted': 'nuevo registro insertado',
'New simple application': 'New simple application', 'New simple application': 'Nueva aplicación',
'next': 'next', 'next': 'next',
'next 100 rows': '100 filas siguientes', 'next 100 rows': '100 filas siguientes',
'NO': 'NO', 'NO': 'NO',
@@ -248,16 +248,16 @@
'No ticket_storage.txt found under /private folder': 'No ticket_storage.txt found under /private folder', 'No ticket_storage.txt found under /private folder': 'No ticket_storage.txt found under /private folder',
'online designer': 'online designer', 'online designer': 'online designer',
'or alternatively': 'or alternatively', 'or alternatively': 'or alternatively',
'Or Get from URL:': 'Or Get from URL:', 'Or Get from URL:': 'O obtener desde una URL:',
'or import from csv file': 'o importar desde archivo CSV', 'or import from csv file': 'o importar desde archivo CSV',
'or provide app url:': 'o provea URL de la aplicación:', 'or provide app url:': 'o provea URL de la aplicación:',
'or provide application url:': 'o provea URL de la aplicación:', 'or provide application url:': 'o provea URL de la aplicación:',
'Origin': 'Origen', 'Origin': 'Origen',
'Original/Translation': 'Original/Traducción', 'Original/Translation': 'Original/Traducción',
'Overwrite installed app': 'sobreescriba aplicación instalada', 'Overwrite installed app': 'sobreescriba la aplicación instalada',
'Pack all': 'empaquetar todo', 'Pack all': 'empaquetar todo',
'Pack compiled': 'empaquete compiladas', 'Pack compiled': 'empaquete compiladas',
'Pack custom': 'Pack custom', 'Pack custom': 'empaquetar personalizado',
'pack plugin': 'empaquetar plugin', 'pack plugin': 'empaquetar plugin',
'PAM authenticated user, cannot change password here': 'usuario autenticado por PAM, no puede cambiar la contraseña aquí', 'PAM authenticated user, cannot change password here': 'usuario autenticado por PAM, no puede cambiar la contraseña aquí',
'Password': 'Contraseña', 'Password': 'Contraseña',
@@ -271,8 +271,8 @@
'Plural-Forms:': 'Plural-Forms:', 'Plural-Forms:': 'Plural-Forms:',
'Powered by': 'Este sitio usa', 'Powered by': 'Este sitio usa',
'previous 100 rows': '100 filas anteriores', 'previous 100 rows': '100 filas anteriores',
'Private files': 'Private files', 'Private files': 'Archivos privados',
'private files': 'private files', 'private files': 'archivos privados',
'Query:': 'Consulta:', 'Query:': 'Consulta:',
'Rapid Search': 'Rapid Search', 'Rapid Search': 'Rapid Search',
'record': 'registro', 'record': 'registro',
@@ -285,9 +285,9 @@
'reload': 'reload', 'reload': 'reload',
'Reload routes': 'Reload routes', 'Reload routes': 'Reload routes',
'Remove compiled': 'eliminar compiladas', 'Remove compiled': 'eliminar compiladas',
'Removed Breakpoint on %s at line %s': 'Removed Breakpoint on %s at line %s', 'Removed Breakpoint on %s at line %s': 'Eliminado punto de ruptura en %s en la línea %s',
'Replace': 'Replace', 'Replace': 'Reemplazar',
'Replace All': 'Replace All', 'Replace All': 'Reemplazar todos',
'request': 'request', 'request': 'request',
'Resolve Conflict file': 'archivo Resolución de Conflicto', 'Resolve Conflict file': 'archivo Resolución de Conflicto',
'response': 'response', 'response': 'response',
@@ -303,19 +303,19 @@
'Running on %s': 'Running on %s', 'Running on %s': 'Running on %s',
'Save': 'Save', 'Save': 'Save',
'save': 'guardar', 'save': 'guardar',
'Save file:': 'Save file:', 'Save file:': 'Guardar:',
'Save file: %s': 'Save file: %s', 'Save file: %s': 'Guardar: %s',
'Save via Ajax': 'Save via Ajax', 'Save via Ajax': 'Guardar via Ajax',
'Saved file hash:': 'Hash del archivo guardado:', 'Saved file hash:': 'Hash del archivo guardado:',
'selected': 'seleccionado(s)', 'selected': 'seleccionado(s)',
'session': 'session', 'session': 'session',
'session expired': 'sesión expirada', 'session expired': 'sesión expirada',
'Set Breakpoint on %s at line %s: %s': 'Set Breakpoint on %s at line %s: %s', 'Set Breakpoint on %s at line %s: %s': 'Establecer punto de ruptura en %s en la línea %s: %s',
'shell': 'shell', 'shell': 'shell',
'Site': 'sitio', 'Site': 'sitio',
'some files could not be removed': 'algunos archivos no pudieron ser removidos', 'some files could not be removed': 'algunos archivos no pudieron ser removidos',
'Start searching': 'Start searching', 'Start searching': 'Iniciar búsqueda',
'Start wizard': 'Start wizard', 'Start wizard': 'Iniciar asistente',
'state': 'estado', 'state': 'estado',
'Static': 'Static', 'Static': 'Static',
'static': 'estáticos', 'static': 'estáticos',
@@ -324,7 +324,7 @@
'stop': 'stop', 'stop': 'stop',
'submit': 'enviar', 'submit': 'enviar',
'Submit': 'Submit', 'Submit': 'Submit',
'successful': 'successful', 'successful': 'exitoso',
'Sure you want to delete this object?': '¿Está seguro que desea eliminar este objeto?', 'Sure you want to delete this object?': '¿Está seguro que desea eliminar este objeto?',
'table': 'tabla', 'table': 'tabla',
'Table name': 'Nombre de la tabla', 'Table name': 'Nombre de la tabla',
@@ -332,21 +332,21 @@
'Testing application': 'Probando aplicación', 'Testing application': 'Probando aplicación',
'The "query" is a condition like "db.table1.field1==\'value\'". Something like "db.table1.field1==db.table2.field2" results in a SQL JOIN.': 'La "consulta" es una condición como "db.tabla1.campo1==\'valor\'". Algo como "db.tabla1.campo1==db.tabla2.campo2" resulta en un JOIN SQL.', 'The "query" is a condition like "db.table1.field1==\'value\'". Something like "db.table1.field1==db.table2.field2" results in a SQL JOIN.': 'La "consulta" es una condición como "db.tabla1.campo1==\'valor\'". Algo como "db.tabla1.campo1==db.tabla2.campo2" resulta en un JOIN SQL.',
'the application logic, each URL path is mapped in one exposed function in the controller': 'la lógica de la aplicación, cada ruta URL se mapea en una función expuesta en el controlador', 'the application logic, each URL path is mapped in one exposed function in the controller': 'la lógica de la aplicación, cada ruta URL se mapea en una función expuesta en el controlador',
'The application logic, each URL path is mapped in one exposed function in the controller': 'The application logic, each URL path is mapped in one exposed function in the controller', 'The application logic, each URL path is mapped in one exposed function in the controller': 'La lógica de la aplicación, cada ruta URL se mapea en una función expuesta en el controlador',
'the data representation, define database tables and sets': 'la representación de datos, define tablas y conjuntos de base de datos', 'the data representation, define database tables and sets': 'la representación de datos, define tablas y conjuntos de base de datos',
'The data representation, define database tables and sets': 'The data representation, define database tables and sets', 'The data representation, define database tables and sets': 'La representación de datos, define tablas y conjuntos de base de datos',
'The presentations layer, views are also known as templates': 'The presentations layer, views are also known as templates', 'The presentations layer, views are also known as templates': 'La capa de presentación, las vistas también son llamadas plantillas',
'the presentations layer, views are also known as templates': 'la capa de presentación, las vistas también son llamadas plantillas', 'the presentations layer, views are also known as templates': 'la capa de presentación, las vistas también son llamadas plantillas',
'There are no controllers': 'No hay controladores', 'There are no controllers': 'No hay controladores',
'There are no models': 'No hay modelos', 'There are no models': 'No hay modelos',
'There are no modules': 'No hay módulos', 'There are no modules': 'No hay módulos',
'There are no plugins': 'There are no plugins', 'There are no plugins': 'No hay plugins',
'There are no private files': 'There are no private files', 'There are no private files': 'No hay archivos privados',
'There are no static files': 'No hay archivos estáticos', 'There are no static files': 'No hay archivos estáticos',
'There are no translators, only default language is supported': 'No hay traductores, sólo el lenguaje por defecto es soportado', 'There are no translators, only default language is supported': 'No hay traductores, sólo el lenguaje por defecto es soportado',
'There are no views': 'No hay vistas', 'There are no views': 'No hay vistas',
'These files are not served, they are only available from within your app': 'These files are not served, they are only available from within your app', 'These files are not served, they are only available from within your app': 'Estos archivos no son servidos, ellos solo estan disponibles para su aplicación',
'These files are served without processing, your images go here': 'These files are served without processing, your images go here', 'These files are served without processing, your images go here': 'Estos archivos son servidos sin procesar, sus imágenes van aquí',
'these files are served without processing, your images go here': 'estos archivos son servidos sin procesar, sus imágenes van aquí', 'these files are served without processing, your images go here': 'estos archivos son servidos sin procesar, sus imágenes van aquí',
'This is the %(filename)s template': 'Esta es la plantilla %(filename)s', 'This is the %(filename)s template': 'Esta es la plantilla %(filename)s',
'this page to see if a breakpoint was hit and debug interaction is required.': 'this page to see if a breakpoint was hit and debug interaction is required.', 'this page to see if a breakpoint was hit and debug interaction is required.': 'this page to see if a breakpoint was hit and debug interaction is required.',
@@ -358,14 +358,14 @@
'To create a plugin, name a file/folder plugin_[name]': 'Para crear un plugin, nombre un archivo/carpeta plugin_[nombre]', 'To create a plugin, name a file/folder plugin_[name]': 'Para crear un plugin, nombre un archivo/carpeta plugin_[nombre]',
'To emulate a breakpoint programatically, write:': 'To emulate a breakpoint programatically, write:', 'To emulate a breakpoint programatically, write:': 'To emulate a breakpoint programatically, write:',
'to use the debugger!': 'to use the debugger!', 'to use the debugger!': 'to use the debugger!',
'toggle breakpoint': 'toggle breakpoint', 'toggle breakpoint': 'alternar punto de ruptura',
'Toggle Fullscreen': 'Toggle Fullscreen', 'Toggle Fullscreen': 'Alternar pantalla completa',
'Traceback': 'Traceback', 'Traceback': 'Traceback',
'translation strings for the application': 'cadenas de caracteres de traducción para la aplicación', 'translation strings for the application': 'cadenas de caracteres de traducción para la aplicación',
'Translation strings for the application': 'Translation strings for the application', 'Translation strings for the application': 'Cadenas de caracteres de traducción para la aplicación',
'try': 'intente', 'try': 'intente',
'try something like': 'intente algo como', 'try something like': 'intente algo como',
'Try the mobile interface': 'Try the mobile interface', 'Try the mobile interface': 'Pruebe la interfaz móvil',
'try view': 'try view', 'try view': 'try view',
'Type some Python code in here and hit Return (Enter) to execute it.': 'Type some Python code in here and hit Return (Enter) to execute it.', 'Type some Python code in here and hit Return (Enter) to execute it.': 'Type some Python code in here and hit Return (Enter) to execute it.',
'Unable to check for upgrades': 'No es posible verificar la existencia de actualizaciones', 'Unable to check for upgrades': 'No es posible verificar la existencia de actualizaciones',
@@ -386,10 +386,10 @@
'Update:': 'Actualice:', 'Update:': 'Actualice:',
'upgrade now to %s': 'upgrade now to %s', 'upgrade now to %s': 'upgrade now to %s',
'upgrade web2py now': 'actualize web2py ahora', 'upgrade web2py now': 'actualize web2py ahora',
'Upload': 'Upload', 'Upload': 'Subir',
'Upload & install packed application': 'Suba e instale aplicación empaquetada', 'Upload & install packed application': 'Suba e instale aplicación empaquetada',
'Upload a package:': 'Upload a package:', 'Upload a package:': 'Subir un paquete:',
'Upload and install packed application': 'Upload and install packed application', 'Upload and install packed application': 'Suba e instale una aplicación empaquetada',
'upload application:': 'subir aplicación:', 'upload application:': 'subir aplicación:',
'Upload existing application': 'Suba esta aplicación', 'Upload existing application': 'Suba esta aplicación',
'upload file:': 'suba archivo:', 'upload file:': 'suba archivo:',
+5
View File
@@ -8,6 +8,7 @@ from gluon.fileutils import read_file
# ## make sure administrator is on localhost or https # ## make sure administrator is on localhost or https
# ########################################################### # ###########################################################
http_host = request.env.http_host.split(':')[0] http_host = request.env.http_host.split(':')[0]
if request.env.web2py_runtime_gae: if request.env.web2py_runtime_gae:
@@ -145,6 +146,10 @@ elif session.is_mobile == 'false':
else: else:
is_mobile = request.user_agent().is_mobile is_mobile = request.user_agent().is_mobile
if DEMO_MODE:
session.authorized = True
session.forget()
if request.controller == "webservices": if request.controller == "webservices":
basic = request.env.http_authorization basic = request.env.http_authorization
if not basic or not basic[:6].lower() == 'basic ': if not basic or not basic[:6].lower() == 'basic ':
+63 -45
View File
@@ -380,7 +380,6 @@ _base_environment_['SQLFORM'] = SQLFORM
_base_environment_['SQLTABLE'] = SQLTABLE _base_environment_['SQLTABLE'] = SQLTABLE
_base_environment_['LOAD'] = LOAD _base_environment_['LOAD'] = LOAD
def build_environment(request, response, session, store_current=True): def build_environment(request, response, session, store_current=True):
""" """
Build the environment dictionary into which web2py files are executed. Build the environment dictionary into which web2py files are executed.
@@ -392,8 +391,11 @@ def build_environment(request, response, session, store_current=True):
request.env = Storage() request.env = Storage()
# Enable standard conditional models (i.e., /*.py, /[controller]/*.py, and # Enable standard conditional models (i.e., /*.py, /[controller]/*.py, and
# /[controller]/[function]/*.py) # /[controller]/[function]/*.py)
response.models_to_run = [r'^\w+\.py$', r'^%s/\w+\.py$' % request.controller, response.models_to_run = [
r'^%s/%s/\w+\.py$' % (request.controller, request.function)] r'^\w+\.py$',
r'^%s/\w+\.py$' % request.controller,
r'^%s/%s/\w+\.py$' % (request.controller, request.function)
]
t = environment['T'] = translator(os.path.join(request.folder,'languages'), t = environment['T'] = translator(os.path.join(request.folder,'languages'),
request.env.http_accept_language) request.env.http_accept_language)
@@ -452,12 +454,12 @@ def compile_views(folder):
""" """
path = pjoin(folder, 'views') path = pjoin(folder, 'views')
for file in listdir(path, '^[\w/\-]+(\.\w+)*$'): for fname in listdir(path, '^[\w/\-]+(\.\w+)*$'):
try: try:
data = parse_template(file, path) data = parse_template(fname, path)
except Exception, e: except Exception, e:
raise Exception("%s in %s" % (e, file)) raise Exception("%s in %s" % (e, fname))
filename = ('views/%s.py' % file).replace('/', '_').replace('\\', '_') filename = 'views.%s.py' % fname.replace(os.path.sep, '.')
filename = pjoin(folder, 'compiled', filename) filename = pjoin(folder, 'compiled', filename)
write_file(filename, data) write_file(filename, data)
save_pyc(filename) save_pyc(filename)
@@ -470,9 +472,10 @@ def compile_models(folder):
""" """
path = pjoin(folder, 'models') path = pjoin(folder, 'models')
for file in listdir(path, '.+\.py$'): for fname in listdir(path, '.+\.py$'):
data = read_file(pjoin(path, file)) data = read_file(pjoin(path, fname))
filename = pjoin(folder, 'compiled', 'models', file) modelfile = 'models.'+fname.replace(os.path.sep,'.')
filename = pjoin(folder, 'compiled', modelfile)
mktree(filename) mktree(filename)
write_file(filename, data) write_file(filename, data)
save_pyc(filename) save_pyc(filename)
@@ -485,20 +488,21 @@ def compile_controllers(folder):
""" """
path = pjoin(folder, 'controllers') path = pjoin(folder, 'controllers')
for file in listdir(path, '.+\.py$'): for fname in listdir(path, '.+\.py$'):
### why is this here? save_pyc(pjoin(path, file)) ### why is this here? save_pyc(pjoin(path, file))
data = read_file(pjoin(path, file)) data = read_file(pjoin(path, fname))
exposed = regex_expose.findall(data) exposed = regex_expose.findall(data)
for function in exposed: for function in exposed:
command = data + "\nresponse._vars=response._caller(%s)\n" % \ command = data + "\nresponse._vars=response._caller(%s)\n" % \
function function
filename = pjoin(folder, 'compiled', ('controllers/' filename = pjoin(folder, 'compiled',
+ file[:-3]).replace('/', '_') 'controllers.%s.%s.py' % (fname[:-3],function))
+ '_' + function + '.py')
write_file(filename, command) write_file(filename, command)
save_pyc(filename) save_pyc(filename)
os.unlink(filename) os.unlink(filename)
def model_cmp(a,b):
return cmp(a.count('.'),b.count('.')) or cmp(a,b)
def run_models_in(environment): def run_models_in(environment):
""" """
@@ -509,33 +513,38 @@ def run_models_in(environment):
folder = environment['request'].folder folder = environment['request'].folder
c = environment['request'].controller c = environment['request'].controller
f = environment['request'].function f = environment['request'].function
response = environment['response']
path = pjoin(folder, 'models')
cpath = pjoin(folder, 'compiled') cpath = pjoin(folder, 'compiled')
if os.path.exists(cpath): compiled = os.path.exists(cpath)
for model in listdir(cpath, '^models_\w+\.pyc$', 0): if compiled:
restricted(read_pyc(model), environment, layer=model) models = sorted(listdir(cpath, '^models[_.][\w.]+\.pyc$', 0),model_cmp)
path = pjoin(cpath, 'models')
models = listdir(path, '^\w+\.pyc$', 0, sort=True)
compiled = True
else: else:
path = pjoin(folder, 'models') models = sorted(listdir(path, '^\w+\.py$', 0, sort=False),model_cmp)
models = listdir(path, '^\w+\.py$', 0, sort=True) n = len(path)+1
compiled = False
n = len(path) + 1 models_to_run = None
for model in models: for model in models:
regex = environment['response'].models_to_run if response.models_to_run != models_to_run:
if isinstance(regex, list): regex = models_to_run = response.models_to_run
regex = re_compile('|'.join(regex)) if isinstance(regex, list):
file = model[n:].replace(os.path.sep, '/').replace('.pyc', '.py') regex = re_compile('|'.join(regex))
if not regex.search(file) and c != 'appadmin': if models_to_run:
continue if compiled:
elif compiled: fname = model[n:-4].replace('.','/')+'.py'
code = read_pyc(model) else:
elif is_gae: fname = model[n:].replace(os.path.sep,'/')
code = getcfs(model, model, if not regex.search(fname) and c != 'appadmin':
lambda: compile2(read_file(model), model)) continue
else: elif compiled:
code = getcfs(model, model, None) code = read_pyc(model)
restricted(code, environment, layer=model) elif is_gae:
code = getcfs(model, model,
lambda: compile2(read_file(model), model))
else:
code = getcfs(model, model, None)
restricted(code, environment, layer=model)
def run_controller_in(controller, function, environment): def run_controller_in(controller, function, environment):
@@ -551,12 +560,17 @@ def run_controller_in(controller, function, environment):
badc = 'invalid controller (%s/%s)' % (controller, function) badc = 'invalid controller (%s/%s)' % (controller, function)
badf = 'invalid function (%s/%s)' % (controller, function) badf = 'invalid function (%s/%s)' % (controller, function)
if os.path.exists(path): if os.path.exists(path):
filename = pjoin(path, 'controllers_%s_%s.pyc' filename = pjoin(path, 'controllers.%s.%s.pyc'
% (controller, function)) % (controller, function))
if not os.path.exists(filename): if not os.path.exists(filename):
raise HTTP(404, ### for backward compatibility
rewrite.THREAD_LOCAL.routes.error_message % badf, filename = pjoin(path, 'controllers_%s_%s.pyc'
web2py_error=badf) % (controller, function))
### end for backward compatibility
if not os.path.exists(filename):
raise HTTP(404,
rewrite.THREAD_LOCAL.routes.error_message % badf,
web2py_error=badf)
restricted(read_pyc(filename), environment, layer=filename) restricted(read_pyc(filename), environment, layer=filename)
elif function == '_TEST': elif function == '_TEST':
# TESTING: adjust the path to include site packages # TESTING: adjust the path to include site packages
@@ -631,11 +645,15 @@ def run_view_in(environment):
context=environment) context=environment)
restricted(ccode, environment, 'file stream') restricted(ccode, environment, 'file stream')
elif os.path.exists(path): elif os.path.exists(path):
x = view.replace('/', '.')
files = ['views.%s.pyc' % x]
if allow_generic:
files.append('views.generic.%s.pyc' % request.extension)
# for backward compatibility
x = view.replace('/', '_') x = view.replace('/', '_')
files = ['views_%s.pyc' % x] files.append('views_%s.pyc' % x)
if allow_generic: if allow_generic:
files.append('views_generic.%s.pyc' % request.extension) files.append('views_generic.%s.pyc' % request.extension)
# for backward compatibility
if request.extension == 'html': if request.extension == 'html':
files.append('views_%s.pyc' % x[:-5]) files.append('views_%s.pyc' % x[:-5])
if allow_generic: if allow_generic:
+1 -1
View File
@@ -37,7 +37,7 @@ class MemcacheClient(object):
self.client.delete(key) self.client.delete(key)
else: else:
value = f() value = f()
self.client.set(key, (time.time(), value)) self.client.set(key, (time.time(), value), time=time_expire)
return value return value
def increment(self, key, value=1): def increment(self, key, value=1):
+1 -1
View File
@@ -6926,7 +6926,7 @@ def sqlhtml_validators(field):
elif field_type == 'double' or field_type == 'float': elif field_type == 'double' or field_type == 'float':
requires.append(validators.IS_FLOAT_IN_RANGE(-1e100, 1e100)) requires.append(validators.IS_FLOAT_IN_RANGE(-1e100, 1e100))
elif field_type in ('integer','bigint'): elif field_type in ('integer','bigint'):
requires.append(validators.IS_INT_IN_RANGE(-1e100, 1e100)) requires.append(validators.IS_INT_IN_RANGE(-2**31, 2**31-1))
elif field_type.startswith('decimal'): elif field_type.startswith('decimal'):
requires.append(validators.IS_DECIMAL_IN_RANGE(-10**10, 10**10)) requires.append(validators.IS_DECIMAL_IN_RANGE(-10**10, 10**10))
elif field_type == 'date': elif field_type == 'date':
+9 -6
View File
@@ -1917,14 +1917,14 @@ class SQLFORM(FORM):
else: else:
fields = [] fields = []
columns = [] columns = []
filter1 = lambda f:isinstance(f,Field)
filter2 = lambda f:isinstance(f,Field) and f.readable
for table in tables: for table in tables:
fields += filter(filter1, table)
columns += filter(filter2, table)
for k,f in table.iteritems(): for k,f in table.iteritems():
if not k.startswith('_'): if not k.startswith('_'):
if isinstance(f,Field): if isinstance(f,Field.Virtual) and f.readable:
fields.append(f) # these are selected
if f.readable:
columns.append(f) # these are displayed
elif isinstance(f,Field.Virtual) and f.readable:
f.tablename = table._tablename f.tablename = table._tablename
columns.append(f) columns.append(f)
fields.append(f) fields.append(f)
@@ -2273,7 +2273,9 @@ class SQLFORM(FORM):
limitby = None limitby = None
try: try:
table_fields = filter(lambda f: f.tablename in tablenames, fields) table_fields = filter(
lambda f: (f.tablename in tablenames) and \
(not(isinstance(f,Field.Virtual))),fields)
if dbset._db._adapter.dbengine=='google:datastore': if dbset._db._adapter.dbengine=='google:datastore':
rows = dbset.select(left=left,orderby=orderby, rows = dbset.select(left=left,orderby=orderby,
groupby=groupby,limitby=limitby, groupby=groupby,limitby=limitby,
@@ -2366,6 +2368,7 @@ class SQLFORM(FORM):
continue continue
if field.type == 'blob': if field.type == 'blob':
continue continue
print row
value = row[str(field)] value = row[str(field)]
maxlength = maxtextlengths.get(str(field), maxtextlength) maxlength = maxtextlengths.get(str(field), maxtextlength)
if field.represent: if field.represent:
+18 -37
View File
@@ -22,6 +22,8 @@ from cStringIO import StringIO
from gluon.utils import simple_hash, web2py_uuid, DIGEST_ALG_BY_SIZE from gluon.utils import simple_hash, web2py_uuid, DIGEST_ALG_BY_SIZE
from gluon.dal import FieldVirtual, FieldMethod from gluon.dal import FieldVirtual, FieldMethod
regex_isint = re.compile('^\-?\d+$')
JSONErrors = (NameError, TypeError, ValueError, AttributeError, JSONErrors = (NameError, TypeError, ValueError, AttributeError,
KeyError) KeyError)
try: try:
@@ -692,15 +694,15 @@ class IS_INT_IN_RANGE(Validator):
>>> IS_INT_IN_RANGE(1,5)(5) >>> IS_INT_IN_RANGE(1,5)(5)
(5, 'enter an integer between 1 and 4') (5, 'enter an integer between 1 and 4')
>>> IS_INT_IN_RANGE(1,5)(3.5) >>> IS_INT_IN_RANGE(1,5)(3.5)
(3, 'enter an integer between 1 and 4') (3.5, 'enter an integer between 1 and 4')
>>> IS_INT_IN_RANGE(None,5)('4') >>> IS_INT_IN_RANGE(None,5)('4')
(4, None) (4, None)
>>> IS_INT_IN_RANGE(None,5)('6') >>> IS_INT_IN_RANGE(None,5)('6')
(6, 'enter an integer less than or equal to 4') ('6', 'enter an integer less than or equal to 4')
>>> IS_INT_IN_RANGE(1,None)('4') >>> IS_INT_IN_RANGE(1,None)('4')
(4, None) (4, None)
>>> IS_INT_IN_RANGE(1,None)('0') >>> IS_INT_IN_RANGE(1,None)('0')
(0, 'enter an integer greater than or equal to 1') ('0', 'enter an integer greater than or equal to 1')
>>> IS_INT_IN_RANGE()(6) >>> IS_INT_IN_RANGE()(6)
(6, None) (6, None)
>>> IS_INT_IN_RANGE()('abc') >>> IS_INT_IN_RANGE()('abc')
@@ -741,24 +743,13 @@ class IS_INT_IN_RANGE(Validator):
% dict(min=self.minimum, max=self.maximum - 1) % dict(min=self.minimum, max=self.maximum - 1)
def __call__(self, value): def __call__(self, value):
try: if value and regex_isint.match(str(value)):
fvalue = float(value) v = int(value)
value = int(value) if ((self.minimum is None or v >= self.minimum) and
if value != fvalue: (self.maximum is None or v < self.maximum)):
return (value, self.error_message) return (v, None)
if self.minimum is None:
if self.maximum is None or value < self.maximum:
return (value, None)
elif self.maximum is None:
if value >= self.minimum:
return (value, None)
elif self.minimum <= value < self.maximum:
return (value, None)
except ValueError:
pass
return (value, self.error_message) return (value, self.error_message)
def str2dec(number): def str2dec(number):
s = str(number) s = str(number)
if not '.' in s: if not '.' in s:
@@ -839,17 +830,12 @@ class IS_FLOAT_IN_RANGE(Validator):
def __call__(self, value): def __call__(self, value):
try: try:
if self.dot == '.': if self.dot == '.':
fvalue = float(value) v = float(value)
else: else:
fvalue = float(str(value).replace(self.dot, '.')) v = float(str(value).replace(self.dot, '.'))
if self.minimum is None: if ((self.minimum is None or v >= self.minimum) and
if self.maximum is None or fvalue <= self.maximum: (self.maximum is None or v <= self.maximum)):
return (fvalue, None) return (v, None)
elif self.maximum is None:
if fvalue >= self.minimum:
return (fvalue, None)
elif self.minimum <= fvalue <= self.maximum:
return (fvalue, None)
except (ValueError, TypeError): except (ValueError, TypeError):
pass pass
return (value, self.error_message) return (value, self.error_message)
@@ -948,14 +934,9 @@ class IS_DECIMAL_IN_RANGE(Validator):
v = value v = value
else: else:
v = decimal.Decimal(str(value).replace(self.dot, '.')) v = decimal.Decimal(str(value).replace(self.dot, '.'))
if self.minimum is None: if ((self.minimum is None or v >= self.minimum) and
if self.maximum is None or v <= self.maximum: (self.maximum is None or v <= self.maximum)):
return (v, None) return (v, None)
elif self.maximum is None:
if v >= self.minimum:
return (v, None)
elif self.minimum <= v <= self.maximum:
return (v, None)
except (ValueError, TypeError, decimal.InvalidOperation): except (ValueError, TypeError, decimal.InvalidOperation):
pass pass
return (value, self.error_message) return (value, self.error_message)