Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
afdb028070 | ||
|
|
80d4615f32 | ||
|
|
5a12a7fb31 | ||
|
|
17c10b8a45 | ||
|
|
f8e2c8e319 | ||
|
|
9ea82fdaaf | ||
|
|
3d01a83c85 | ||
|
|
13f8b1a10c | ||
|
|
f78e172eda | ||
|
|
bd452f90b2 | ||
|
|
2b1f150f02 | ||
|
|
e7a9457249 | ||
|
|
d3ab2e73d5 | ||
|
|
860f40ca63 | ||
|
|
59a7db56a4 | ||
|
|
01e5107a96 | ||
|
|
8765dbbe0f | ||
|
|
d125b0b95b | ||
|
|
1d2fc4b8f5 | ||
|
|
146ea115bf | ||
|
|
4f44188997 | ||
|
|
ac5fb303eb | ||
|
|
31a14997f8 | ||
|
|
4cd4ff2c5e | ||
|
|
26ef508966 | ||
|
|
28b4badb9a | ||
|
|
8e2e2420b0 | ||
|
|
67349627f4 | ||
|
|
cfe825f94a | ||
|
|
53e79915fa | ||
|
|
9fb5f688ed | ||
|
|
c2cdae0615 | ||
|
|
2516bb59a1 | ||
|
|
13c78fae58 | ||
|
|
91c0a31800 | ||
|
|
277137c8e6 | ||
|
|
4556a355a2 | ||
|
|
7dafb07438 | ||
|
|
3c8e7a1364 | ||
|
|
921cd46c10 |
@@ -1,4 +1,4 @@
|
|||||||
## 2.6.1
|
## 2.6.1 - 2.6.4
|
||||||
|
|
||||||
Attention all users: For pre 2.6 applications to work with web2py >=2.6, you must copy static/js/web2py.js, controllers/appadmin.py, and views/appadmin.html from the welcome app to your own apps (all of them).
|
Attention all users: For pre 2.6 applications to work with web2py >=2.6, you must copy static/js/web2py.js, controllers/appadmin.py, and views/appadmin.html from the welcome app to your own apps (all of them).
|
||||||
|
|
||||||
@@ -38,6 +38,8 @@ Attention MySQL users: The length of string fields changed from 255 to 512 bytes
|
|||||||
- speedup for define_table, thanks Michele
|
- speedup for define_table, thanks Michele
|
||||||
- settings.cfg to admin, thanks Paolo
|
- settings.cfg to admin, thanks Paolo
|
||||||
- many bugs fixed, thanks Niphlod, Michele, Roberto, Jonathan, and many others
|
- many bugs fixed, thanks Niphlod, Michele, Roberto, Jonathan, and many others
|
||||||
|
- 2.6,3 specifically fixed a possible DoS vulnerability
|
||||||
|
- 2.6.4 specifically fixes major problem introduced in 2.6.1 with session logic
|
||||||
|
|
||||||
## 2.5.2
|
## 2.5.2
|
||||||
|
|
||||||
|
|||||||
@@ -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.6.2-stable+timestamp.'`date +%Y.%m.%d.%H.%M.%S` > VERSION
|
echo 'Version 2.6.4-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 @@
|
|||||||
Version 2.6.2-stable+timestamp.2013.09.13.17.43.10
|
Version 2.6.4-stable+timestamp.2013.09.21.20.41.28
|
||||||
|
|||||||
@@ -108,7 +108,7 @@ def index():
|
|||||||
if session.authorized:
|
if session.authorized:
|
||||||
redirect(send)
|
redirect(send)
|
||||||
elif request.vars.password:
|
elif request.vars.password:
|
||||||
if verify_password(request.vars.password):
|
if verify_password(request.vars.password[:1024]):
|
||||||
session.authorized = True
|
session.authorized = True
|
||||||
login_record(True)
|
login_record(True)
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +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)',
|
||||||
'(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\x01Searching: **%s** %%{file}': 'Searching: **%s** files',
|
'@markmin\x01Searching: **%s** %%{file}': 'Searching: **%s** files',
|
||||||
@@ -32,6 +33,7 @@
|
|||||||
'application "%s" uninstalled': 'aplicación "%s" desinstalada',
|
'application "%s" uninstalled': 'aplicación "%s" desinstalada',
|
||||||
'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:',
|
||||||
'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"?',
|
||||||
@@ -47,6 +49,7 @@
|
|||||||
'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',
|
||||||
'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',
|
||||||
@@ -54,14 +57,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',
|
||||||
'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 Password': 'Cambie Contraseña',
|
'Change Password': 'Cambie Contraseña',
|
||||||
'check all': 'marcar todos',
|
'check all': 'marcar todos',
|
||||||
|
'Check for upgrades': 'Check for upgrades',
|
||||||
'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',
|
||||||
@@ -91,6 +97,7 @@
|
|||||||
'Current request': 'Solicitud en curso',
|
'Current request': 'Solicitud en curso',
|
||||||
'Current response': 'Respuesta en curso',
|
'Current response': 'Respuesta en curso',
|
||||||
'Current session': 'Sesión en curso',
|
'Current session': 'Sesión en curso',
|
||||||
|
'currently running': 'currently running',
|
||||||
'currently saved or': 'actualmente guardado o',
|
'currently saved or': 'actualmente guardado o',
|
||||||
'customize me!': 'Adaptame!',
|
'customize me!': 'Adaptame!',
|
||||||
'data uploaded': 'datos subidos',
|
'data uploaded': 'datos subidos',
|
||||||
@@ -107,14 +114,21 @@
|
|||||||
'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)': 'Delete this file (you will be asked to confirm deletion)',
|
||||||
'Delete:': 'Elimine:',
|
'Delete:': 'Elimine:',
|
||||||
|
'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',
|
||||||
'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',
|
||||||
|
'details': 'details',
|
||||||
'direction: ltr': 'direction: ltr',
|
'direction: ltr': 'direction: ltr',
|
||||||
|
'Disable': 'Disable',
|
||||||
'docs': 'docs',
|
'docs': 'docs',
|
||||||
'done!': 'listo!',
|
'done!': 'listo!',
|
||||||
|
'Download': 'Download',
|
||||||
|
'download files via http:': 'download files via http:',
|
||||||
'download layouts': 'download layouts',
|
'download layouts': 'download layouts',
|
||||||
'download plugins': 'download plugins',
|
'download plugins': 'download plugins',
|
||||||
'E-mail': 'Correo electrónico',
|
'E-mail': 'Correo electrónico',
|
||||||
@@ -122,17 +136,25 @@
|
|||||||
'Edit': 'editar',
|
'Edit': 'editar',
|
||||||
'Edit application': 'Editar aplicación',
|
'Edit application': 'Editar aplicación',
|
||||||
'edit controller': 'editar controlador',
|
'edit controller': 'editar controlador',
|
||||||
|
'edit controller:': 'edit controller:',
|
||||||
'Edit current record': 'Edite el registro actual',
|
'Edit current record': 'Edite el registro actual',
|
||||||
'Edit Profile': 'Editar Perfil',
|
'Edit Profile': 'Editar Perfil',
|
||||||
'edit views:': 'editar vistas:',
|
'edit views:': 'editar vistas:',
|
||||||
'Editing file': 'Editando archivo',
|
'Editing file': 'Editando archivo',
|
||||||
'Editing file "%s"': 'Editando archivo "%s"',
|
'Editing file "%s"': 'Editando archivo "%s"',
|
||||||
'Editing Language file': 'Editando archivo de lenguaje',
|
'Editing Language file': 'Editando archivo de lenguaje',
|
||||||
|
'Editing myclientapi': 'Editing myclientapi',
|
||||||
|
'Editing myemail': 'Editing myemail',
|
||||||
|
'Editing rbare': 'Editing rbare',
|
||||||
|
'Editing ul': 'Editing ul',
|
||||||
'Enterprise Web Framework': 'Armazón Empresarial para Internet',
|
'Enterprise Web Framework': 'Armazón Empresarial para Internet',
|
||||||
'Error': 'Error',
|
'Error': 'Error',
|
||||||
'Error logs for "%(app)s"': 'Bitácora de errores en "%(app)s"',
|
'Error logs for "%(app)s"': 'Bitácora de errores en "%(app)s"',
|
||||||
|
'Error snapshot': 'Error snapshot',
|
||||||
|
'Error ticket': 'Error ticket',
|
||||||
'Errors': 'errores',
|
'Errors': 'errores',
|
||||||
'Exception instance attributes': 'Atributos de la instancia de Excepción',
|
'Exception instance attributes': 'Atributos de la instancia de Excepción',
|
||||||
|
'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:': 'exposes:',
|
||||||
@@ -154,6 +176,7 @@
|
|||||||
'Find Next': 'Find Next',
|
'Find Next': 'Find Next',
|
||||||
'Find Previous': 'Find Previous',
|
'Find Previous': 'Find Previous',
|
||||||
'First name': 'Nombre',
|
'First name': 'Nombre',
|
||||||
|
'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].',
|
||||||
'Globals##debug': 'Globals',
|
'Globals##debug': 'Globals',
|
||||||
'graph model': 'graph model',
|
'graph model': 'graph model',
|
||||||
@@ -166,6 +189,7 @@
|
|||||||
'includes': 'incluye',
|
'includes': 'incluye',
|
||||||
'insert new': 'inserte nuevo',
|
'insert new': 'inserte nuevo',
|
||||||
'insert new %s': 'inserte nuevo %s',
|
'insert new %s': 'inserte nuevo %s',
|
||||||
|
'inspect attributes': 'inspect attributes',
|
||||||
'Install': 'instalar',
|
'Install': 'instalar',
|
||||||
'Installed applications': 'Aplicaciones instaladas',
|
'Installed applications': 'Aplicaciones instaladas',
|
||||||
'Interaction at %s line %s': 'Interaction at %s line %s',
|
'Interaction at %s line %s': 'Interaction at %s line %s',
|
||||||
@@ -175,10 +199,12 @@
|
|||||||
'Invalid action': 'Acción inválida',
|
'Invalid action': 'Acción inválida',
|
||||||
'Invalid email': 'Correo inválido',
|
'Invalid email': 'Correo inválido',
|
||||||
'invalid password': 'contraseña inválida',
|
'invalid password': 'contraseña inválida',
|
||||||
|
'invalid password.': 'invalid password.',
|
||||||
'Invalid Query': 'Consulta inválida',
|
'Invalid Query': 'Consulta inválida',
|
||||||
'invalid request': 'solicitud inválida',
|
'invalid request': 'solicitud inválida',
|
||||||
'invalid ticket': 'tiquete inválido',
|
'invalid ticket': 'tiquete inválido',
|
||||||
'Key bindings': 'Key bindings',
|
'Key bindings': 'Key bindings',
|
||||||
|
'Key bindings for ZenCoding Plugin': 'Key bindings for ZenCoding Plugin',
|
||||||
'language file "%(filename)s" created/updated': 'archivo de lenguaje "%(filename)s" creado/actualizado',
|
'language file "%(filename)s" created/updated': 'archivo de lenguaje "%(filename)s" creado/actualizado',
|
||||||
'Language files (static strings) updated': 'Archivos de lenguaje (cadenas estáticas) actualizados',
|
'Language files (static strings) updated': 'Archivos de lenguaje (cadenas estáticas) actualizados',
|
||||||
'languages': 'lenguajes',
|
'languages': 'lenguajes',
|
||||||
@@ -188,6 +214,7 @@
|
|||||||
'Last saved on:': 'Guardado en:',
|
'Last saved on:': 'Guardado en:',
|
||||||
'License for': 'Licencia para',
|
'License for': 'Licencia para',
|
||||||
'loading...': 'cargando...',
|
'loading...': 'cargando...',
|
||||||
|
'locals': 'locals',
|
||||||
'Locals##debug': 'Locals',
|
'Locals##debug': 'Locals',
|
||||||
'Login': 'Inicio de sesión',
|
'Login': 'Inicio de sesión',
|
||||||
'login': 'inicio de sesión',
|
'login': 'inicio de sesión',
|
||||||
@@ -195,6 +222,7 @@
|
|||||||
'Logout': 'fin de sesión',
|
'Logout': 'fin de sesión',
|
||||||
'Lost Password': 'Contraseña perdida',
|
'Lost Password': 'Contraseña perdida',
|
||||||
'manage': 'manage',
|
'manage': 'manage',
|
||||||
|
'Manage': 'Manage',
|
||||||
'merge': 'combinar',
|
'merge': 'combinar',
|
||||||
'Models': 'Modelos',
|
'Models': 'Modelos',
|
||||||
'models': 'modelos',
|
'models': 'modelos',
|
||||||
@@ -202,16 +230,22 @@
|
|||||||
'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 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',
|
||||||
'next': 'next',
|
'next': 'next',
|
||||||
'next 100 rows': '100 filas siguientes',
|
'next 100 rows': '100 filas siguientes',
|
||||||
'NO': 'NO',
|
'NO': 'NO',
|
||||||
'No databases in this application': 'No hay bases de datos en esta aplicación',
|
'No databases in this application': 'No hay bases de datos en esta aplicación',
|
||||||
'No Interaction yet': 'No Interaction yet',
|
'No Interaction yet': 'No Interaction yet',
|
||||||
'no match': 'no encontrado',
|
'no match': 'no encontrado',
|
||||||
|
'no package selected': 'no package selected',
|
||||||
|
'No ticket_storage.txt found under /private folder': 'No ticket_storage.txt found under /private folder',
|
||||||
|
'online designer': 'online designer',
|
||||||
'or alternatively': 'or alternatively',
|
'or alternatively': 'or alternatively',
|
||||||
|
'Or Get from URL:': 'Or Get from 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:',
|
||||||
@@ -220,6 +254,7 @@
|
|||||||
'Overwrite installed app': 'sobreescriba aplicación instalada',
|
'Overwrite installed app': 'sobreescriba aplicación instalada',
|
||||||
'Pack all': 'empaquetar todo',
|
'Pack all': 'empaquetar todo',
|
||||||
'Pack compiled': 'empaquete compiladas',
|
'Pack compiled': 'empaquete compiladas',
|
||||||
|
'Pack custom': 'Pack custom',
|
||||||
'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',
|
||||||
@@ -236,6 +271,7 @@
|
|||||||
'Private files': 'Private files',
|
'Private files': 'Private files',
|
||||||
'private files': 'private files',
|
'private files': 'private files',
|
||||||
'Query:': 'Consulta:',
|
'Query:': 'Consulta:',
|
||||||
|
'Rapid Search': 'Rapid Search',
|
||||||
'record': 'registro',
|
'record': 'registro',
|
||||||
'record does not exist': 'el registro no existe',
|
'record does not exist': 'el registro no existe',
|
||||||
'record id': 'id de registro',
|
'record id': 'id de registro',
|
||||||
@@ -244,11 +280,14 @@
|
|||||||
'Register': 'Registrese',
|
'Register': 'Registrese',
|
||||||
'Registration key': 'Contraseña de Registro',
|
'Registration key': 'Contraseña de Registro',
|
||||||
'reload': 'reload',
|
'reload': 'reload',
|
||||||
|
'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': 'Removed Breakpoint on %s at line %s',
|
||||||
'Replace': 'Replace',
|
'Replace': 'Replace',
|
||||||
'Replace All': 'Replace All',
|
'Replace All': 'Replace All',
|
||||||
|
'request': 'request',
|
||||||
'Resolve Conflict file': 'archivo Resolución de Conflicto',
|
'Resolve Conflict file': 'archivo Resolución de Conflicto',
|
||||||
|
'response': 'response',
|
||||||
'restore': 'restaurar',
|
'restore': 'restaurar',
|
||||||
'return': 'return',
|
'return': 'return',
|
||||||
'revert': 'revertir',
|
'revert': 'revertir',
|
||||||
@@ -256,26 +295,32 @@
|
|||||||
'Rows in table': 'Filas en la tabla',
|
'Rows in table': 'Filas en la tabla',
|
||||||
'Rows selected': 'Filas seleccionadas',
|
'Rows selected': 'Filas seleccionadas',
|
||||||
'rules are not defined': 'rules are not defined',
|
'rules are not defined': 'rules are not defined',
|
||||||
|
'Run tests in this file': 'Run tests in this file',
|
||||||
"Run tests in this file (to run all files, you may also use the button labelled 'test')": "Run tests in this file (to run all files, you may also use the button labelled 'test')",
|
"Run tests in this file (to run all files, you may also use the button labelled 'test')": "Run tests in this file (to run all files, you may also use the button labelled 'test')",
|
||||||
|
'Running on %s': 'Running on %s',
|
||||||
'Save': 'Save',
|
'Save': 'Save',
|
||||||
'save': 'guardar',
|
'save': 'guardar',
|
||||||
'Save file:': 'Save file:',
|
'Save file:': 'Save file:',
|
||||||
|
'Save file: %s': 'Save file: %s',
|
||||||
'Save via Ajax': 'Save via Ajax',
|
'Save via Ajax': 'Save 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 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': 'Set Breakpoint on %s at line %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': 'Start searching',
|
||||||
|
'Start wizard': 'Start wizard',
|
||||||
'state': 'estado',
|
'state': 'estado',
|
||||||
'static': 'estáticos',
|
|
||||||
'Static': 'Static',
|
'Static': 'Static',
|
||||||
|
'static': 'estáticos',
|
||||||
'Static files': 'Archivos estáticos',
|
'Static files': 'Archivos estáticos',
|
||||||
'step': 'step',
|
'step': 'step',
|
||||||
'stop': 'stop',
|
'stop': 'stop',
|
||||||
'submit': 'enviar',
|
'submit': 'enviar',
|
||||||
|
'Submit': 'Submit',
|
||||||
'successful': 'successful',
|
'successful': 'successful',
|
||||||
'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',
|
||||||
@@ -303,6 +348,7 @@
|
|||||||
'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.',
|
||||||
'Ticket': 'Tiquete',
|
'Ticket': 'Tiquete',
|
||||||
|
'Ticket ID': 'Ticket ID',
|
||||||
'Timestamp': 'Timestamp',
|
'Timestamp': 'Timestamp',
|
||||||
'TM': 'MR',
|
'TM': 'MR',
|
||||||
'to previous version.': 'a la versión previa.',
|
'to previous version.': 'a la versión previa.',
|
||||||
@@ -311,10 +357,13 @@
|
|||||||
'to use the debugger!': 'to use the debugger!',
|
'to use the debugger!': 'to use the debugger!',
|
||||||
'toggle breakpoint': 'toggle breakpoint',
|
'toggle breakpoint': 'toggle breakpoint',
|
||||||
'Toggle Fullscreen': 'Toggle Fullscreen',
|
'Toggle Fullscreen': 'Toggle Fullscreen',
|
||||||
|
'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': 'Translation strings for the application',
|
||||||
'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 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',
|
||||||
'unable to create application "%s"': 'no es posible crear la aplicación "%s"',
|
'unable to create application "%s"': 'no es posible crear la aplicación "%s"',
|
||||||
@@ -332,9 +381,12 @@
|
|||||||
'update': 'actualizar',
|
'update': 'actualizar',
|
||||||
'update all languages': 'actualizar todos los lenguajes',
|
'update all languages': 'actualizar todos los lenguajes',
|
||||||
'Update:': 'Actualice:',
|
'Update:': 'Actualice:',
|
||||||
|
'upgrade now to %s': 'upgrade now to %s',
|
||||||
'upgrade web2py now': 'actualize web2py ahora',
|
'upgrade web2py now': 'actualize web2py ahora',
|
||||||
'Upload': 'Upload',
|
'Upload': 'Upload',
|
||||||
'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 and install packed application': 'Upload and install packed application',
|
||||||
'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:',
|
||||||
@@ -348,6 +400,7 @@
|
|||||||
'view': 'vista',
|
'view': 'vista',
|
||||||
'Views': 'Vistas',
|
'Views': 'Vistas',
|
||||||
'views': 'vistas',
|
'views': 'vistas',
|
||||||
|
'Web Framework': 'Web Framework',
|
||||||
'web2py is up to date': 'web2py está actualizado',
|
'web2py is up to date': 'web2py está actualizado',
|
||||||
'web2py online debugger': 'web2py online debugger',
|
'web2py online debugger': 'web2py online debugger',
|
||||||
'web2py Recent Tweets': 'Tweets Recientes de web2py',
|
'web2py Recent Tweets': 'Tweets Recientes de web2py',
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ def verify_password(password):
|
|||||||
session.pam_user = None
|
session.pam_user = None
|
||||||
if DEMO_MODE:
|
if DEMO_MODE:
|
||||||
return True
|
return True
|
||||||
elif not 'password' in _config:
|
elif not _config.get('password'):
|
||||||
return False
|
return False
|
||||||
elif _config['password'].startswith('pam_user:'):
|
elif _config['password'].startswith('pam_user:'):
|
||||||
session.pam_user = _config['password'][9:].strip()
|
session.pam_user = _config['password'][9:].strip()
|
||||||
|
|||||||
@@ -2,5 +2,5 @@
|
|||||||
theme = web2py
|
theme = web2py
|
||||||
|
|
||||||
[editor]
|
[editor]
|
||||||
theme = night
|
theme = web2py
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
position: absolute ! important;
|
position: absolute ! important;
|
||||||
top: 0; left: 0;
|
top: 0; left: 0;
|
||||||
width: 100% ! important;
|
width: 100% ! important;
|
||||||
z-index: 9999;
|
z-index: 1028;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* BREAKPOINTS */
|
/* BREAKPOINTS */
|
||||||
|
|||||||
@@ -277,6 +277,8 @@
|
|||||||
ajax_page: function (method, action, data, target, element) {
|
ajax_page: function (method, action, data, target, element) {
|
||||||
/* element is a new parameter, but should be put be put in front */
|
/* element is a new parameter, but should be put be put in front */
|
||||||
if(element == undefined) element = $(document);
|
if(element == undefined) element = $(document);
|
||||||
|
/* if target is not there, fill it with something that there isn't in the page*/
|
||||||
|
if(target == undefined || target == '') target = 'w2p_none';
|
||||||
if(web2py.fire(element, 'ajax:before', null, target )) { /*test a usecase, should stop here if returns false */
|
if(web2py.fire(element, 'ajax:before', null, target )) { /*test a usecase, should stop here if returns false */
|
||||||
$.ajax({
|
$.ajax({
|
||||||
'type': method,
|
'type': method,
|
||||||
@@ -303,12 +305,7 @@
|
|||||||
},
|
},
|
||||||
'complete': function (xhr, status) {
|
'complete': function (xhr, status) {
|
||||||
web2py.fire(element, 'ajax:complete', [xhr, status], target);
|
web2py.fire(element, 'ajax:complete', [xhr, status], target);
|
||||||
var html = xhr.responseText;
|
web2py.updatePage(xhr, target); /* Parse and load the html received */
|
||||||
var content = xhr.getResponseHeader('web2py-component-content');
|
|
||||||
var t = $('#' + target);
|
|
||||||
if(content == 'prepend') t.prepend(html);
|
|
||||||
else if(content == 'append') t.append(html);
|
|
||||||
else if(content != 'hide') t.html(html);
|
|
||||||
web2py.trap_form(action, target);
|
web2py.trap_form(action, target);
|
||||||
web2py.trap_link(target);
|
web2py.trap_link(target);
|
||||||
web2py.ajax_init('#' + target);
|
web2py.ajax_init('#' + target);
|
||||||
@@ -378,6 +375,20 @@
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
updatePage: function (xhr, target) {
|
||||||
|
var t = $('#' + target);
|
||||||
|
var html = $.parseHTML(xhr.responseText, document, true);
|
||||||
|
var title_elements = $(html).filter('title').add($(html).find('title'));
|
||||||
|
var title = title_elements.last().text();
|
||||||
|
if (title) {
|
||||||
|
title_elements.remove(); /* Remove any title elements from the response */
|
||||||
|
document.title = $.trim(title); /* Set the new document title */
|
||||||
|
}
|
||||||
|
var content = xhr.getResponseHeader('web2py-component-content');
|
||||||
|
if(content == 'prepend') t.prepend(xhr.responseText);
|
||||||
|
else if(content == 'append') t.append(xhr.responseText);
|
||||||
|
else if(content != 'hide') t.html(html);
|
||||||
|
},
|
||||||
calc_entropy: function (mystring) {
|
calc_entropy: function (mystring) {
|
||||||
/* calculate a simple entropy for a given string */
|
/* calculate a simple entropy for a given string */
|
||||||
var csets = new Array(
|
var csets = new Array(
|
||||||
@@ -569,9 +580,9 @@
|
|||||||
}
|
}
|
||||||
if(target == undefined) {
|
if(target == undefined) {
|
||||||
if(method == 'GET') {
|
if(method == 'GET') {
|
||||||
web2py.ajax_page('get', action, [], 'bogus', el); //fixme?
|
web2py.ajax_page('get', action, [], '', el);
|
||||||
} else if(method == 'POST') {
|
} else if(method == 'POST') {
|
||||||
web2py.ajax_page('post', action, [], 'bogus', el); //fixme?
|
web2py.ajax_page('post', action, [], '', el);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if(method == 'GET') {
|
if(method == 'GET') {
|
||||||
@@ -689,3 +700,4 @@ web2py_trap_link = jQuery.web2py.trap_link;
|
|||||||
web2py_calc_entropy = jQuery.web2py.calc_entropy;
|
web2py_calc_entropy = jQuery.web2py.calc_entropy;
|
||||||
*/
|
*/
|
||||||
/* compatibility code - end*/
|
/* compatibility code - end*/
|
||||||
|
|
||||||
|
|||||||
@@ -30,6 +30,4 @@ jQuery(function(){
|
|||||||
hoverMenu(); // first page load
|
hoverMenu(); // first page load
|
||||||
jQuery(window).resize(hoverMenu); // on resize event
|
jQuery(window).resize(hoverMenu); // on resize event
|
||||||
jQuery('ul.nav li.dropdown a').click(function(){window.location=jQuery(this).attr('href');});
|
jQuery('ul.nav li.dropdown a').click(function(){window.location=jQuery(this).attr('href');});
|
||||||
// make all buttons bootstrap buttons
|
|
||||||
jQuery('button, form input[type="submit"], form input[type="button"]').addClass('btn');
|
|
||||||
});
|
});
|
||||||
@@ -79,8 +79,8 @@
|
|||||||
return marker;
|
return marker;
|
||||||
}
|
}
|
||||||
|
|
||||||
{{if filetype=='html':}}
|
{{if filetype in ('html', 'js', 'css'):}}
|
||||||
// must be here or break emmet/zencoding for html
|
// must be here or break emmet/zencoding
|
||||||
CodeMirror.defaults.extraKeys["Ctrl-S"] =
|
CodeMirror.defaults.extraKeys["Ctrl-S"] =
|
||||||
function(instance) {
|
function(instance) {
|
||||||
doClickSave();};
|
doClickSave();};
|
||||||
|
|||||||
@@ -277,6 +277,8 @@
|
|||||||
ajax_page: function (method, action, data, target, element) {
|
ajax_page: function (method, action, data, target, element) {
|
||||||
/* element is a new parameter, but should be put be put in front */
|
/* element is a new parameter, but should be put be put in front */
|
||||||
if(element == undefined) element = $(document);
|
if(element == undefined) element = $(document);
|
||||||
|
/* if target is not there, fill it with something that there isn't in the page*/
|
||||||
|
if(target == undefined || target == '') target = 'w2p_none';
|
||||||
if(web2py.fire(element, 'ajax:before', null, target )) { /*test a usecase, should stop here if returns false */
|
if(web2py.fire(element, 'ajax:before', null, target )) { /*test a usecase, should stop here if returns false */
|
||||||
$.ajax({
|
$.ajax({
|
||||||
'type': method,
|
'type': method,
|
||||||
@@ -303,12 +305,7 @@
|
|||||||
},
|
},
|
||||||
'complete': function (xhr, status) {
|
'complete': function (xhr, status) {
|
||||||
web2py.fire(element, 'ajax:complete', [xhr, status], target);
|
web2py.fire(element, 'ajax:complete', [xhr, status], target);
|
||||||
var html = xhr.responseText;
|
web2py.updatePage(xhr, target); /* Parse and load the html received */
|
||||||
var content = xhr.getResponseHeader('web2py-component-content');
|
|
||||||
var t = $('#' + target);
|
|
||||||
if(content == 'prepend') t.prepend(html);
|
|
||||||
else if(content == 'append') t.append(html);
|
|
||||||
else if(content != 'hide') t.html(html);
|
|
||||||
web2py.trap_form(action, target);
|
web2py.trap_form(action, target);
|
||||||
web2py.trap_link(target);
|
web2py.trap_link(target);
|
||||||
web2py.ajax_init('#' + target);
|
web2py.ajax_init('#' + target);
|
||||||
@@ -378,6 +375,20 @@
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
updatePage: function (xhr, target) {
|
||||||
|
var t = $('#' + target);
|
||||||
|
var html = $.parseHTML(xhr.responseText, document, true);
|
||||||
|
var title_elements = $(html).filter('title').add($(html).find('title'));
|
||||||
|
var title = title_elements.last().text();
|
||||||
|
if (title) {
|
||||||
|
title_elements.remove(); /* Remove any title elements from the response */
|
||||||
|
document.title = $.trim(title); /* Set the new document title */
|
||||||
|
}
|
||||||
|
var content = xhr.getResponseHeader('web2py-component-content');
|
||||||
|
if(content == 'prepend') t.prepend(xhr.responseText);
|
||||||
|
else if(content == 'append') t.append(xhr.responseText);
|
||||||
|
else if(content != 'hide') t.html(html);
|
||||||
|
},
|
||||||
calc_entropy: function (mystring) {
|
calc_entropy: function (mystring) {
|
||||||
/* calculate a simple entropy for a given string */
|
/* calculate a simple entropy for a given string */
|
||||||
var csets = new Array(
|
var csets = new Array(
|
||||||
@@ -569,9 +580,9 @@
|
|||||||
}
|
}
|
||||||
if(target == undefined) {
|
if(target == undefined) {
|
||||||
if(method == 'GET') {
|
if(method == 'GET') {
|
||||||
web2py.ajax_page('get', action, [], 'bogus', el); //fixme?
|
web2py.ajax_page('get', action, [], '', el);
|
||||||
} else if(method == 'POST') {
|
} else if(method == 'POST') {
|
||||||
web2py.ajax_page('post', action, [], 'bogus', el); //fixme?
|
web2py.ajax_page('post', action, [], '', el);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if(method == 'GET') {
|
if(method == 'GET') {
|
||||||
@@ -689,3 +700,4 @@ web2py_trap_link = jQuery.web2py.trap_link;
|
|||||||
web2py_calc_entropy = jQuery.web2py.calc_entropy;
|
web2py_calc_entropy = jQuery.web2py.calc_entropy;
|
||||||
*/
|
*/
|
||||||
/* compatibility code - end*/
|
/* compatibility code - end*/
|
||||||
|
|
||||||
|
|||||||
@@ -30,6 +30,4 @@ jQuery(function(){
|
|||||||
hoverMenu(); // first page load
|
hoverMenu(); // first page load
|
||||||
jQuery(window).resize(hoverMenu); // on resize event
|
jQuery(window).resize(hoverMenu); // on resize event
|
||||||
jQuery('ul.nav li.dropdown a').click(function(){window.location=jQuery(this).attr('href');});
|
jQuery('ul.nav li.dropdown a').click(function(){window.location=jQuery(this).attr('href');});
|
||||||
// make all buttons bootstrap buttons
|
|
||||||
jQuery('button, form input[type="submit"], form input[type="button"]').addClass('btn');
|
|
||||||
});
|
});
|
||||||
@@ -277,6 +277,8 @@
|
|||||||
ajax_page: function (method, action, data, target, element) {
|
ajax_page: function (method, action, data, target, element) {
|
||||||
/* element is a new parameter, but should be put be put in front */
|
/* element is a new parameter, but should be put be put in front */
|
||||||
if(element == undefined) element = $(document);
|
if(element == undefined) element = $(document);
|
||||||
|
/* if target is not there, fill it with something that there isn't in the page*/
|
||||||
|
if(target == undefined || target == '') target = 'w2p_none';
|
||||||
if(web2py.fire(element, 'ajax:before', null, target )) { /*test a usecase, should stop here if returns false */
|
if(web2py.fire(element, 'ajax:before', null, target )) { /*test a usecase, should stop here if returns false */
|
||||||
$.ajax({
|
$.ajax({
|
||||||
'type': method,
|
'type': method,
|
||||||
@@ -303,12 +305,7 @@
|
|||||||
},
|
},
|
||||||
'complete': function (xhr, status) {
|
'complete': function (xhr, status) {
|
||||||
web2py.fire(element, 'ajax:complete', [xhr, status], target);
|
web2py.fire(element, 'ajax:complete', [xhr, status], target);
|
||||||
var html = xhr.responseText;
|
web2py.updatePage(xhr, target); /* Parse and load the html received */
|
||||||
var content = xhr.getResponseHeader('web2py-component-content');
|
|
||||||
var t = $('#' + target);
|
|
||||||
if(content == 'prepend') t.prepend(html);
|
|
||||||
else if(content == 'append') t.append(html);
|
|
||||||
else if(content != 'hide') t.html(html);
|
|
||||||
web2py.trap_form(action, target);
|
web2py.trap_form(action, target);
|
||||||
web2py.trap_link(target);
|
web2py.trap_link(target);
|
||||||
web2py.ajax_init('#' + target);
|
web2py.ajax_init('#' + target);
|
||||||
@@ -378,6 +375,20 @@
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
updatePage: function (xhr, target) {
|
||||||
|
var t = $('#' + target);
|
||||||
|
var html = $.parseHTML(xhr.responseText, document, true);
|
||||||
|
var title_elements = $(html).filter('title').add($(html).find('title'));
|
||||||
|
var title = title_elements.last().text();
|
||||||
|
if (title) {
|
||||||
|
title_elements.remove(); /* Remove any title elements from the response */
|
||||||
|
document.title = $.trim(title); /* Set the new document title */
|
||||||
|
}
|
||||||
|
var content = xhr.getResponseHeader('web2py-component-content');
|
||||||
|
if(content == 'prepend') t.prepend(xhr.responseText);
|
||||||
|
else if(content == 'append') t.append(xhr.responseText);
|
||||||
|
else if(content != 'hide') t.html(html);
|
||||||
|
},
|
||||||
calc_entropy: function (mystring) {
|
calc_entropy: function (mystring) {
|
||||||
/* calculate a simple entropy for a given string */
|
/* calculate a simple entropy for a given string */
|
||||||
var csets = new Array(
|
var csets = new Array(
|
||||||
@@ -569,9 +580,9 @@
|
|||||||
}
|
}
|
||||||
if(target == undefined) {
|
if(target == undefined) {
|
||||||
if(method == 'GET') {
|
if(method == 'GET') {
|
||||||
web2py.ajax_page('get', action, [], 'bogus', el); //fixme?
|
web2py.ajax_page('get', action, [], '', el);
|
||||||
} else if(method == 'POST') {
|
} else if(method == 'POST') {
|
||||||
web2py.ajax_page('post', action, [], 'bogus', el); //fixme?
|
web2py.ajax_page('post', action, [], '', el);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if(method == 'GET') {
|
if(method == 'GET') {
|
||||||
@@ -689,3 +700,4 @@ web2py_trap_link = jQuery.web2py.trap_link;
|
|||||||
web2py_calc_entropy = jQuery.web2py.calc_entropy;
|
web2py_calc_entropy = jQuery.web2py.calc_entropy;
|
||||||
*/
|
*/
|
||||||
/* compatibility code - end*/
|
/* compatibility code - end*/
|
||||||
|
|
||||||
|
|||||||
@@ -30,6 +30,4 @@ jQuery(function(){
|
|||||||
hoverMenu(); // first page load
|
hoverMenu(); // first page load
|
||||||
jQuery(window).resize(hoverMenu); // on resize event
|
jQuery(window).resize(hoverMenu); // on resize event
|
||||||
jQuery('ul.nav li.dropdown a').click(function(){window.location=jQuery(this).attr('href');});
|
jQuery('ul.nav li.dropdown a').click(function(){window.location=jQuery(this).attr('href');});
|
||||||
// make all buttons bootstrap buttons
|
|
||||||
jQuery('button, form input[type="submit"], form input[type="button"]').addClass('btn');
|
|
||||||
});
|
});
|
||||||
@@ -5,7 +5,7 @@
|
|||||||
Usage:
|
Usage:
|
||||||
Install py2exe: http://sourceforge.net/projects/py2exe/files/
|
Install py2exe: http://sourceforge.net/projects/py2exe/files/
|
||||||
Copy script to the web2py directory
|
Copy script to the web2py directory
|
||||||
c:\bin\python26\python build_windows_exe.py py2exe
|
c:\bin\python26\python setup_exe.py py2exe
|
||||||
|
|
||||||
Adapted from http://bazaar.launchpad.net/~flavour/sahana-eden/trunk/view/head:/static/scripts/tools/standalone_exe.py
|
Adapted from http://bazaar.launchpad.net/~flavour/sahana-eden/trunk/view/head:/static/scripts/tools/standalone_exe.py
|
||||||
"""
|
"""
|
||||||
@@ -42,18 +42,18 @@ remove_build_files = Config.getboolean("Setup", "remove_build_files")
|
|||||||
|
|
||||||
|
|
||||||
# Python base version
|
# Python base version
|
||||||
python_version = sys.version[:3]
|
python_version = sys.version_info[:3]
|
||||||
|
|
||||||
# List of modules deprecated in python2.6 that are in the above set
|
# List of modules deprecated in python2.6 that are in the above set
|
||||||
py26_deprecated = ['mhlib', 'multifile', 'mimify', 'sets', 'MimeWriter']
|
py26_deprecated = ['mhlib', 'multifile', 'mimify', 'sets', 'MimeWriter']
|
||||||
|
|
||||||
if python_version == '2.6':
|
if python_version > (2,5):
|
||||||
base_modules += ['json', 'multiprocessing']
|
base_modules += ['json', 'multiprocessing', 'ldap']
|
||||||
base_modules = list(set(base_modules).difference(set(py26_deprecated)))
|
base_modules = list(set(base_modules).difference(set(py26_deprecated)))
|
||||||
|
|
||||||
|
|
||||||
#I don't know if this is even necessary
|
#I don't know if this is even necessary
|
||||||
if python_version == '2.6':
|
if python_version > (2,5):
|
||||||
# Python26 compatibility: http://www.py2exe.org/index.cgi/Tutorial#Step52
|
# Python26 compatibility: http://www.py2exe.org/index.cgi/Tutorial#Step52
|
||||||
try:
|
try:
|
||||||
shutil.copytree('C:\Bin\Microsoft.VC90.CRT', 'dist/')
|
shutil.copytree('C:\Bin\Microsoft.VC90.CRT', 'dist/')
|
||||||
@@ -62,8 +62,11 @@ if python_version == '2.6':
|
|||||||
|
|
||||||
|
|
||||||
setup(
|
setup(
|
||||||
console=['web2py.py'],
|
console=[{'script':'web2py.py',
|
||||||
|
'icon_resources': [(0, 'extras/icons/web2py.ico')]
|
||||||
|
}],
|
||||||
windows=[{'script':'web2py.py',
|
windows=[{'script':'web2py.py',
|
||||||
|
'icon_resources': [(1, 'extras/icons/web2py.ico')],
|
||||||
'dest_base':'web2py_no_console' # MUST NOT be just 'web2py' otherwise it overrides the standard web2py.exe
|
'dest_base':'web2py_no_console' # MUST NOT be just 'web2py' otherwise it overrides the standard web2py.exe
|
||||||
}],
|
}],
|
||||||
name="web2py",
|
name="web2py",
|
||||||
@@ -72,14 +75,9 @@ setup(
|
|||||||
author="Massimo DiPierro",
|
author="Massimo DiPierro",
|
||||||
license="LGPL v3",
|
license="LGPL v3",
|
||||||
data_files=[
|
data_files=[
|
||||||
'ABOUT',
|
'ABOUT',
|
||||||
'LICENSE',
|
'LICENSE',
|
||||||
'VERSION',
|
'VERSION'
|
||||||
'splashlogo.gif',
|
|
||||||
'logging.example.conf',
|
|
||||||
'options_std.py',
|
|
||||||
'app.example.yaml',
|
|
||||||
'queue.example.yaml'
|
|
||||||
],
|
],
|
||||||
options={'py2exe': {
|
options={'py2exe': {
|
||||||
'packages': contributed_modules,
|
'packages': contributed_modules,
|
||||||
@@ -126,6 +124,10 @@ else:
|
|||||||
copy_folders('applications/examples', 'applications/examples')
|
copy_folders('applications/examples', 'applications/examples')
|
||||||
print "Only web2py's admin, examples & welcome applications have been added"
|
print "Only web2py's admin, examples & welcome applications have been added"
|
||||||
|
|
||||||
|
copy_folders('extras', 'extras')
|
||||||
|
copy_folders('examples', 'examples')
|
||||||
|
copy_folders('handlers', 'handlers')
|
||||||
|
|
||||||
|
|
||||||
#should we copy project's site-packages into dist/site-packages
|
#should we copy project's site-packages into dist/site-packages
|
||||||
if copy_site_packages:
|
if copy_site_packages:
|
||||||
|
|||||||
+1
-1
@@ -10,7 +10,7 @@ Web2Py framework modules
|
|||||||
========================
|
========================
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__all__ = ['A', 'B', 'BEAUTIFY', 'BODY', 'BR', 'CAT', 'CENTER', 'CLEANUP', 'CODE', 'CRYPT', 'DAL', 'DIV', 'EM', 'EMBED', 'FIELDSET', 'FORM', 'Field', 'H1', 'H2', 'H3', 'H4', 'H5', 'H6', 'HEAD', 'HR', 'HTML', 'HTTP', 'I', 'IFRAME', 'IMG', 'INPUT', 'IS_ALPHANUMERIC', 'IS_DATE', 'IS_DATETIME', 'IS_DATETIME_IN_RANGE', 'IS_DATE_IN_RANGE', 'IS_DECIMAL_IN_RANGE', 'IS_EMAIL', 'IS_EMPTY_OR', 'IS_EQUAL_TO', 'IS_EXPR', 'IS_FLOAT_IN_RANGE', 'IS_IMAGE', 'IS_JSON', 'IS_INT_IN_RANGE', 'IS_IN_DB', 'IS_IN_SET', 'IS_IPV4', 'IS_LENGTH', 'IS_LIST_OF', 'IS_LOWER', 'IS_MATCH', 'IS_NOT_EMPTY', 'IS_NOT_IN_DB', 'IS_NULL_OR', 'IS_SLUG', 'IS_STRONG', 'IS_TIME', 'IS_UPLOAD_FILENAME', 'IS_UPPER', 'IS_URL', 'LABEL', 'LEGEND', 'LI', 'LINK', 'LOAD', 'MARKMIN', 'MENU', 'META', 'OBJECT', 'OL', 'ON', 'OPTGROUP', 'OPTION', 'P', 'PRE', 'SCRIPT', 'SELECT', 'SPAN', 'SQLFORM', 'SQLTABLE', 'STRONG', 'STYLE', 'TABLE', 'TAG', 'TBODY', 'TD', 'TEXTAREA', 'TFOOT', 'TH', 'THEAD', 'TITLE', 'TR', 'TT', 'UL', 'URL', 'XHTML', 'XML', 'redirect', 'current', 'embed64']
|
__all__ = ['A', 'B', 'BEAUTIFY', 'BODY', 'BR', 'CAT', 'CENTER', 'CLEANUP', 'CODE', 'CRYPT', 'DAL', 'DIV', 'EM', 'EMBED', 'FIELDSET', 'FORM', 'Field', 'H1', 'H2', 'H3', 'H4', 'H5', 'H6', 'HEAD', 'HR', 'HTML', 'HTTP', 'I', 'IFRAME', 'IMG', 'INPUT', 'IS_ALPHANUMERIC', 'IS_DATE', 'IS_DATETIME', 'IS_DATETIME_IN_RANGE', 'IS_DATE_IN_RANGE', 'IS_DECIMAL_IN_RANGE', 'IS_EMAIL', 'IS_LIST_OF_EMAILS', 'IS_EMPTY_OR', 'IS_EQUAL_TO', 'IS_EXPR', 'IS_FLOAT_IN_RANGE', 'IS_IMAGE', 'IS_JSON', 'IS_INT_IN_RANGE', 'IS_IN_DB', 'IS_IN_SET', 'IS_IPV4', 'IS_LENGTH', 'IS_LIST_OF', 'IS_LOWER', 'IS_MATCH', 'IS_NOT_EMPTY', 'IS_NOT_IN_DB', 'IS_NULL_OR', 'IS_SLUG', 'IS_STRONG', 'IS_TIME', 'IS_UPLOAD_FILENAME', 'IS_UPPER', 'IS_URL', 'LABEL', 'LEGEND', 'LI', 'LINK', 'LOAD', 'MARKMIN', 'MENU', 'META', 'OBJECT', 'OL', 'ON', 'OPTGROUP', 'OPTION', 'P', 'PRE', 'SCRIPT', 'SELECT', 'SPAN', 'SQLFORM', 'SQLTABLE', 'STRONG', 'STYLE', 'TABLE', 'TAG', 'TBODY', 'TD', 'TEXTAREA', 'TFOOT', 'TH', 'THEAD', 'TITLE', 'TR', 'TT', 'UL', 'URL', 'XHTML', 'XML', 'redirect', 'current', 'embed64']
|
||||||
|
|
||||||
from globals import current
|
from globals import current
|
||||||
from html import *
|
from html import *
|
||||||
|
|||||||
+28
-12
@@ -310,6 +310,11 @@ if not 'google' in DRIVERS:
|
|||||||
except ImportError:
|
except ImportError:
|
||||||
LOGGER.debug('no MySQL driver MySQLDB')
|
LOGGER.debug('no MySQL driver MySQLDB')
|
||||||
|
|
||||||
|
try:
|
||||||
|
import mysql.connector as mysqlconnector
|
||||||
|
DRIVERS.append("MySQL(mysqlconnector)")
|
||||||
|
except ImportError:
|
||||||
|
LOGGER.debug("no driver mysql.connector")
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import psycopg2
|
import psycopg2
|
||||||
@@ -2150,9 +2155,15 @@ class BaseAdapter(ConnectionPool):
|
|||||||
for row in rowsobj.records:
|
for row in rowsobj.records:
|
||||||
box = row[tablename]
|
box = row[tablename]
|
||||||
for f,v in fields_virtual:
|
for f,v in fields_virtual:
|
||||||
box[f] = v.f(row)
|
try:
|
||||||
|
box[f] = v.f(row)
|
||||||
|
except AttributeError:
|
||||||
|
pass # not enough fields to define virtual field
|
||||||
for f,v in fields_lazy:
|
for f,v in fields_lazy:
|
||||||
box[f] = (v.handler or VirtualCommand)(v.f,row)
|
try:
|
||||||
|
box[f] = (v.handler or VirtualCommand)(v.f,row)
|
||||||
|
except AttributeError:
|
||||||
|
pass # not enough fields to define virtual field
|
||||||
|
|
||||||
### old style virtual fields
|
### old style virtual fields
|
||||||
for item in table.virtualfields:
|
for item in table.virtualfields:
|
||||||
@@ -2439,7 +2450,7 @@ class JDBCSQLiteAdapter(SQLiteAdapter):
|
|||||||
|
|
||||||
|
|
||||||
class MySQLAdapter(BaseAdapter):
|
class MySQLAdapter(BaseAdapter):
|
||||||
drivers = ('MySQLdb','pymysql')
|
drivers = ('MySQLdb','pymysql', 'mysqlconnector')
|
||||||
|
|
||||||
commit_on_alter_table = True
|
commit_on_alter_table = True
|
||||||
support_distributed_transaction = True
|
support_distributed_transaction = True
|
||||||
@@ -6498,9 +6509,10 @@ class IMAPAdapter(NoSQLAdapter):
|
|||||||
def _insert(self, table, fields):
|
def _insert(self, table, fields):
|
||||||
def add_payload(message, obj):
|
def add_payload(message, obj):
|
||||||
payload = Message()
|
payload = Message()
|
||||||
charset = obj.get("encoding", "utf-8")
|
payload.set_charset(obj.get("encoding", "utf-8"))
|
||||||
payload.set_type(obj.get("mime", None))
|
mime = obj.get("mime", None)
|
||||||
payload.set_charset(charset)
|
if mime:
|
||||||
|
payload.set_type(mime)
|
||||||
if "text" in obj:
|
if "text" in obj:
|
||||||
payload.set_payload(obj["text"])
|
payload.set_payload(obj["text"])
|
||||||
elif "payload" in obj:
|
elif "payload" in obj:
|
||||||
@@ -6538,7 +6550,9 @@ class IMAPAdapter(NoSQLAdapter):
|
|||||||
else:
|
else:
|
||||||
message[item] = ";".join([i for i in
|
message[item] = ";".join([i for i in
|
||||||
value])
|
value])
|
||||||
if not message.is_multipart():
|
if (not message.is_multipart() and
|
||||||
|
(not message.get_content_type().startswith(
|
||||||
|
"multipart"))):
|
||||||
if isinstance(content, basestring):
|
if isinstance(content, basestring):
|
||||||
message.set_payload(content)
|
message.set_payload(content)
|
||||||
elif len(content) > 0:
|
elif len(content) > 0:
|
||||||
@@ -8443,8 +8457,10 @@ class Table(object):
|
|||||||
clones.append(field.clone(
|
clones.append(field.clone(
|
||||||
unique=False, type=field.type if nfk else 'bigint'))
|
unique=False, type=field.type if nfk else 'bigint'))
|
||||||
archive_db.define_table(
|
archive_db.define_table(
|
||||||
archive_name, Field(current_record,field_type,
|
archive_name,
|
||||||
label=current_record_label), *clones)
|
Field(current_record,field_type,label=current_record_label),
|
||||||
|
*clones,**dict(format=self._format))
|
||||||
|
|
||||||
self._before_update.append(
|
self._before_update.append(
|
||||||
lambda qset,fs,db=archive_db,an=archive_name,cn=current_record:
|
lambda qset,fs,db=archive_db,an=archive_name,cn=current_record:
|
||||||
archive_record(qset,fs,db[an],cn))
|
archive_record(qset,fs,db[an],cn))
|
||||||
@@ -9203,13 +9219,13 @@ class Expression(object):
|
|||||||
|
|
||||||
def startswith(self, value):
|
def startswith(self, value):
|
||||||
db = self.db
|
db = self.db
|
||||||
if not self.type in ('string', 'text', 'json'):
|
if not self.type in ('string', 'text', 'json', 'upload'):
|
||||||
raise SyntaxError("startswith used with incompatible field type")
|
raise SyntaxError("startswith used with incompatible field type")
|
||||||
return Query(db, db._adapter.STARTSWITH, self, value)
|
return Query(db, db._adapter.STARTSWITH, self, value)
|
||||||
|
|
||||||
def endswith(self, value):
|
def endswith(self, value):
|
||||||
db = self.db
|
db = self.db
|
||||||
if not self.type in ('string', 'text', 'json'):
|
if not self.type in ('string', 'text', 'json', 'upload'):
|
||||||
raise SyntaxError("endswith used with incompatible field type")
|
raise SyntaxError("endswith used with incompatible field type")
|
||||||
return Query(db, db._adapter.ENDSWITH, self, value)
|
return Query(db, db._adapter.ENDSWITH, self, value)
|
||||||
|
|
||||||
@@ -9227,7 +9243,7 @@ class Expression(object):
|
|||||||
return self.contains('')
|
return self.contains('')
|
||||||
else:
|
else:
|
||||||
return reduce(all and AND or OR,subqueries)
|
return reduce(all and AND or OR,subqueries)
|
||||||
if not self.type in ('string', 'text', 'json') and not self.type.startswith('list:'):
|
if not self.type in ('string', 'text', 'json', 'upload') and not self.type.startswith('list:'):
|
||||||
raise SyntaxError("contains used with incompatible field type")
|
raise SyntaxError("contains used with incompatible field type")
|
||||||
return Query(db, db._adapter.CONTAINS, self, value, case_sensitive=case_sensitive)
|
return Query(db, db._adapter.CONTAINS, self, value, case_sensitive=case_sensitive)
|
||||||
|
|
||||||
|
|||||||
+81
-39
@@ -211,12 +211,12 @@ class Request(Storage):
|
|||||||
body.seek(0)
|
body.seek(0)
|
||||||
|
|
||||||
# parse POST variables on POST, PUT, BOTH only in post_vars
|
# parse POST variables on POST, PUT, BOTH only in post_vars
|
||||||
if (body and
|
if (body and not is_json
|
||||||
env.request_method in ('POST', 'PUT', 'DELETE', 'BOTH') and
|
and env.request_method in ('POST', 'PUT', 'DELETE', 'BOTH')):
|
||||||
not is_json):
|
query_string = env.pop('QUERY_STRING',None)
|
||||||
query_string = env.pop('QUERY_STRING') if 'QUERY_STRING' in env else None
|
|
||||||
dpost = cgi.FieldStorage(fp=body, environ=env, keep_blank_values=1)
|
dpost = cgi.FieldStorage(fp=body, environ=env, keep_blank_values=1)
|
||||||
post_vars.update(dpost)
|
if len(dpost):
|
||||||
|
post_vars.update(dpost)
|
||||||
if query_string is not None:
|
if query_string is not None:
|
||||||
env['QUERY_STRING'] = query_string
|
env['QUERY_STRING'] = query_string
|
||||||
# The same detection used by FieldStorage to detect multipart POSTs
|
# The same detection used by FieldStorage to detect multipart POSTs
|
||||||
@@ -232,19 +232,13 @@ class Request(Storage):
|
|||||||
if key is None:
|
if key is None:
|
||||||
continue # not sure why cgi.FieldStorage returns None key
|
continue # not sure why cgi.FieldStorage returns None key
|
||||||
dpk = dpost[key]
|
dpk = dpost[key]
|
||||||
# if an element is not a file replace it with its value else leave it alone
|
# if an element is not a file replace it with
|
||||||
if isinstance(dpk, list):
|
# its value else leave it alone
|
||||||
value = []
|
|
||||||
for _dpk in dpk:
|
pvalue = listify([(_dpk if _dpk.filename else _dpk.value)
|
||||||
if not _dpk.filename:
|
for _dpk in dpk]
|
||||||
value.append(_dpk.value)
|
if isinstance(dpk, list) else
|
||||||
else:
|
(dpk if dpk.filename else dpk.value))
|
||||||
value.append(_dpk)
|
|
||||||
elif not dpk.filename:
|
|
||||||
value = dpk.value
|
|
||||||
else:
|
|
||||||
value = dpk
|
|
||||||
pvalue = listify(value)
|
|
||||||
if len(pvalue):
|
if len(pvalue):
|
||||||
post_vars[key] = (len(pvalue) > 1 and pvalue) or pvalue[0]
|
post_vars[key] = (len(pvalue) > 1 and pvalue) or pvalue[0]
|
||||||
|
|
||||||
@@ -333,13 +327,12 @@ class Request(Storage):
|
|||||||
_self.args[-1], _, self.extension = self.args[-1].rpartition('.')
|
_self.args[-1], _, self.extension = self.args[-1].rpartition('.')
|
||||||
current.response.headers['Content-Type'] = \
|
current.response.headers['Content-Type'] = \
|
||||||
contenttype('.' + _self.extension.lower())
|
contenttype('.' + _self.extension.lower())
|
||||||
if not method in ['GET', 'POST', 'DELETE', 'PUT']:
|
|
||||||
raise HTTP(400, "invalid method")
|
|
||||||
rest_action = _action().get(method, None)
|
rest_action = _action().get(method, None)
|
||||||
if not rest_action:
|
if not (rest_action and method==method.upper()
|
||||||
|
and callable(rest_action)):
|
||||||
raise HTTP(400, "method not supported")
|
raise HTTP(400, "method not supported")
|
||||||
try:
|
try:
|
||||||
return rest_action(*_self.args, **_self.vars)
|
return rest_action(*_self.args, **getattr(_self,'vars',{}))
|
||||||
except TypeError, e:
|
except TypeError, e:
|
||||||
exc_type, exc_value, exc_traceback = sys.exc_info()
|
exc_type, exc_value, exc_traceback = sys.exc_info()
|
||||||
if len(traceback.extract_tb(exc_traceback)) == 1:
|
if len(traceback.extract_tb(exc_traceback)) == 1:
|
||||||
@@ -742,10 +735,11 @@ class Session(Storage):
|
|||||||
response.session_cookie_compression_level = compression_level
|
response.session_cookie_compression_level = compression_level
|
||||||
|
|
||||||
# check if there is a session_id in cookies
|
# check if there is a session_id in cookies
|
||||||
try:
|
try:
|
||||||
response.session_id = cookies[response.session_id_name].value
|
old_session_id = cookies[response.session_id_name].value
|
||||||
except KeyError:
|
except KeyError:
|
||||||
response.session_id = None
|
old_session_id = None
|
||||||
|
response.session_id = old_session_id
|
||||||
|
|
||||||
# if we are supposed to use cookie based session data
|
# if we are supposed to use cookie based session data
|
||||||
if cookie_key:
|
if cookie_key:
|
||||||
@@ -865,12 +859,30 @@ class Session(Storage):
|
|||||||
else:
|
else:
|
||||||
response.session_id = None
|
response.session_id = None
|
||||||
response.session_new = True
|
response.session_new = True
|
||||||
|
# if there is no session id yet, we'll need to create a
|
||||||
|
# new session
|
||||||
|
else:
|
||||||
|
response.session_new = True
|
||||||
|
|
||||||
|
# set the cookie now if you know the session_id so user can set
|
||||||
|
# cookie attributes in controllers/models
|
||||||
|
# cookie will be reset later
|
||||||
|
# yet cookie may be reset later
|
||||||
|
# Removed comparison between old and new session ids - should send
|
||||||
|
# the cookie all the time
|
||||||
|
if isinstance(response.session_id,str):
|
||||||
|
response.cookies[response.session_id_name] = response.session_id
|
||||||
|
response.cookies[response.session_id_name]['path'] = '/'
|
||||||
|
if cookie_expires:
|
||||||
|
response.cookies[response.session_id_name]['expires'] = \
|
||||||
|
cookie_expires.strftime(FMT)
|
||||||
|
|
||||||
|
session_pickled = cPickle.dumps(self)
|
||||||
|
response.session_hash = hashlib.md5(session_pickled).hexdigest()
|
||||||
|
|
||||||
if self.flash:
|
if self.flash:
|
||||||
(response.flash, self.flash) = (self.flash, None)
|
(response.flash, self.flash) = (self.flash, None)
|
||||||
|
|
||||||
session_pickled = cPickle.dumps(self)
|
|
||||||
response.session_hash = hashlib.md5(session_pickled).hexdigest()
|
|
||||||
|
|
||||||
def renew(self, clear_session=False):
|
def renew(self, clear_session=False):
|
||||||
|
|
||||||
@@ -929,6 +941,30 @@ class Session(Storage):
|
|||||||
else:
|
else:
|
||||||
response.session_new = True
|
response.session_new = True
|
||||||
|
|
||||||
|
def _fixup_before_save(self):
|
||||||
|
response = current.response
|
||||||
|
rcookies = response.cookies
|
||||||
|
if self._forget and response.session_id_name in rcookies:
|
||||||
|
del rcookies[response.session_id_name]
|
||||||
|
elif self._secure and response.session_id_name in rcookies:
|
||||||
|
rcookies[response.session_id_name]['secure'] = True
|
||||||
|
|
||||||
|
def clear_session_cookies(sefl):
|
||||||
|
request = current.request
|
||||||
|
response = current.response
|
||||||
|
session = response.session
|
||||||
|
masterapp = response.session_masterapp
|
||||||
|
cookies = request.cookies
|
||||||
|
rcookies = response.cookies
|
||||||
|
# if not cookie_key, but session_data_name in cookies
|
||||||
|
# expire session_data_name from cookies
|
||||||
|
if response.session_data_name in cookies:
|
||||||
|
rcookies[response.session_data_name] = 'expired'
|
||||||
|
rcookies[response.session_data_name]['path'] = '/'
|
||||||
|
rcookies[response.session_data_name]['expires'] = PAST
|
||||||
|
if response.session_id_name in rcookies:
|
||||||
|
del rcookies[response.session_id_name]
|
||||||
|
|
||||||
def save_session_id_cookie(self):
|
def save_session_id_cookie(self):
|
||||||
request = current.request
|
request = current.request
|
||||||
response = current.response
|
response = current.response
|
||||||
@@ -946,12 +982,11 @@ class Session(Storage):
|
|||||||
if response.session_id:
|
if response.session_id:
|
||||||
rcookies[response.session_id_name] = response.session_id
|
rcookies[response.session_id_name] = response.session_id
|
||||||
rcookies[response.session_id_name]['path'] = '/'
|
rcookies[response.session_id_name]['path'] = '/'
|
||||||
if isinstance(response.session_cookie_expires,datetime.datetime):
|
expires = response.session_cookie_expires
|
||||||
rcookies[response.session_id_name]['expires'] = \
|
if isinstance(expires,datetime.datetime):
|
||||||
response.session_cookie_expires.strftime(FMT)
|
expires = expires.strftime(FMT)
|
||||||
elif isinstance(response.session_cookie_expires,str):
|
if expires:
|
||||||
rcookies[response.session_id_name]['expires'] = \
|
rcookies[response.session_id_name]['expires'] = expires
|
||||||
response.session_cookie_expires
|
|
||||||
|
|
||||||
def clear(self):
|
def clear(self):
|
||||||
Storage.clear(self)
|
Storage.clear(self)
|
||||||
@@ -981,6 +1016,7 @@ class Session(Storage):
|
|||||||
|
|
||||||
def _try_store_in_cookie(self, request, response):
|
def _try_store_in_cookie(self, request, response):
|
||||||
if self._forget or self._unchanged(response):
|
if self._forget or self._unchanged(response):
|
||||||
|
# self.clear_session_cookies()
|
||||||
self.save_session_id_cookie()
|
self.save_session_id_cookie()
|
||||||
return False
|
return False
|
||||||
name = response.session_data_name
|
name = response.session_data_name
|
||||||
@@ -988,13 +1024,15 @@ class Session(Storage):
|
|||||||
value = secure_dumps(dict(self),
|
value = secure_dumps(dict(self),
|
||||||
response.session_cookie_key,
|
response.session_cookie_key,
|
||||||
compression_level=compression_level)
|
compression_level=compression_level)
|
||||||
expires = response.session_cookie_expires
|
|
||||||
rcookies = response.cookies
|
rcookies = response.cookies
|
||||||
rcookies.pop(name, None)
|
rcookies.pop(name, None)
|
||||||
rcookies[name] = value
|
rcookies[name] = value
|
||||||
rcookies[name]['path'] = '/'
|
rcookies[name]['path'] = '/'
|
||||||
|
expires = response.session_cookie_expires
|
||||||
|
if isinstance(expires,datetime.datetime):
|
||||||
|
expires = expires.strftime(FMT)
|
||||||
if expires:
|
if expires:
|
||||||
rcookies[name]['expires'] = expires.strftime(FMT)
|
rcookies[name]['expires'] = expires
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def _unchanged(self,response):
|
def _unchanged(self,response):
|
||||||
@@ -1006,13 +1044,15 @@ class Session(Storage):
|
|||||||
def _try_store_in_db(self, request, response):
|
def _try_store_in_db(self, request, response):
|
||||||
# don't save if file-based sessions,
|
# don't save if file-based sessions,
|
||||||
# no session id, or session being forgotten
|
# no session id, or session being forgotten
|
||||||
# or no changes to session
|
# or no changes to session (Unless the session is new)
|
||||||
|
if (not response.session_db_table or
|
||||||
if not response.session_db_table or self._forget or self._unchanged(response):
|
self._forget or
|
||||||
|
(self._unchanged(response) and not response.session_new)):
|
||||||
if (not response.session_db_table and
|
if (not response.session_db_table and
|
||||||
global_settings.db_sessions is not True and
|
global_settings.db_sessions is not True and
|
||||||
response.session_masterapp in global_settings.db_sessions):
|
response.session_masterapp in global_settings.db_sessions):
|
||||||
global_settings.db_sessions.remove(response.session_masterapp)
|
global_settings.db_sessions.remove(response.session_masterapp)
|
||||||
|
# self.clear_session_cookies()
|
||||||
self.save_session_id_cookie()
|
self.save_session_id_cookie()
|
||||||
return False
|
return False
|
||||||
|
|
||||||
@@ -1050,7 +1090,9 @@ class Session(Storage):
|
|||||||
|
|
||||||
def _try_store_in_file(self, request, response):
|
def _try_store_in_file(self, request, response):
|
||||||
try:
|
try:
|
||||||
if not response.session_id or self._forget or self._unchanged(response):
|
if (not response.session_id or self._forget
|
||||||
|
or self._unchanged(response)):
|
||||||
|
# self.clear_session_cookies()
|
||||||
self.save_session_id_cookie()
|
self.save_session_id_cookie()
|
||||||
return False
|
return False
|
||||||
if response.session_new or not response.session_file:
|
if response.session_new or not response.session_file:
|
||||||
|
|||||||
+2
-2
@@ -67,8 +67,8 @@ regex_param = re.compile(r'{(?P<s>.+?)}')
|
|||||||
|
|
||||||
# pattern for a valid accept_language
|
# pattern for a valid accept_language
|
||||||
regex_language = \
|
regex_language = \
|
||||||
re.compile('([a-z]{2}(?:\-[a-z]{2})?(?:\-[a-z]{2})?)(?:[,;]|$)')
|
re.compile('([a-z]{2,3}(?:\-[a-z]{2})?(?:\-[a-z]{2})?)(?:[,;]|$)')
|
||||||
regex_langfile = re.compile('^[a-z]{2}(-[a-z]{2})?\.py$')
|
regex_langfile = re.compile('^[a-z]{2,3}(-[a-z]{2})?\.py$')
|
||||||
regex_backslash = re.compile(r"\\([\\{}%])")
|
regex_backslash = re.compile(r"\\([\\{}%])")
|
||||||
regex_plural = re.compile('%({.+?})')
|
regex_plural = re.compile('%({.+?})')
|
||||||
regex_plural_dict = re.compile('^{(?P<w>[^()[\]][^()[\]]*?)\((?P<n>[^()\[\]]+)\)}$') # %%{word(varname or number)}
|
regex_plural_dict = re.compile('^{(?P<w>[^()[\]][^()[\]]*?)\((?P<n>[^()\[\]]+)\)}$') # %%{word(varname or number)}
|
||||||
|
|||||||
+8
-10
@@ -503,12 +503,8 @@ def wsgibase(environ, responder):
|
|||||||
# store cookies in headers
|
# store cookies in headers
|
||||||
# ##################################################
|
# ##################################################
|
||||||
|
|
||||||
rcookies = response.cookies
|
session._fixup_before_save()
|
||||||
if session._forget and response.session_id_name in rcookies:
|
http_response.cookies2headers(response.cookies)
|
||||||
del rcookies[response.session_id_name]
|
|
||||||
elif session._secure:
|
|
||||||
rcookies[response.session_id_name]['secure'] = True
|
|
||||||
http_response.cookies2headers(rcookies)
|
|
||||||
|
|
||||||
ticket = None
|
ticket = None
|
||||||
|
|
||||||
@@ -612,7 +608,8 @@ def save_password(password, port):
|
|||||||
|
|
||||||
def appfactory(wsgiapp=wsgibase,
|
def appfactory(wsgiapp=wsgibase,
|
||||||
logfilename='httpserver.log',
|
logfilename='httpserver.log',
|
||||||
profiler_dir=None):
|
profiler_dir=None,
|
||||||
|
profilerfilename=None):
|
||||||
"""
|
"""
|
||||||
generates a wsgi application that does logging and profiling and calls
|
generates a wsgi application that does logging and profiling and calls
|
||||||
wsgibase
|
wsgibase
|
||||||
@@ -623,7 +620,8 @@ def appfactory(wsgiapp=wsgibase,
|
|||||||
[, profilerfilename='profiler.log']]])
|
[, profilerfilename='profiler.log']]])
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
if profilerfilename is not None:
|
||||||
|
raise BaseException("Deprecated API")
|
||||||
if profiler_dir:
|
if profiler_dir:
|
||||||
profiler_dir = abspath(profiler_dir)
|
profiler_dir = abspath(profiler_dir)
|
||||||
logger.warn('profiler is on. will use dir %s', profiler_dir)
|
logger.warn('profiler is on. will use dir %s', profiler_dir)
|
||||||
@@ -631,14 +629,14 @@ def appfactory(wsgiapp=wsgibase,
|
|||||||
try:
|
try:
|
||||||
os.makedirs(profiler_dir)
|
os.makedirs(profiler_dir)
|
||||||
except:
|
except:
|
||||||
raise BaseException, "Can't create dir %s" % profiler_dir
|
raise BaseException("Can't create dir %s" % profiler_dir)
|
||||||
filepath = pjoin(profiler_dir, 'wtest')
|
filepath = pjoin(profiler_dir, 'wtest')
|
||||||
try:
|
try:
|
||||||
filehandle = open( filepath, 'w' )
|
filehandle = open( filepath, 'w' )
|
||||||
filehandle.close()
|
filehandle.close()
|
||||||
os.unlink(filepath)
|
os.unlink(filepath)
|
||||||
except IOError:
|
except IOError:
|
||||||
raise BaseException, "Unable to write to dir %s" % profiler_dir
|
raise BaseException("Unable to write to dir %s" % profiler_dir)
|
||||||
|
|
||||||
def app_with_logging(environ, responder):
|
def app_with_logging(environ, responder):
|
||||||
"""
|
"""
|
||||||
|
|||||||
+1
-2
@@ -292,6 +292,7 @@ class ListWidget(StringWidget):
|
|||||||
_class = 'string'
|
_class = 'string'
|
||||||
requires = field.requires if isinstance(
|
requires = field.requires if isinstance(
|
||||||
field.requires, (IS_NOT_EMPTY, IS_LIST_OF)) else None
|
field.requires, (IS_NOT_EMPTY, IS_LIST_OF)) else None
|
||||||
|
if isinstance(value,str): value = [value]
|
||||||
nvalue = value or ['']
|
nvalue = value or ['']
|
||||||
items = [LI(INPUT(_id=_id, _class=_class, _name=_name,
|
items = [LI(INPUT(_id=_id, _class=_class, _name=_name,
|
||||||
value=v, hideerror=k < len(nvalue) - 1,
|
value=v, hideerror=k < len(nvalue) - 1,
|
||||||
@@ -1356,8 +1357,6 @@ class SQLFORM(FORM):
|
|||||||
value = self.record[fieldname]
|
value = self.record[fieldname]
|
||||||
else:
|
else:
|
||||||
value = self.table[fieldname].default
|
value = self.table[fieldname].default
|
||||||
if field.type.startswith('list:') and isinstance(value, str):
|
|
||||||
value = [value]
|
|
||||||
row_id = '%s_%s%s' % (
|
row_id = '%s_%s%s' % (
|
||||||
self.table, fieldname, SQLFORM.ID_ROW_SUFFIX)
|
self.table, fieldname, SQLFORM.ID_ROW_SUFFIX)
|
||||||
widget = field.widget(field, value)
|
widget = field.widget(field, value)
|
||||||
|
|||||||
+1
-1
@@ -1509,7 +1509,7 @@ class Auth(object):
|
|||||||
self.bar = SPAN(s1, Anr(items[0]['name'],
|
self.bar = SPAN(s1, Anr(items[0]['name'],
|
||||||
_href=items[0]['href']), s3,
|
_href=items[0]['href']), s3,
|
||||||
_class='auth_navbar')
|
_class='auth_navbar')
|
||||||
for item in items:
|
for item in items[1:]:
|
||||||
self.bar.insert(-1, s2)
|
self.bar.insert(-1, s2)
|
||||||
self.bar.insert(-1, Anr(item['name'], _href=item['href']))
|
self.bar.insert(-1, Anr(item['name'], _href=item['href']))
|
||||||
|
|
||||||
|
|||||||
+38
-1
@@ -42,6 +42,7 @@ __all__ = [
|
|||||||
'IS_DATETIME',
|
'IS_DATETIME',
|
||||||
'IS_DECIMAL_IN_RANGE',
|
'IS_DECIMAL_IN_RANGE',
|
||||||
'IS_EMAIL',
|
'IS_EMAIL',
|
||||||
|
'IS_LIST_OF_EMAILS',
|
||||||
'IS_EMPTY_OR',
|
'IS_EMPTY_OR',
|
||||||
'IS_EXPR',
|
'IS_EXPR',
|
||||||
'IS_FLOAT_IN_RANGE',
|
'IS_FLOAT_IN_RANGE',
|
||||||
@@ -1178,6 +1179,39 @@ class IS_EMAIL(Validator):
|
|||||||
return (value, None)
|
return (value, None)
|
||||||
return (value, translate(self.error_message))
|
return (value, translate(self.error_message))
|
||||||
|
|
||||||
|
class IS_LIST_OF_EMAILS(object):
|
||||||
|
"""
|
||||||
|
use as follows:
|
||||||
|
Field('emails','list:string',
|
||||||
|
widget=SQLFORM.widgets.text.widget,
|
||||||
|
requires=IS_LIST_OF_EMAILS(),
|
||||||
|
represent=lambda v,r: \
|
||||||
|
SPAN(*[A(x,_href='mailto:'+x) for x in (v or [])])
|
||||||
|
)
|
||||||
|
"""
|
||||||
|
split_emails = re.compile('[^,;\s]+')
|
||||||
|
def __init__(self, error_message = 'Invalid emails: %s'):
|
||||||
|
self.error_message = error_message
|
||||||
|
|
||||||
|
def __call__(self, value):
|
||||||
|
bad_emails = []
|
||||||
|
emails = []
|
||||||
|
f = IS_EMAIL()
|
||||||
|
for email in self.split_emails.findall(value):
|
||||||
|
if not email in emails:
|
||||||
|
emails.append(email)
|
||||||
|
error = f(email)[1]
|
||||||
|
if error and not email in bad_emails:
|
||||||
|
bad_emails.append(email)
|
||||||
|
if not bad_emails:
|
||||||
|
return (value, None)
|
||||||
|
else:
|
||||||
|
return (value,
|
||||||
|
translate(self.error_message) % ', '.join(bad_emails))
|
||||||
|
|
||||||
|
def formatter(self,value,row=None):
|
||||||
|
return ', '.join(value or [])
|
||||||
|
|
||||||
|
|
||||||
# URL scheme source:
|
# URL scheme source:
|
||||||
# <http://en.wikipedia.org/wiki/URI_scheme> obtained on 2008-Nov-10
|
# <http://en.wikipedia.org/wiki/URI_scheme> obtained on 2008-Nov-10
|
||||||
@@ -2890,7 +2924,8 @@ class CRYPT(object):
|
|||||||
key=None,
|
key=None,
|
||||||
digest_alg='pbkdf2(1000,20,sha512)',
|
digest_alg='pbkdf2(1000,20,sha512)',
|
||||||
min_length=0,
|
min_length=0,
|
||||||
error_message='too short', salt=True):
|
error_message='too short', salt=True,
|
||||||
|
max_length=1024):
|
||||||
"""
|
"""
|
||||||
important, digest_alg='md5' is not the default hashing algorithm for
|
important, digest_alg='md5' is not the default hashing algorithm for
|
||||||
web2py. This is only an example of usage of this function.
|
web2py. This is only an example of usage of this function.
|
||||||
@@ -2901,10 +2936,12 @@ class CRYPT(object):
|
|||||||
self.key = key
|
self.key = key
|
||||||
self.digest_alg = digest_alg
|
self.digest_alg = digest_alg
|
||||||
self.min_length = min_length
|
self.min_length = min_length
|
||||||
|
self.max_length = max_length
|
||||||
self.error_message = error_message
|
self.error_message = error_message
|
||||||
self.salt = salt
|
self.salt = salt
|
||||||
|
|
||||||
def __call__(self, value):
|
def __call__(self, value):
|
||||||
|
value = value and value[:self.max_length]
|
||||||
if len(value) < self.min_length:
|
if len(value) < self.min_length:
|
||||||
return ('', translate(self.error_message))
|
return ('', translate(self.error_message))
|
||||||
return (LazyCrypt(self, value), None)
|
return (LazyCrypt(self, value), None)
|
||||||
|
|||||||
Reference in New Issue
Block a user