Compare commits

..

204 Commits

Author SHA1 Message Date
2efa54a2d7 remove useless imports. 2019-12-12 18:03:10 +00:00
f5cdf17c48 fix wrong redis server host. 2019-12-12 15:07:23 +00:00
3272755fea better structure in the redis test class. 2019-12-12 15:00:37 +00:00
022ddd49c4 fixed convertions for compatibility with Python3. Add further testing of redis sessions functions. 2019-12-12 14:37:41 +00:00
8f84b5df34 fix lambda definition. 2019-12-11 19:09:51 +00:00
223755d894 fix missing pip install redis. 2019-12-11 19:06:19 +00:00
981254ec61 add test_redis to gluon init. 2019-12-11 18:55:14 +00:00
ce917feb7e Fix redis_session types for new redis client. Add testing in travis and appveyor.yml 2019-12-11 18:31:44 +00:00
bad0d0b26b Start new testing of redis_session and save redis session table information so we can recover data from redis in the native format. 2019-12-05 19:53:20 +00:00
517f88891f Add a test that simulates redis session usage. 2019-12-05 19:26:40 +00:00
mdipierro
c44c2b06d3 Merge branch 'master' of github.com:web2py/web2py 2019-11-02 23:09:04 -07:00
mdipierro
eda8277fbd removed unwanted import that breaks python3.8 2019-11-02 20:09:47 -07:00
mdipierro
21afb0933e Merge pull request #2270 from tomodachi/freeipa_auth
Add support for freeIPA ldap auth
2019-10-27 21:27:40 -07:00
mdipierro
90fc9ea622 Merge pull request #2269 from bmiklautz/spawn_v2
Fix scheduler issue on linux related to multiprocessing
2019-10-27 21:27:04 -07:00
mdipierro
61976e7c3a Merge pull request #2267 from nicozanf/master
Fix broken inframe Vimeo video
2019-10-27 21:25:20 -07:00
Mateusz Mojsiejuk
a0eac8fce7 Add support for freeIPA ldap auth 2019-10-25 15:52:11 +02:00
Bernhard Miklautz
7038758960 new [scheduler]: add parameter use_spawn
Add a new parameter to Scheduler to allow it to use spawn
multiprocessing method.

This is only available with python3 therefore the parameter is
ignored with python2.
2019-10-25 11:31:54 +02:00
Nico Zanferrari
77bcda3f3e Added Python 3 binaries to the download page +typo
It fixes issue #2027.

** IMPORTANT ** - before approving, you need to copy from https://github.com/nicozanf/web2py-pyinstaller to https://mdipierro.pythonanywhere.com/examples/static the files: 
- web2py_win.zip
- web2py_win_py2.zip
- web2py_osx.zip
- web2py_osx_py2.zip

And also modify the procedures for the "For Testers" versions on https://mdipierro.pythonanywhere.com/examples/static, that should use the previous ones as binaries.
2019-10-23 22:41:19 +02:00
Nico Zanferrari
92bb2c2241 Added Python 3 binaries to the download page 2019-10-23 22:05:12 +02:00
Nico Zanferrari
f7b3abdc89 Fix broken inframe Vimeo video
It fixes Issue #2068
2019-10-22 21:54:01 +02:00
mdipierro
8f98994423 fixed validate for good 2019-10-20 22:04:11 -07:00
mdipierro
cf91145db0 made validators compliant with new dal 2019-10-20 21:48:49 -07:00
mdipierro
dce5fbb472 fixed validate maybe 2019-10-20 21:43:01 -07:00
mdipierro
40485ecd88 Merge pull request #2265 from vinyldarkscratch/patch-1
Add events for form upload progress
2019-10-20 21:39:50 -07:00
mdipierro
78b529bb92 Merge pull request #2263 from jicho/master
No redirect when url ends with #
2019-10-20 21:38:36 -07:00
mdipierro
32fc729cdc Merge pull request #2225 from nicozanf/pyinstaller
Full docs for obtaining Win and Mac binaries with PyInstaller
2019-10-20 21:35:47 -07:00
Queen Vinyl Darkscratch
5bcf34aba5 Add events for form upload progress 2019-10-15 16:32:43 -07:00
jicho
e4845aeef6 No redirect when url ends with #
When a redirect url ends with a hash (#) the browser (Chrome) does not redirect/refreshes the browser.

This is happening with this setting:
```
form = SQLFORM.grid(
        query,
        client_side_delete=True
    )
```
2019-10-09 09:33:18 +02:00
mdipierro
1ce316609a Merge branch 'master' of github.com:web2py/web2py 2019-09-30 20:47:15 -07:00
mdipierro
c95b4e43d7 isostring->isoformat 2019-09-30 20:47:06 -07:00
mdipierro
501d0b8a9b Merge pull request #2260 from timnyborg/patch-11
no sleep when redis_cache set to fail gracefully
2019-09-29 19:47:13 -07:00
Tim Nyborg
2b30157cce Update redis_cache.py
moving logging as well
2019-09-25 11:06:23 +01:00
mdipierro
cbbf793841 Merge pull request #2259 from timnyborg/patch-8
correcting indentation
2019-09-21 12:00:09 -07:00
Tim Nyborg
89c392d224 correcting indentation 2019-09-17 14:48:15 +01:00
mdipierro
91fd094790 Merge branch 'master' of github.com:web2py/web2py 2019-09-09 21:13:20 -07:00
mdipierro
0f638f9cdf possibly fixed the Redis problem, thanks Rastafarian 2019-09-09 21:13:01 -07:00
mdipierro
d84cbf8763 Merge pull request #2255 from vinyldarkscratch/patch-1
Don't set form in trap_form as ajax_page element
2019-09-09 20:52:15 -07:00
mdipierro
6af98ac7bc Merge pull request #2252 from misl6/fix-user-registration-key-error
Fix user registration key error
2019-09-09 20:51:24 -07:00
mdipierro
f91eaa84e8 Merge pull request #2249 from timnyborg/patch-7
python3 compatibility for JSONRPCError
2019-09-09 20:50:47 -07:00
Queen Vinyl Darkscratch
d17572fb10 Don't set form in trap_form as ajax_page element 2019-09-05 00:02:19 -07:00
Mirko Galimberti
1dec1b4358 Checks for user availability before accessing the registration key 2019-09-02 13:50:39 +02:00
Mirko
4191d4c48c Merge pull request #2 from web2py/master
Merge w/ current master
2019-09-02 13:43:56 +02:00
Tim Nyborg
75491fb273 python3 compatibility for JSONRPCError
Trying this again, now that I learned about gluon._compat
2019-08-23 12:25:11 +01:00
mdipierro
b7202df0b9 do not test 3.5 on bionic 2019-08-18 01:11:04 -07:00
mdipierro
529444cda7 fixed a test for Decimal serializer 2019-08-18 00:47:25 -07:00
mdipierro
12d1ca739d reverting test 3.5 2019-08-18 00:21:31 -07:00
mdipierro
af151783c6 test 2019-08-18 00:20:24 -07:00
mdipierro
4a838c2c14 biopic web2py tests 2019-08-17 23:43:25 -07:00
mdipierro
42181ca263 Merge branch 'master' of github.com:web2py/web2py 2019-08-17 22:46:56 -07:00
mdipierro
8b55025cb3 serializing decimal as float, thanks villas 2019-08-17 22:46:31 -07:00
mdipierro
e0fc657b8e Merge pull request #2237 from dlage/fake_migrate
Fake migrate
2019-08-17 21:59:28 -07:00
mdipierro
619af453a6 Merge pull request #2234 from jvanbraekel/Fix-encoding-of-pdflatex-log-file
Fix encoding of pdflatex log file
2019-08-17 21:58:30 -07:00
179edb659a Load all models when using --force_migrate (same behaviour as appadmin). 2019-08-13 18:04:30 +01:00
mdipierro
019295e1d1 reverting 2c364c2079 which incorrecly assumes the scheme can only be http or https 2019-08-11 10:58:22 -07:00
mdipierro
60c68164f3 Merge pull request #2231 from dlage/patch-1
Force page reload with anchors
2019-08-11 10:45:37 -07:00
b4c2ee8304 Allow easily switching fake_migrate on to allow easier fixes of the database migrations 2019-07-25 17:15:19 +01:00
cb0c2e6edd Merge remote-tracking branch 'upstream/master' 2019-07-25 17:07:24 +01:00
jvanbraekel
37d1fca32c Enable greek symbols support
Pakage was missing form the template, leading to errors when greeks characters were used
2019-07-25 11:28:37 +02:00
jvanbraekel
251314ceb8 Only return get_vars after a failing login
Since the redirect is a GET action, there is no reason to return post vars from the failing attempt.
2019-07-24 09:43:03 +02:00
jvanbraekel
a23a068d40 Add utf-8 encoding in latex log opening
By default, open use ascii encoding leading to crash when non ascii caracters are present . Fix it by enforcing UTF-8  encoding
2019-07-23 15:52:21 +02:00
jvanbraekel
726d664292 Merge pull request #3 from web2py/master
merge web2py master changes
2019-07-23 15:38:15 +02:00
mdipierro
2c364c2079 Merge pull request #2233 from rayluo/patch-1
Better https detection
2019-07-23 00:28:17 -07:00
Ray Luo
8faa5e2a82 Better https detection
Switch to request.is_https which provides better https detection
2019-07-22 23:41:23 -07:00
Dinis
6fddca4e4f Force page reload with anchors
Force page to reload even when the location contains anchors, while using "web2py-redirect-location".
Otherwise, when the location is the same and the url has an anchor it won't redirect.
2019-07-17 15:18:44 +01:00
mdipierro
0557fe9c58 sync 2019-07-15 22:02:57 -07:00
mdipierro
5945edebfd Merge pull request #2230 from bjones1/master
Allow specification of server's encoding in webclient.
2019-07-15 22:00:33 -07:00
mdipierro
558afd886c Merge pull request #2229 from leonelcamara/patch-32
__lt__ and __gt__ for lazyT
2019-07-15 22:00:13 -07:00
mdipierro
1bc8ea6838 Merge pull request #2227 from nicozanf/bookfix
fix for py 3.6+ compatibility
2019-07-15 21:59:56 -07:00
mdipierro
24d970a943 Merge pull request #2223 from gonguinguen/patch-6
Added followlinks=True when calling listdir
2019-07-15 21:58:06 -07:00
mdipierro
e66dda8641 Merge pull request #2222 from gonguinguen/patch-5
Added followlinks argument to listdir
2019-07-15 21:57:36 -07:00
mdipierro
320a28d564 Merge pull request #2216 from web-py/patch-3
Update fa.py
2019-07-15 21:57:12 -07:00
Bryan A. Jones
9db1c6b0b0 Allow specification of server's encoding in webclient. 2019-07-12 10:23:53 -05:00
Leonel Câmara
f307fe7d56 __lt__ and __gt__ for lazyT
Fixes #2228
2019-07-10 12:25:40 +01:00
Nico Zanferrari
f845497479 fix for py 3.6+ compatibility
py 3.6+ gives errors and need more escapes - I've tested the patch on the full web2py book's latex output and it's backward compatible with 2.7. For technical details see https://bugs.python.org/issue28450 :
"Deprecated since version 3.5, will be removed in version 3.6: Unknown escapes consist of '\' and ASCII letter now raise a deprecation warning and will be forbidden in Python 3.6"
2019-07-07 00:55:39 +02:00
Nico Zanferrari
ab257031b5 Modified fake site.py from PyInstaller - for PY3 2019-07-01 22:51:25 +02:00
Nico Zanferrari
64c66000fa Modified fake site.py from PyInstaller - for PY2 2019-07-01 22:50:37 +02:00
Nico Zanferrari
c247e740a2 full docs 2019-07-01 22:49:09 +02:00
Nico Zanferrari
3fe797ce60 full docs 2019-07-01 22:42:27 +02:00
Dinis
f1f65275f7 Merge pull request #1 from web2py/master
Refresh master
2019-06-19 14:20:22 +01:00
Lisandro
2989beae02 Added followlinks=True when calling listdir
In order to solve the issue #2221, I've added followlinks=True when calling listdir() from functions compile_views(), compile_models() and compile_controllers()
2019-06-07 19:24:59 -03:00
Lisandro
2a7b16d61f Added followlinks argument to listdir
The followlinks argument is then used by the function when it calls os.walk(path...
Notice the "followlinks" argument of os.walk() is False by default, so this change won't make any difference. Every actual call to listdir() function won't need to be changed.
This change is needed to resolve issue #2221
2019-06-07 19:21:10 -03:00
mdipierro
14c1b3e400 fixed typo 2019-06-06 22:39:38 -07:00
mdipierro
8823cde350 simpler populate 2019-06-06 21:52:20 -07:00
mdipierro
3e09add351 submit->Submit, thanks Paolo Pastori 2019-06-06 21:28:56 -07:00
mdipierro
7385904f97 --force_migrate and --cron_threads, thanks Paolo Pastori 2019-06-06 21:23:31 -07:00
web-py
c82f0ba619 Update fa.py
edit plural-forms for persian agian
2019-06-02 16:07:58 +04:30
mdipierro
409a499dd0 Merge pull request #2215 from yamandu/pt_br_translation
Better Brazilian Portuguese translation
2019-06-01 11:37:17 -07:00
mdipierro
9d52f5498e Merge pull request #2214 from yamandu/issue2179
Issue2179
2019-06-01 11:36:52 -07:00
mdipierro
0fe9d0aa34 Merge pull request #2213 from web-py/patch-2
create fa.py
2019-06-01 11:36:06 -07:00
mdipierro
89a4da0594 better scheduler logic to prevent deadlocks, thanks Paolo Pastori 2019-06-01 11:34:58 -07:00
mdipierro
f2e95d1bb6 no need to create folders in shell 2019-06-01 11:31:27 -07:00
Carlos Costa
273ebb9a70 Better Brazilian Portuguese translation
Including SQLFORM.grid, auth and other strings.
2019-05-31 12:04:32 -03:00
Carlos Costa
1bfffc4f12 issue #2179
fixing tab size setting that breaks the editor configuration
2019-05-31 11:20:39 -03:00
Carlos José da Costa
6d7900be82 Merge pull request #1 from web2py/master
Sync with original
2019-05-31 10:28:05 -03:00
Ankidroid-net
dadf363122 create fa.py
Hello. I intend to prepare a Persian translation of the Web 2 Pie and provide a good source for Persian speakers.
2019-05-26 17:20:25 +04:30
mdipierro
ce25d8dc31 description % should not be escaped, reverting 2019-05-25 01:01:32 -07:00
mdipierro
1c5b2d7fce chmod a-x, thanks Paolo 2019-05-25 00:30:34 -07:00
mdipierro
9b831a64c0 Merge pull request #2159 from nicozanf/master
Change binary scripts to use PyInstaller with PY3
2019-05-25 00:24:16 -07:00
mdipierro
e6e92b43c9 Merge pull request #2212 from gonguinguen/patch-4
solves #2211
2019-05-25 00:21:44 -07:00
mdipierro
c02ee6a5c0 Merge pull request #2210 from timnyborg/patch-5
prevent open redirects with no protocol specified
2019-05-25 00:21:20 -07:00
mdipierro
22f95677d9 Merge pull request #2208 from dlage/fix-missing-folders-in-script
Refactor methods from gluon/admin to gluon/fileutils
2019-05-25 00:20:52 -07:00
mdipierro
4fd44ff682 Merge pull request #2207 from dlage/migrator-pr
Migrator - add a command line option to ensure that all tables are migrated
2019-05-25 00:20:21 -07:00
mdipierro
da253f7ba8 Merge pull request #2202 from bmiklautz/shell_controller
fix: controller function invocation via shell
2019-05-25 00:18:55 -07:00
mdipierro
a24926ad6f Merge pull request #2199 from timnyborg/patch-4
correct SAML authorization request binding
2019-05-25 00:18:27 -07:00
c6837a9e73 Merge branch 'master' into migrator-pr 2019-05-23 14:32:24 +01:00
a65234478c Merge branch 'master' into fix-missing-folders-in-script 2019-05-23 14:32:04 +01:00
mdipierro
94af61e732 better cron limits number of threads, thanks P.Pastori 2019-05-22 21:44:42 -07:00
Lisandro
bd892556e1 solves #2211
The change I propose solves issue #2211 
I hope this is the correct approach.
2019-05-20 11:58:42 -03:00
Tim Nyborg
99d3d1d465 prevent open redirects with no protocol specified
prevent_open_redirect doesn't currently handle a 'next' with a // but no protocol, e.g.: .../user/login?_next=//google.com
2019-05-20 11:27:21 +01:00
mdipierro
f258cbecee syncing pydal with restapi 2019-05-18 22:25:08 -07:00
mdipierro
2ccd7a86ec better thread handling in GUI and more resiliant start/stop, thanks P.Pastori 2019-05-18 22:21:03 -07:00
mdipierro
1790688357 some changes in permissions, thanks Paolo 2019-05-18 22:18:24 -07:00
30a0ac6a1b Refactor methods from gluon/admin to gluon/fileutils 2019-05-16 18:51:26 +01:00
b365d12a2e Merge branch 'master' into migrator-pr 2019-05-16 16:49:15 +01:00
4455fa48c4 Add a script to force migration of lazy tables and fix missing options in DAL init. 2019-05-16 15:33:19 +01:00
96534ccf30 First attempt to force migration of the tables even with migrate option set to false. 2019-05-15 20:07:36 +01:00
mdipierro
148e9e8629 removed cicrular dependency in copystream, thanks Paolo 2019-05-13 20:41:27 -07:00
mdipierro
95bbaf6a38 more regex improvements, thanks Paolo Pastori 2019-05-12 19:39:33 -07:00
mdipierro
0372c50ef5 restored some missing regex, thanks Paolo Pastori 2019-05-12 17:34:24 -07:00
mdipierro
3ed69380f2 one logger per app and fixed some threading issues with newcron, thanks Paolo Pastori 2019-05-11 13:21:40 -07:00
mdipierro
55aa94bbb9 myregex is gone. Thanks Paolo Pastori 2019-05-11 13:18:03 -07:00
Bernhard Miklautz
7a225da44e fix: controller function invocation via shell
If only a compiled version is available and a controller function is invoked with -S app/c/f an
IOError is raised as '_' is used as delimiter instead of '.'.

web2py.py  -S test/test/test -M would lead to:

IOError: [Errno 2] No such file or directory: 'applications/test/compiled/controllers_test_test.pyc'
2019-05-11 17:33:42 +02:00
mdipierro
caf3010408 better regex and improvements in compileapp, thank you Paolo Pastori 2019-05-09 23:30:07 -07:00
mdipierro
f9c0c478df sync 2019-05-07 21:20:26 -07:00
mdipierro
c5ab91041d use testing app, not welcome for test_web, thanks Paolo 2019-05-07 20:51:48 -07:00
Tim Nyborg
3f15d1ceb8 correct SAML authorization request binding
AuthnRequest cannot use BINDING_HTTP_REDIRECT, according to the SAML v2 specifications.  See:
https://github.com/IdentityPython/pysaml2/issues/163
2019-05-07 09:09:56 +01:00
mdipierro
ee3b63b792 fixed create missing folders, thanks Paolo 2019-05-05 23:15:09 -07:00
mdipierro
fc256343a7 better setup and teardown in test_web, thanks Paolo 2019-05-05 20:53:20 -07:00
mdipierro
c59186fa64 fixed missing folder in start scheduler 2019-05-05 20:49:56 -07:00
mdipierro
091f13df43 fixed logic for running tests and using welcome for testing, thanks Paolo 2019-05-05 20:34:28 -07:00
mdipierro
621d9e6d83 Merge pull request #2194 from leonelcamara/patch-31
Fixes #2182 possibly Fixes #2190
2019-05-05 20:30:40 -07:00
mdipierro
42528987af regex fix, thanks Paolo 2019-05-04 10:20:44 -07:00
mdipierro
c258d10d15 removed options_std.py, no longer necssary since options can be passed as command line arguments 2019-05-03 20:07:19 -07:00
mdipierro
ca0b72d7b1 fixed a few more typos and better testing, thanks Paolo 2019-05-03 20:03:41 -07:00
mdipierro
eba2455298 fixed typo, thanks Paolo 2019-05-03 20:01:27 -07:00
Leonel Câmara
be81e69c2b fix tests for new json serializer 2019-05-02 16:21:34 +01:00
Leonel Câmara
e3a981fc2c Fixes #2182 possibly Fixes #2190 2019-05-02 16:09:10 +01:00
mdipierro
1a169b340e fixed python3 compatibility 2019-05-01 21:45:12 -07:00
mdipierro
20416b4d1c syncing 2019-05-01 21:23:34 -07:00
mdipierro
76c5bad895 Merge branch 'master' of github.com:web2py/web2py 2019-05-01 21:10:03 -07:00
mdipierro
15daf70298 pydal sync 2019-05-01 21:09:36 -07:00
mdipierro
1c08c07a0f new command line options 2019-05-01 21:07:52 -07:00
mdipierro
b291239a41 Merge pull request #2189 from nicozanf/patch-1
PY2 small print fix
2019-04-28 11:29:03 -07:00
mdipierro
6f12be7e20 even better option processing in widget.py, thanks Paolo 2019-04-26 22:36:02 -07:00
Nico Zanferrari
9769314f01 PY2 compatibility 2019-04-24 23:38:06 +02:00
Nico Zanferrari
b79b5951f8 Update docs 2019-04-24 23:35:44 +02:00
Nico Zanferrari
7b9d2c87c2 PY2 compatibility 2019-04-24 23:28:48 +02:00
Nico Zanferrari
89c441cdc8 PY2 small print fix 2019-04-24 19:28:46 +02:00
mdipierro
0a9975809c cleanup in main, thanks Paolo 2019-04-23 22:10:53 -07:00
mdipierro
14dee6b466 better shell using create_app, thanks Paolo 2019-04-21 09:27:02 -07:00
mdipierro
9d5a16351b simplify admin by using create_app, thanks Paolo 2019-04-21 09:24:56 -07:00
mdipierro
7c1bb810fc cleaner fileutils and untarring/unzipping in fileutils, thanks Paolo 2019-04-20 13:53:53 -07:00
mdipierro
8a9b2d687e better option handling for the shell, thanks Paolo 2019-04-19 21:23:59 -07:00
mdipierro
0d04b8a511 widget fix, thanks Paolo 2019-04-19 21:22:29 -07:00
mdipierro
2f35117282 better options and regexp, thanks Paolo 2019-04-18 21:32:46 -07:00
mdipierro
563de284f7 better logic for passing parameters to scheduler, thanks Paolo 2019-04-17 21:59:03 -07:00
mdipierro
8c29f8b12a fixed order or sorting in grid 2019-04-13 18:04:43 -07:00
mdipierro
2fbaced689 removed naming conflict from previous commit, thanks Paolo 2019-04-11 21:18:36 -07:00
mdipierro
33335ec3e1 removed redundant os.chdir, thanks paolo 2019-04-11 21:16:54 -07:00
mdipierro
066d9c9ab5 better newcrow and widget, fixed some ssl related bugs, thanks Paolo 2019-04-11 21:15:48 -07:00
mdipierro
b96c54cef9 some cleanup and better use of die() function, thanks paolo 2019-04-09 21:49:04 -07:00
mdipierro
59700b8d06 R-2.18.5 2019-04-07 21:16:13 -07:00
mdipierro
455d188da8 removed un-necessary sort exception is sqlform.grid 2019-04-07 16:26:28 -07:00
mdipierro
d13a003475 use metavar, thanks Paolo 2019-04-07 09:25:08 -07:00
mdipierro
a47deac038 Merge pull request #2166 from leonelcamara/revert-2145-expose
Revert "don't use a regex to find exposed functions"
2019-04-07 09:15:39 -07:00
mdipierro
5667149f8d syncing 2019-04-06 20:59:23 -07:00
mdipierro
c9a42c4638 refactoring of widget.py, thanks Paolo 2019-04-06 20:54:16 -07:00
mdipierro
33fe831287 support web2py.py --GAE {app-name}, thanks Paolo 2019-04-06 20:05:39 -07:00
mdipierro
f2dcc53a18 cleanup in custom import, thanks Paolo 2019-04-06 19:51:57 -07:00
Leonel Câmara
39b965be7b Revert "don't use a regex to find exposed functions" 2019-04-01 15:24:46 +01:00
mdipierro
e637b6b58a removed un-needed IO class in widgets and som refactoring, thanks Paolo 2019-03-31 19:50:02 -07:00
mdipierro
18da4fa7fd request.folder no longer ends with os.sep 2019-03-31 19:46:55 -07:00
mdipierro
66d5faf78f fixed sys.exit value, thanks Paolo 2019-03-30 11:35:34 -07:00
mdipierro
cfdee6e065 better logic in running system tests, thanks Paolo 2019-03-30 10:42:01 -07:00
mdipierro
44b93929e2 better regex, thanks Paolo 2019-03-30 10:34:49 -07:00
mdipierro
8c090954fd new custom import works better with recursive imports, thanks Paolo Pastori 2019-03-24 11:28:28 -07:00
mdipierro
b4e22bf465 code simplificaton in widget.py, thanks Paolo Pastori 2019-03-24 10:50:02 -07:00
mdipierro
565415d4bf code simplificatons in newcron (although deprecated), thanks Paolo Pastori 2019-03-24 10:49:35 -07:00
mdipierro
12e043c0a2 removed un-necessary code from shell, thanks Paolo Pastori 2019-03-24 10:48:58 -07:00
mdipierro
1a828bf630 syncing 2019-03-23 22:27:35 -07:00
mdipierro
ce2ad2d15b syncing 2019-03-23 22:13:13 -07:00
mdipierro
78ab6de16b Merge pull request #2156 from misl6/master
Fixes virtualfields representation on grid
2019-03-23 22:12:27 -07:00
mdipierro
2e2639b12a Merge pull request #2151 from leonelcamara/patch-30
Teach admin how to deal with syntax errors
2019-03-23 22:11:31 -07:00
mdipierro
83ca7f20b8 no need for Field import, thanks Paolo 2019-03-23 21:53:30 -07:00
mdipierro
eb07384c23 moved pluralize logic into sqlhtml for speed reasons, thanks Paolo P. 2019-03-23 21:42:06 -07:00
Nico Zanferrari
c03c962778 Rename README to README.md 2019-03-22 15:37:44 +01:00
Nico Zanferrari
ca7b676591 Update README 2019-03-22 15:37:14 +01:00
Nico Zanferrari
7a0e113a5f new PyInstaller script 2019-03-22 15:34:50 +01:00
Nico Zanferrari
7e30be377d cleanup 2019-03-22 15:33:44 +01:00
Nico Zanferrari
f9db6a8306 cleanup 2019-03-22 15:33:29 +01:00
Nico Zanferrari
50878f33bd cleanup 2019-03-22 15:33:14 +01:00
Mirko Galimberti
5bc1ab1367 Fixes Field.Virtual repr in grid 2019-03-19 12:22:16 +01:00
Mirko
1d81132159 Merge pull request #1 from web2py/master
Merging from master
2019-03-19 12:07:59 +01:00
mdipierro
b29cdef7e2 syncing 2019-03-18 08:22:26 -07:00
Leonel Câmara
986406ed80 Teach admin how to deal with syntax errors 2019-03-18 15:06:38 +00:00
mdipierro
396311714c fixed import 2019-03-17 13:44:40 -07:00
mdipierro
8b84026206 syncing 2019-03-17 13:11:44 -07:00
mdipierro
c4861879ea moved default_validatos to pydal 2019-03-17 11:00:56 -07:00
mdipierro
4a90c82ee4 lazy initialization of highligher styles, thanks Paolo 2019-03-15 22:32:01 -07:00
mdipierro
4a16a1c377 Fixes #1996, thanks Paolo 2019-03-15 22:21:11 -07:00
mdipierro
e276ac497d Merge branch 'master' of github.com:web2py/web2py 2019-03-14 21:01:49 -07:00
mdipierro
7e1e767d8f syncing pydal 2019-03-14 21:00:11 -07:00
mdipierro
378405b6b6 Merge pull request #2147 from leonelcamara/patch-29
import translate and ValidationError as well
2019-03-13 21:14:11 -07:00
Leonel Câmara
e821e5c7a6 import translate and ValidationError as well 2019-03-13 18:40:45 +00:00
392 changed files with 7678 additions and 3310 deletions

View File

@@ -1,27 +1,22 @@
language: python
sudo: required
cache: pip
dist: "xenial"
dist: "bionic"
services:
- mysql
- redis-server
python:
- '2.7'
- '3.5'
- '3.6'
- '3.6-dev'
- '3.7'
- '3.7-dev'
- 'pypy3.5'
matrix:
allow_failures:
- python: '3.6-dev'
- python: '3.7-dev'
- python: 'pypy3.5'
install:
- pip install -e .
@@ -29,6 +24,7 @@ install:
before_script:
- pip install coverage
- pip install codecov
- pip install redis
before_install:
- mysql -e 'create database pydal;'

View File

@@ -1,5 +1,26 @@
## 2.18.1-2.18.4
- pydal 19.02
## 2.19.0
- new command line options (Thanks Paolo Pastori)
OLD NAME NEW NAME
================== ==================
--debug --log_level
--nogui --no_gui
--ssl_private_key --server_key
--ssl_certificate --server_cert
--minthreads --min_threads
--maxthreads --max_threads
--profiler --profiler_dir
--run-cron --with_cron
--softcron --soft_cron
--cron --cron_run
--cronjob * --cron_job *
--test --run_doctests
--add_options
--interface
--crontab
## 2.18.1-2.18.5
- pydal 19.04
- made template its own module (Yet Another Template Language)
- improved python 3.4-3.7 support
- better regular expressions

View File

@@ -19,11 +19,11 @@ clean:
find applications/welcome/ -name '.*' -exec rm -f {} \;
find . -name '*.pyc' -exec rm -f {} \;
tests:
python web2py.py --run_system_tests
python web2py.py --verbose --run_system_tests
coverage:
coverage erase --rcfile=gluon/tests/coverage.ini
export COVERAGE_PROCESS_START=gluon/tests/coverage.ini
python web2py.py --run_system_tests --with_coverage
python web2py.py --verbose --run_system_tests --with_coverage
coverage combine --rcfile=gluon/tests/coverage.ini
sleep 1
coverage html --rcfile=gluon/tests/coverage.ini
@@ -45,7 +45,7 @@ rmfiles:
rm -rf applications/examples/uploads/*
src:
### Use semantic versioning
echo 'Version 2.18.4-stable+timestamp.'`date +%Y.%m.%d.%H.%M.%S` > VERSION
echo 'Version 2.18.5-stable+timestamp.'`date +%Y.%m.%d.%H.%M.%S` > VERSION
### rm -f all junk files
make clean
# make rmfiles

View File

@@ -1 +1 @@
Version 2.18.4-stable+timestamp.2019.03.12.22.20.22
Version 2.18.5-stable+timestamp.2019.04.07.21.13.59

View File

@@ -30,7 +30,7 @@ except:
if request.is_https:
session.secure()
elif (remote_addr not in hosts) and (remote_addr != "127.0.0.1") and \
elif (remote_addr not in hosts) and (remote_addr != '127.0.0.1') and \
(request.function != 'manage'):
raise HTTP(200, T('appadmin is disabled because insecure channel'))
@@ -46,7 +46,7 @@ if request.function == 'manage':
auth.table_permission()])
manager_role = manager_action.get('role', None) if manager_action else None
if not (gluon.fileutils.check_credentials(request) or auth.has_membership(manager_role)):
raise HTTP(403, "Not authorized")
raise HTTP(403, 'Not authorized')
menu = False
elif (request.application == 'admin' and not session.authorized) or \
(request.application != 'admin' and not gluon.fileutils.check_credentials(request)):
@@ -182,7 +182,7 @@ def select():
db = get_database(request)
dbname = request.args[0]
try:
is_imap = db._uri.startswith("imap://")
is_imap = db._uri.startswith('imap://')
except (KeyError, AttributeError, TypeError):
is_imap = False
regex = re.compile(r'(?P<table>\w+)\.(?P<field>\w+)=(?P<value>\d+)')
@@ -224,15 +224,15 @@ def select():
session.last_orderby = orderby
session.last_query = request.vars.query
form = FORM(TABLE(TR(T('Query:'), '', INPUT(_style='width:400px',
_name='query', _value=request.vars.query or '', _class="form-control",
_name='query', _value=request.vars.query or '', _class='form-control',
requires=IS_NOT_EMPTY(
error_message=T("Cannot be empty")))), TR(T('Update:'),
error_message=T('Cannot be empty')))), TR(T('Update:'),
INPUT(_name='update_check', _type='checkbox',
value=False), INPUT(_style='width:400px',
_name='update_fields', _value=request.vars.update_fields
or '', _class="form-control")), TR(T('Delete:'), INPUT(_name='delete_check',
or '', _class='form-control')), TR(T('Delete:'), INPUT(_name='delete_check',
_class='delete', _type='checkbox', value=False), ''),
TR('', '', INPUT(_type='submit', _value=T('submit'), _class="btn btn-primary"))),
TR('', '', INPUT(_type='submit', _value=T('Submit'), _class='btn btn-primary'))),
_action=URL(r=request, args=request.args))
tb = None
@@ -254,8 +254,8 @@ def select():
if is_imap:
fields = [db[table][name] for name in
("id", "uid", "created", "to",
"sender", "subject")]
('id', 'uid', 'created', 'to',
'sender', 'subject')]
if orderby:
rows = db(query, ignore_common_filters=True).select(
*fields, limitby=(start, stop),
@@ -271,10 +271,10 @@ def select():
# begin handle upload csv
csv_table = table or request.vars.table
if csv_table:
formcsv = FORM(str(T('or import from csv file')) + " ",
formcsv = FORM(str(T('or import from csv file')) + ' ',
INPUT(_type='file', _name='csvfile'),
INPUT(_type='hidden', _value=csv_table, _name='table'),
INPUT(_type='submit', _value=T('import'), _class="btn btn-primary"))
INPUT(_type='submit', _value=T('import'), _class='btn btn-primary'))
else:
formcsv = None
if formcsv and formcsv.process().accepted:
@@ -356,26 +356,26 @@ def state():
def ccache():
if is_gae:
form = FORM(
P(TAG.BUTTON(T("Clear CACHE?"), _type="submit", _name="yes", _value="yes")))
P(TAG.BUTTON(T('Clear CACHE?'), _type='submit', _name='yes', _value='yes')))
else:
cache.ram.initialize()
cache.disk.initialize()
form = FORM(
P(TAG.BUTTON(
T("Clear CACHE?"), _type="submit", _name="yes", _value="yes")),
T('Clear CACHE?'), _type='submit', _name='yes', _value='yes')),
P(TAG.BUTTON(
T("Clear RAM"), _type="submit", _name="ram", _value="ram")),
T('Clear RAM'), _type='submit', _name='ram', _value='ram')),
P(TAG.BUTTON(
T("Clear DISK"), _type="submit", _name="disk", _value="disk")),
T('Clear DISK'), _type='submit', _name='disk', _value='disk')),
)
if form.accepts(request.vars, session):
session.flash = ""
session.flash = ''
if is_gae:
if request.vars.yes:
cache.ram.clear()
session.flash += T("Cache Cleared")
session.flash += T('Cache Cleared')
else:
clear_ram = False
clear_disk = False
@@ -387,10 +387,10 @@ def ccache():
clear_disk = True
if clear_ram:
cache.ram.clear()
session.flash += T("Ram Cleared")
session.flash += T('Ram Cleared')
if clear_disk:
cache.disk.clear()
session.flash += T("Disk Cleared")
session.flash += T('Disk Cleared')
redirect(URL(r=request))
try:
@@ -436,7 +436,7 @@ def ccache():
gae_stats['ratio'] = ((gae_stats['hits'] * 100) /
(gae_stats['hits'] + gae_stats['misses']))
except ZeroDivisionError:
gae_stats['ratio'] = T("?")
gae_stats['ratio'] = T('?')
gae_stats['oldest'] = GetInHMS(time.time() - gae_stats['oldest_item_age'])
total.update(gae_stats)
else:
@@ -502,7 +502,7 @@ def ccache():
TR(TD(B(T('Key'))), TD(B(T('Time in Cache (h:m:s)')))),
*[TR(TD(k[0]), TD('%02d:%02d:%02d' % k[1])) for k in keys],
**dict(_class='cache-keys',
_style="border-collapse: separate; border-spacing: .5em;"))
_style='border-collapse: separate; border-spacing: .5em;'))
if not is_gae:
ram['keys'] = key_table(ram['keys'])
@@ -536,26 +536,26 @@ def table_template(table):
# This is horribe HTML but the only one graphiz understands
rows = []
cellpadding = 4
color = "#000000"
bgcolor = "#FFFFFF"
face = "Helvetica"
face_bold = "Helvetica Bold"
color = '#000000'
bgcolor = '#FFFFFF'
face = 'Helvetica'
face_bold = 'Helvetica Bold'
border = 0
rows.append(TR(TD(FONT(table, _face=face_bold, _color=bgcolor),
_colspan=3, _cellpadding=cellpadding,
_align="center", _bgcolor=color)))
_align='center', _bgcolor=color)))
for row in db[table]:
rows.append(TR(TD(FONT(row.name, _color=color, _face=face_bold),
_align="left", _cellpadding=cellpadding,
_align='left', _cellpadding=cellpadding,
_border=border),
TD(FONT(row.type, _color=color, _face=face),
_align="left", _cellpadding=cellpadding,
_align='left', _cellpadding=cellpadding,
_border=border),
TD(FONT(types(row), _color=color, _face=face),
_align="center", _cellpadding=cellpadding,
_align='center', _cellpadding=cellpadding,
_border=border)))
return "< %s >" % TABLE(*rows, **dict(_bgcolor=bgcolor, _border=1,
return '< %s >' % TABLE(*rows, **dict(_bgcolor=bgcolor, _border=1,
_cellborder=0, _cellspacing=0)
).xml()
@@ -632,15 +632,15 @@ def hooks():
if len(functions):
method_hooks.append({'name': op, 'functions':functions})
if len(method_hooks):
tables.append({'name': "%s.%s" % (db_str, t), 'slug': IS_SLUG()("%s.%s" % (db_str,t))[0], 'method_hooks':method_hooks})
tables.append({'name': '%s.%s' % (db_str, t), 'slug': IS_SLUG()('%s.%s' % (db_str,t))[0], 'method_hooks':method_hooks})
# Render
ul_main = UL(_class='nav nav-list')
for t in tables:
ul_main.append(A(t['name'], _onclick="collapse('a_%s')" % t['slug']))
ul_t = UL(_class='nav nav-list', _id="a_%s" % t['slug'], _style='display:none')
ul_t = UL(_class='nav nav-list', _id='a_%s' % t['slug'], _style='display:none')
for op in t['method_hooks']:
ul_t.append(LI(op['name']))
ul_t.append(UL([LI(A(f['funcname'], _class="editor_filelink", _href=f['url']if 'url' in f else None, **{'_data-lineno':f['lineno']-1})) for f in op['functions']]))
ul_t.append(UL([LI(A(f['funcname'], _class='editor_filelink', _href=f['url']if 'url' in f else None, **{'_data-lineno':f['lineno']-1})) for f in op['functions']]))
ul_main.append(ul_t)
return ul_main
@@ -650,11 +650,11 @@ def hooks():
# ###########################################################
def d3_graph_model():
""" See https://www.facebook.com/web2py/posts/145613995589010 from Bruno Rocha
''' See https://www.facebook.com/web2py/posts/145613995589010 from Bruno Rocha
and also the app_admin bg_graph_model function
Create a list of table dicts, called "nodes"
"""
Create a list of table dicts, called 'nodes'
'''
nodes = []
links = []
@@ -670,10 +670,10 @@ def d3_graph_model():
elif f_type == 'string':
disp = field.length
elif f_type == 'id':
disp = "PK"
disp = 'PK'
elif f_type.startswith('reference') or \
f_type.startswith('list:reference'):
disp = "FK"
disp = 'FK'
else:
disp = ' '
fields.append(dict(name=field.name, type=field.type, disp=disp))
@@ -685,7 +685,7 @@ def d3_graph_model():
links.append(dict(source=tablename, target = referenced_table))
nodes.append(dict(name=tablename, type="table", fields = fields))
nodes.append(dict(name=tablename, type='table', fields = fields))
# d3 v4 allows individual modules to be specified. The complete d3 library is included below.
response.files.append(URL('admin','static','js/d3.min.js'))

View File

@@ -166,9 +166,9 @@ def check_version():
new_version, version = check_new_version(request.env.web2py_version,
WEB2PY_VERSION_URL)
if new_version == -1:
if new_version in (-1, -2):
return A(T('Unable to check for upgrades'), _href=WEB2PY_URL)
elif new_version != True:
elif not new_version:
return A(T('web2py is up to date'), _href=WEB2PY_URL)
elif platform.system().lower() in ('windows', 'win32', 'win64') and os.path.exists("web2py.exe"):
return SPAN('You should upgrade to %s' % version.split('(')[0])
@@ -814,8 +814,11 @@ def edit():
if len(request.args) > 2 and request.args[1] == 'controllers':
controller = (request.args[2])[:-3]
functions = find_exposed_functions(data)
functions = functions and sorted(functions) or []
try:
functions = find_exposed_functions(data)
functions = functions and sorted(functions) or []
except SyntaxError as err:
functions = ['SyntaxError:Line:%d' % err.lineno]
else:
(controller, functions) = (None, None)
@@ -1117,7 +1120,7 @@ def design():
defines = {}
for m in models:
data = safe_read(apath('%s/models/%s' % (app, m), r=request))
defines[m] = regex_tables.findall(data)
defines[m] = re.findall(REGEX_DEFINE_TABLE, data, re.MULTILINE)
defines[m].sort()
# Get all controllers
@@ -1127,8 +1130,11 @@ def design():
functions = {}
for c in controllers:
data = safe_read(apath('%s/controllers/%s' % (app, c), r=request))
items = find_exposed_functions(data)
functions[c] = items and sorted(items) or []
try:
items = find_exposed_functions(data)
functions[c] = items and sorted(items) or []
except SyntaxError as err:
functions[c] = ['SyntaxError:Line:%d' % err.lineno]
# Get all views
views = sorted(
@@ -1138,12 +1144,12 @@ def design():
include = {}
for c in views:
data = safe_read(apath('%s/views/%s' % (app, c), r=request))
items = regex_extend.findall(data)
items = re.findall(REGEX_EXTEND, data, re.MULTILINE)
if items:
extend[c] = items[0][1]
items = regex_include.findall(data)
items = re.findall(REGEX_INCLUDE, data)
include[c] = [i[1] for i in items]
# Get all modules
@@ -1265,8 +1271,11 @@ def plugin():
functions = {}
for c in controllers:
data = safe_read(apath('%s/controllers/%s' % (app, c), r=request))
items = find_exposed_functions(data)
functions[c] = items and sorted(items) or []
try:
items = find_exposed_functions(data)
functions[c] = items and sorted(items) or []
except SyntaxError as err:
functions[c] = ['SyntaxError:Line:%d' % err.lineno]
# Get all views
views = sorted(
@@ -1276,11 +1285,11 @@ def plugin():
include = {}
for c in views:
data = safe_read(apath('%s/views/%s' % (app, c), r=request))
items = regex_extend.findall(data)
items = re.findall(REGEX_EXTEND, data, re.MULTILINE)
if items:
extend[c] = items[0][1]
items = regex_include.findall(data)
items = re.findall(REGEX_INCLUDE, data)
include[c] = [i[1] for i in items]
# Get all modules

0
applications/admin/languages/af.py Executable file → Normal file
View File

0
applications/admin/languages/bg.py Executable file → Normal file
View File

0
applications/admin/languages/cs.py Executable file → Normal file
View File

0
applications/admin/languages/en.py Executable file → Normal file
View File

0
applications/admin/languages/es.py Executable file → Normal file
View File

0
applications/admin/languages/fr.py Executable file → Normal file
View File

0
applications/admin/languages/he.py Executable file → Normal file
View File

0
applications/admin/languages/it.py Executable file → Normal file
View File

0
applications/admin/languages/ja.py Executable file → Normal file
View File

0
applications/admin/languages/my-mm.py Executable file → Normal file
View File

0
applications/admin/languages/nl.py Executable file → Normal file
View File

0
applications/admin/languages/pl.py Executable file → Normal file
View File

0
applications/admin/languages/plural-en.py Executable file → Normal file
View File

0
applications/admin/languages/plural-ru.py Executable file → Normal file
View File

0
applications/admin/languages/plural-uk.py Executable file → Normal file
View File

0
applications/admin/languages/pt-br.py Executable file → Normal file
View File

0
applications/admin/languages/pt.py Executable file → Normal file
View File

0
applications/admin/languages/ro.py Executable file → Normal file
View File

0
applications/admin/languages/ru.py Executable file → Normal file
View File

0
applications/admin/languages/sl.py Executable file → Normal file
View File

0
applications/admin/languages/sr-cr.py Executable file → Normal file
View File

0
applications/admin/languages/sr-lt.py Executable file → Normal file
View File

0
applications/admin/languages/tr.py Executable file → Normal file
View File

0
applications/admin/languages/uk.py Executable file → Normal file
View File

0
applications/admin/languages/zh-tw.py Executable file → Normal file
View File

0
applications/admin/languages/zh.py Executable file → Normal file
View File

View File

@@ -25,6 +25,5 @@ from gluon.utils import md5_hash
from gluon.fileutils import listdir, cleanpath, up
from gluon.fileutils import tar, tar_compiled, untar, fix_newlines
from gluon.languages import findT, update_all_languages
from gluon.myregex import *
from gluon.restricted import *
from gluon.compileapp import compile_application, remove_compiled_application

View File

@@ -1,9 +1,12 @@
[DEFAULT]
[editor]
theme = web2py
editor = default
theme = twilight
editor = sublime
closetag = true
tabwidth = 4
highlightline = true
linenumbers = true
codefolding = false
indentwithtabs = false
[editor_sessions]
welcome = welcome/models/db.py,welcome/controllers/default.py,welcome/views/default/index.html

0
applications/admin/static/css/jqueryMultiSelect.css Executable file → Normal file
View File

0
applications/admin/static/js/jqueryMultiSelect.js vendored Executable file → Normal file
View File

View File

@@ -284,6 +284,7 @@
var redirect = xhr.getResponseHeader('web2py-redirect-location');
if (redirect !== null) {
window.location = redirect;
window.location.reload(); // Force reload even with anchors
}
/* run this here only if this Ajax request is NOT for a web2py component. */
if (xhr.getResponseHeader('web2py-component-content') === null) {

View File

Before

Width:  |  Height:  |  Size: 366 B

After

Width:  |  Height:  |  Size: 366 B

View File

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

Before

Width:  |  Height:  |  Size: 4.2 KiB

After

Width:  |  Height:  |  Size: 4.2 KiB

View File

Before

Width:  |  Height:  |  Size: 3.7 KiB

After

Width:  |  Height:  |  Size: 3.7 KiB

View File

View File

View File

Before

Width:  |  Height:  |  Size: 3.0 KiB

After

Width:  |  Height:  |  Size: 3.0 KiB

View File

@@ -38,19 +38,19 @@ def file_upload_form(location):
INPUT(_type="text",_name="filename",requires=IS_NOT_EMPTY()),
INPUT(_type="hidden",_name="location",_value=location),
INPUT(_type="hidden",_name="sender",_value=URL('design/'+app)),
INPUT(_type="submit",_value=T("submit")),_action=URL('upload_file'))
INPUT(_type="submit",_value=T("Submit")),_action=URL('upload_file'))
return form
def file_create_form(location):
form=FORM(T("create file with filename:")," ",
INPUT(_type="text",_name="filename",requires=IS_NOT_EMPTY()),
INPUT(_type="hidden",_name="location",_value=location),
INPUT(_type="hidden",_name="sender",_value=URL('design/'+app)),
INPUT(_type="submit",_value=T("submit")),_action=URL('create_file'))
INPUT(_type="submit",_value=T("Submit")),_action=URL('create_file'))
return form
def upload_plugin_form(app):
form=FORM(T("upload plugin file:")," ",
INPUT(_type="file",_name="pluginfile"),
INPUT(_type="submit",_value=T("submit")))
INPUT(_type="submit",_value=T("Submit")))
return form
def deletefile(arglist):
return A_delete(SPAN(T('Delete')), _href=URL('delete',args=arglist,vars=dict(sender=request.function+'/'+app)))

View File

@@ -6,7 +6,7 @@
return files
}}
{{themes = [f[:-4] for f in listfiles('admin', "static/codemirror/theme", regexp='.*\.css$' )]}}
{{editors = ['default', 'vim', 'emacs']}}
{{editors = ['default', 'vim', 'emacs', 'sublime']}}
<form id="editor_settings_form" class="form-horizontal" action="">
<div class="control-group">
@@ -27,7 +27,7 @@
</div>
<div class="control-group">
<label class="control-label" for="tabwidth">{{=T('Tab width (# characters)')}}</label>
<div class="controls">{{=SELECT(range(1,9, 1), value=editor_settings['tabwidth'], _name="tabwidth" )}}</div>
<div class="controls">{{=SELECT(list(range(1,9, 1)), value=editor_settings['tabwidth'], _name="tabwidth" )}}</div>
</div>
<div class="control-group">
<label class="control-label" for="indentwithtabs">{{=T('Indent with tabs')}}</label>

View File

@@ -24,7 +24,7 @@ def file_upload_form(location):
INPUT(_type="hidden",_name="location",_value=location),
INPUT(_type="hidden",_name="token",_value=session.token),
INPUT(_type="hidden",_name="sender",_value=URL('design/'+app)),
INPUT(_type="submit",_value=T("submit")),_action=URL('upload_file'))
INPUT(_type="submit",_value=T("Submit")),_action=URL('upload_file'))
return form
def file_create_form(location):
form=FORM(T("create file with filename:")," ",
@@ -32,7 +32,7 @@ def file_create_form(location):
INPUT(_type="hidden",_name="location",_value=location),
INPUT(_type="hidden",_name="token",_value=session.token),
INPUT(_type="hidden",_name="sender",_value=URL('design/'+app)),
INPUT(_type="submit",_value=T("submit")),_action=URL('create_file'))
INPUT(_type="submit",_value=T("Submit")),_action=URL('create_file'))
return form
def deletefile(arglist):
return A(TAG[''](IMG(_src=URL('static', 'images/delete_icon.png')),

View File

@@ -30,7 +30,7 @@ except:
if request.is_https:
session.secure()
elif (remote_addr not in hosts) and (remote_addr != "127.0.0.1") and \
elif (remote_addr not in hosts) and (remote_addr != '127.0.0.1') and \
(request.function != 'manage'):
raise HTTP(200, T('appadmin is disabled because insecure channel'))
@@ -46,7 +46,7 @@ if request.function == 'manage':
auth.table_permission()])
manager_role = manager_action.get('role', None) if manager_action else None
if not (gluon.fileutils.check_credentials(request) or auth.has_membership(manager_role)):
raise HTTP(403, "Not authorized")
raise HTTP(403, 'Not authorized')
menu = False
elif (request.application == 'admin' and not session.authorized) or \
(request.application != 'admin' and not gluon.fileutils.check_credentials(request)):
@@ -182,7 +182,7 @@ def select():
db = get_database(request)
dbname = request.args[0]
try:
is_imap = db._uri.startswith("imap://")
is_imap = db._uri.startswith('imap://')
except (KeyError, AttributeError, TypeError):
is_imap = False
regex = re.compile(r'(?P<table>\w+)\.(?P<field>\w+)=(?P<value>\d+)')
@@ -224,15 +224,15 @@ def select():
session.last_orderby = orderby
session.last_query = request.vars.query
form = FORM(TABLE(TR(T('Query:'), '', INPUT(_style='width:400px',
_name='query', _value=request.vars.query or '', _class="form-control",
_name='query', _value=request.vars.query or '', _class='form-control',
requires=IS_NOT_EMPTY(
error_message=T("Cannot be empty")))), TR(T('Update:'),
error_message=T('Cannot be empty')))), TR(T('Update:'),
INPUT(_name='update_check', _type='checkbox',
value=False), INPUT(_style='width:400px',
_name='update_fields', _value=request.vars.update_fields
or '', _class="form-control")), TR(T('Delete:'), INPUT(_name='delete_check',
or '', _class='form-control')), TR(T('Delete:'), INPUT(_name='delete_check',
_class='delete', _type='checkbox', value=False), ''),
TR('', '', INPUT(_type='submit', _value=T('submit'), _class="btn btn-primary"))),
TR('', '', INPUT(_type='submit', _value=T('Submit'), _class='btn btn-primary'))),
_action=URL(r=request, args=request.args))
tb = None
@@ -254,8 +254,8 @@ def select():
if is_imap:
fields = [db[table][name] for name in
("id", "uid", "created", "to",
"sender", "subject")]
('id', 'uid', 'created', 'to',
'sender', 'subject')]
if orderby:
rows = db(query, ignore_common_filters=True).select(
*fields, limitby=(start, stop),
@@ -271,10 +271,10 @@ def select():
# begin handle upload csv
csv_table = table or request.vars.table
if csv_table:
formcsv = FORM(str(T('or import from csv file')) + " ",
formcsv = FORM(str(T('or import from csv file')) + ' ',
INPUT(_type='file', _name='csvfile'),
INPUT(_type='hidden', _value=csv_table, _name='table'),
INPUT(_type='submit', _value=T('import'), _class="btn btn-primary"))
INPUT(_type='submit', _value=T('import'), _class='btn btn-primary'))
else:
formcsv = None
if formcsv and formcsv.process().accepted:
@@ -356,26 +356,26 @@ def state():
def ccache():
if is_gae:
form = FORM(
P(TAG.BUTTON(T("Clear CACHE?"), _type="submit", _name="yes", _value="yes")))
P(TAG.BUTTON(T('Clear CACHE?'), _type='submit', _name='yes', _value='yes')))
else:
cache.ram.initialize()
cache.disk.initialize()
form = FORM(
P(TAG.BUTTON(
T("Clear CACHE?"), _type="submit", _name="yes", _value="yes")),
T('Clear CACHE?'), _type='submit', _name='yes', _value='yes')),
P(TAG.BUTTON(
T("Clear RAM"), _type="submit", _name="ram", _value="ram")),
T('Clear RAM'), _type='submit', _name='ram', _value='ram')),
P(TAG.BUTTON(
T("Clear DISK"), _type="submit", _name="disk", _value="disk")),
T('Clear DISK'), _type='submit', _name='disk', _value='disk')),
)
if form.accepts(request.vars, session):
session.flash = ""
session.flash = ''
if is_gae:
if request.vars.yes:
cache.ram.clear()
session.flash += T("Cache Cleared")
session.flash += T('Cache Cleared')
else:
clear_ram = False
clear_disk = False
@@ -387,10 +387,10 @@ def ccache():
clear_disk = True
if clear_ram:
cache.ram.clear()
session.flash += T("Ram Cleared")
session.flash += T('Ram Cleared')
if clear_disk:
cache.disk.clear()
session.flash += T("Disk Cleared")
session.flash += T('Disk Cleared')
redirect(URL(r=request))
try:
@@ -436,7 +436,7 @@ def ccache():
gae_stats['ratio'] = ((gae_stats['hits'] * 100) /
(gae_stats['hits'] + gae_stats['misses']))
except ZeroDivisionError:
gae_stats['ratio'] = T("?")
gae_stats['ratio'] = T('?')
gae_stats['oldest'] = GetInHMS(time.time() - gae_stats['oldest_item_age'])
total.update(gae_stats)
else:
@@ -502,7 +502,7 @@ def ccache():
TR(TD(B(T('Key'))), TD(B(T('Time in Cache (h:m:s)')))),
*[TR(TD(k[0]), TD('%02d:%02d:%02d' % k[1])) for k in keys],
**dict(_class='cache-keys',
_style="border-collapse: separate; border-spacing: .5em;"))
_style='border-collapse: separate; border-spacing: .5em;'))
if not is_gae:
ram['keys'] = key_table(ram['keys'])
@@ -536,26 +536,26 @@ def table_template(table):
# This is horribe HTML but the only one graphiz understands
rows = []
cellpadding = 4
color = "#000000"
bgcolor = "#FFFFFF"
face = "Helvetica"
face_bold = "Helvetica Bold"
color = '#000000'
bgcolor = '#FFFFFF'
face = 'Helvetica'
face_bold = 'Helvetica Bold'
border = 0
rows.append(TR(TD(FONT(table, _face=face_bold, _color=bgcolor),
_colspan=3, _cellpadding=cellpadding,
_align="center", _bgcolor=color)))
_align='center', _bgcolor=color)))
for row in db[table]:
rows.append(TR(TD(FONT(row.name, _color=color, _face=face_bold),
_align="left", _cellpadding=cellpadding,
_align='left', _cellpadding=cellpadding,
_border=border),
TD(FONT(row.type, _color=color, _face=face),
_align="left", _cellpadding=cellpadding,
_align='left', _cellpadding=cellpadding,
_border=border),
TD(FONT(types(row), _color=color, _face=face),
_align="center", _cellpadding=cellpadding,
_align='center', _cellpadding=cellpadding,
_border=border)))
return "< %s >" % TABLE(*rows, **dict(_bgcolor=bgcolor, _border=1,
return '< %s >' % TABLE(*rows, **dict(_bgcolor=bgcolor, _border=1,
_cellborder=0, _cellspacing=0)
).xml()
@@ -632,15 +632,15 @@ def hooks():
if len(functions):
method_hooks.append({'name': op, 'functions':functions})
if len(method_hooks):
tables.append({'name': "%s.%s" % (db_str, t), 'slug': IS_SLUG()("%s.%s" % (db_str,t))[0], 'method_hooks':method_hooks})
tables.append({'name': '%s.%s' % (db_str, t), 'slug': IS_SLUG()('%s.%s' % (db_str,t))[0], 'method_hooks':method_hooks})
# Render
ul_main = UL(_class='nav nav-list')
for t in tables:
ul_main.append(A(t['name'], _onclick="collapse('a_%s')" % t['slug']))
ul_t = UL(_class='nav nav-list', _id="a_%s" % t['slug'], _style='display:none')
ul_t = UL(_class='nav nav-list', _id='a_%s' % t['slug'], _style='display:none')
for op in t['method_hooks']:
ul_t.append(LI(op['name']))
ul_t.append(UL([LI(A(f['funcname'], _class="editor_filelink", _href=f['url']if 'url' in f else None, **{'_data-lineno':f['lineno']-1})) for f in op['functions']]))
ul_t.append(UL([LI(A(f['funcname'], _class='editor_filelink', _href=f['url']if 'url' in f else None, **{'_data-lineno':f['lineno']-1})) for f in op['functions']]))
ul_main.append(ul_t)
return ul_main
@@ -650,11 +650,11 @@ def hooks():
# ###########################################################
def d3_graph_model():
""" See https://www.facebook.com/web2py/posts/145613995589010 from Bruno Rocha
''' See https://www.facebook.com/web2py/posts/145613995589010 from Bruno Rocha
and also the app_admin bg_graph_model function
Create a list of table dicts, called "nodes"
"""
Create a list of table dicts, called 'nodes'
'''
nodes = []
links = []
@@ -670,10 +670,10 @@ def d3_graph_model():
elif f_type == 'string':
disp = field.length
elif f_type == 'id':
disp = "PK"
disp = 'PK'
elif f_type.startswith('reference') or \
f_type.startswith('list:reference'):
disp = "FK"
disp = 'FK'
else:
disp = ' '
fields.append(dict(name=field.name, type=field.type, disp=disp))
@@ -685,7 +685,7 @@ def d3_graph_model():
links.append(dict(source=tablename, target = referenced_table))
nodes.append(dict(name=tablename, type="table", fields = fields))
nodes.append(dict(name=tablename, type='table', fields = fields))
# d3 v4 allows individual modules to be specified. The complete d3 library is included below.
response.files.append(URL('admin','static','js/d3.min.js'))

View File

@@ -3,7 +3,7 @@
<div>
{{=get_content('main')}}
<center>
<iframe src="//player.vimeo.com/hubnut/album/3016728?color=ff6600&amp;background=ffffff&amp;slideshow=1&amp;video_title=1&amp;video_byline=1" width="400" height="300" frameborder="0" webkitAllowFullScreen mozallowfullscreen allowFullScreen></iframe>
<iframe src="https://player.vimeo.com/video/104800778?color=ff6600&amp;background=ffffff&amp;slideshow=1&amp;video_title=1&amp;video_byline=1" width="400" height="300" frameborder="0" webkitAllowFullScreen mozallowfullscreen allowFullScreen></iframe>
</center>
{{=get_content('official')}}
{{=get_content('community')}}

View File

@@ -9,7 +9,8 @@
<table class="twothirds">
<thead>
<tr>
<th>For Normal Users</th>
<th>For Normal Users (Py3)</th>
<th>For Legacy Users (Py2)</th>
<th>For Testers</th>
<th>For Developers</th>
</tr>
@@ -17,10 +18,13 @@
<tbody>
<tr>
<td>
<a class="btn btn180 rounded green" href="https://mdipierro.pythonanywhere.com/examples/static/web2py_win.zip">For Windows</a>
<a class="btn btn180 rounded green" href="https://mdipierro.pythonanywhere.com/examples/static/web2py_win.zip">Windows binaries</a>
</td>
<td>
<a class="btn btn180 rounded yellow" href="https://mdipierro.pythonanywhere.com/examples/static/nightly/web2py_win.zip">For Windows</a>
<a class="btn btn180 rounded" href="https://mdipierro.pythonanywhere.com/examples/static/web2py_win_py2.zip">Windows binaries</a>
</td>
<td>
<a class="btn btn180 rounded yellow" href="https://mdipierro.pythonanywhere.com/examples/static/nightly/web2py_win.zip">Windows binaries</a>
</td>
<td>
<a class="btn btn180 rounded red" href="http://github.com/web2py/web2py/">Git Repository</a>
@@ -28,17 +32,25 @@
</tr>
<tr>
<td>
<a class="btn btn180 rounded green" href="https://mdipierro.pythonanywhere.com/examples/static/web2py_osx.zip">For Mac</a>
<a class="btn btn180 rounded green" href="https://mdipierro.pythonanywhere.com/examples/static/web2py_osx.zip">Mac binaries</a>
</td>
<td>
<a class="btn btn180 rounded yellow" href="https://mdipierro.pythonanywhere.com/examples/static/nightly/web2py_osx.zip">For Mac</a>
<a class="btn btn180 rounded" href="https://mdipierro.pythonanywhere.com/examples/static/web2py_osx_py2.zip">Mac binaries</a>
</td>
<td>
<a class="btn btn180 rounded yellow" href="https://mdipierro.pythonanywhere.com/examples/static/nightly/web2py_osx.zip">Mac binaries</a>
</td>
<td>
<a class="btn btn180 rounded" href="http://mdipierro.github.io/web2py/web2py_manual_5th.pdf">Manual</a>
</td>
<td></td>
</tr>
<tr>
<td>
<a class="btn btn180 rounded green" href="https://mdipierro.pythonanywhere.com/examples/static/web2py_src.zip">Source Code</a>
</td>
<td>
<a class="btn btn180 rounded" href="https://mdipierro.pythonanywhere.com/examples/static/web2py_src.zip">Source Code</a>
</td>
<td>
<a class="btn btn180 rounded yellow" href="https://mdipierro.pythonanywhere.com/examples/static/nightly/web2py_src.zip">Source Code</a>
</td>
@@ -48,7 +60,8 @@
</tr>
<tr>
<td>
<a class="btn btn180 rounded green" href="http://mdipierro.github.io/web2py/web2py_manual_5th.pdf">Manual</a>
</td>
<td>
</td>
<td>
<a class="btn btn180 rounded" href="https://github.com/web2py/web2py/releases">Change Log</a>
@@ -62,13 +75,19 @@
</center>
<p style="text-align:left;">
The source code version works on Windows and most Unix systems, including <b>Linux</b>, <b>BSD</b> and <b>Mac</b> . It requires Python 2.6 (no more supported), Python 2.7 (stable) or Python 3.5+ (recommended for new projects) already installed on your system.
There are also binary packages for Windows and Mac OS X. They include the Python 2.7 interpreter so you do not need to have it pre-installed.
The source code version works on Windows and most Unix systems, including <b>Linux</b>, <b>BSD</b> and <b>Mac</b> . It requires Python 3.5+ (recommended for new projects)
or Python 2.7+ (stable, for use with legacy apps) already installed on your system.
</p>
<p style="text-align:left;">
There are also binary packages for Windows and MacOs. They include the Python interpreter version 3.7.4 or 2.7.16, so you do not need to have it pre-installed.
</p>
<h3>Instructions</h3>
<p>With the binary packages, after download, just unzip it and then click on web2py.exe (windows) or web2py.app (osx).
If you prefer to run it from source with your own Python interpreter alreay installed, type:</p>
<p>With the binary packages, after download, just unzip it and then click on web2py.exe (Windows) or web2py (MacOs).</p>
<p>Note that on recent MacOs versions (10.12+) you could face problems in running the binary App program, due to the last changes to the security settings.
In this case, press the 'control' key + click on downloaded file and then 'open' it (confirm the warnings). Finally move the program in Applications and run it from there.
</p>
<p> If you prefer to run it from source with your own Python interpreter already installed, type:</p>
{{=CODE("python web2py.py", language=None, counter='>', _class='boxCode')}}
<p>or for more info type:</p>
{{=CODE("python web2py.py -h", language=None, counter='>', _class='boxCode')}}

View File

@@ -30,7 +30,7 @@ except:
if request.is_https:
session.secure()
elif (remote_addr not in hosts) and (remote_addr != "127.0.0.1") and \
elif (remote_addr not in hosts) and (remote_addr != '127.0.0.1') and \
(request.function != 'manage'):
raise HTTP(200, T('appadmin is disabled because insecure channel'))
@@ -46,7 +46,7 @@ if request.function == 'manage':
auth.table_permission()])
manager_role = manager_action.get('role', None) if manager_action else None
if not (gluon.fileutils.check_credentials(request) or auth.has_membership(manager_role)):
raise HTTP(403, "Not authorized")
raise HTTP(403, 'Not authorized')
menu = False
elif (request.application == 'admin' and not session.authorized) or \
(request.application != 'admin' and not gluon.fileutils.check_credentials(request)):
@@ -182,7 +182,7 @@ def select():
db = get_database(request)
dbname = request.args[0]
try:
is_imap = db._uri.startswith("imap://")
is_imap = db._uri.startswith('imap://')
except (KeyError, AttributeError, TypeError):
is_imap = False
regex = re.compile(r'(?P<table>\w+)\.(?P<field>\w+)=(?P<value>\d+)')
@@ -224,15 +224,15 @@ def select():
session.last_orderby = orderby
session.last_query = request.vars.query
form = FORM(TABLE(TR(T('Query:'), '', INPUT(_style='width:400px',
_name='query', _value=request.vars.query or '', _class="form-control",
_name='query', _value=request.vars.query or '', _class='form-control',
requires=IS_NOT_EMPTY(
error_message=T("Cannot be empty")))), TR(T('Update:'),
error_message=T('Cannot be empty')))), TR(T('Update:'),
INPUT(_name='update_check', _type='checkbox',
value=False), INPUT(_style='width:400px',
_name='update_fields', _value=request.vars.update_fields
or '', _class="form-control")), TR(T('Delete:'), INPUT(_name='delete_check',
or '', _class='form-control')), TR(T('Delete:'), INPUT(_name='delete_check',
_class='delete', _type='checkbox', value=False), ''),
TR('', '', INPUT(_type='submit', _value=T('submit'), _class="btn btn-primary"))),
TR('', '', INPUT(_type='submit', _value=T('Submit'), _class='btn btn-primary'))),
_action=URL(r=request, args=request.args))
tb = None
@@ -254,8 +254,8 @@ def select():
if is_imap:
fields = [db[table][name] for name in
("id", "uid", "created", "to",
"sender", "subject")]
('id', 'uid', 'created', 'to',
'sender', 'subject')]
if orderby:
rows = db(query, ignore_common_filters=True).select(
*fields, limitby=(start, stop),
@@ -271,10 +271,10 @@ def select():
# begin handle upload csv
csv_table = table or request.vars.table
if csv_table:
formcsv = FORM(str(T('or import from csv file')) + " ",
formcsv = FORM(str(T('or import from csv file')) + ' ',
INPUT(_type='file', _name='csvfile'),
INPUT(_type='hidden', _value=csv_table, _name='table'),
INPUT(_type='submit', _value=T('import'), _class="btn btn-primary"))
INPUT(_type='submit', _value=T('import'), _class='btn btn-primary'))
else:
formcsv = None
if formcsv and formcsv.process().accepted:
@@ -356,26 +356,26 @@ def state():
def ccache():
if is_gae:
form = FORM(
P(TAG.BUTTON(T("Clear CACHE?"), _type="submit", _name="yes", _value="yes")))
P(TAG.BUTTON(T('Clear CACHE?'), _type='submit', _name='yes', _value='yes')))
else:
cache.ram.initialize()
cache.disk.initialize()
form = FORM(
P(TAG.BUTTON(
T("Clear CACHE?"), _type="submit", _name="yes", _value="yes")),
T('Clear CACHE?'), _type='submit', _name='yes', _value='yes')),
P(TAG.BUTTON(
T("Clear RAM"), _type="submit", _name="ram", _value="ram")),
T('Clear RAM'), _type='submit', _name='ram', _value='ram')),
P(TAG.BUTTON(
T("Clear DISK"), _type="submit", _name="disk", _value="disk")),
T('Clear DISK'), _type='submit', _name='disk', _value='disk')),
)
if form.accepts(request.vars, session):
session.flash = ""
session.flash = ''
if is_gae:
if request.vars.yes:
cache.ram.clear()
session.flash += T("Cache Cleared")
session.flash += T('Cache Cleared')
else:
clear_ram = False
clear_disk = False
@@ -387,10 +387,10 @@ def ccache():
clear_disk = True
if clear_ram:
cache.ram.clear()
session.flash += T("Ram Cleared")
session.flash += T('Ram Cleared')
if clear_disk:
cache.disk.clear()
session.flash += T("Disk Cleared")
session.flash += T('Disk Cleared')
redirect(URL(r=request))
try:
@@ -436,7 +436,7 @@ def ccache():
gae_stats['ratio'] = ((gae_stats['hits'] * 100) /
(gae_stats['hits'] + gae_stats['misses']))
except ZeroDivisionError:
gae_stats['ratio'] = T("?")
gae_stats['ratio'] = T('?')
gae_stats['oldest'] = GetInHMS(time.time() - gae_stats['oldest_item_age'])
total.update(gae_stats)
else:
@@ -502,7 +502,7 @@ def ccache():
TR(TD(B(T('Key'))), TD(B(T('Time in Cache (h:m:s)')))),
*[TR(TD(k[0]), TD('%02d:%02d:%02d' % k[1])) for k in keys],
**dict(_class='cache-keys',
_style="border-collapse: separate; border-spacing: .5em;"))
_style='border-collapse: separate; border-spacing: .5em;'))
if not is_gae:
ram['keys'] = key_table(ram['keys'])
@@ -536,26 +536,26 @@ def table_template(table):
# This is horribe HTML but the only one graphiz understands
rows = []
cellpadding = 4
color = "#000000"
bgcolor = "#FFFFFF"
face = "Helvetica"
face_bold = "Helvetica Bold"
color = '#000000'
bgcolor = '#FFFFFF'
face = 'Helvetica'
face_bold = 'Helvetica Bold'
border = 0
rows.append(TR(TD(FONT(table, _face=face_bold, _color=bgcolor),
_colspan=3, _cellpadding=cellpadding,
_align="center", _bgcolor=color)))
_align='center', _bgcolor=color)))
for row in db[table]:
rows.append(TR(TD(FONT(row.name, _color=color, _face=face_bold),
_align="left", _cellpadding=cellpadding,
_align='left', _cellpadding=cellpadding,
_border=border),
TD(FONT(row.type, _color=color, _face=face),
_align="left", _cellpadding=cellpadding,
_align='left', _cellpadding=cellpadding,
_border=border),
TD(FONT(types(row), _color=color, _face=face),
_align="center", _cellpadding=cellpadding,
_align='center', _cellpadding=cellpadding,
_border=border)))
return "< %s >" % TABLE(*rows, **dict(_bgcolor=bgcolor, _border=1,
return '< %s >' % TABLE(*rows, **dict(_bgcolor=bgcolor, _border=1,
_cellborder=0, _cellspacing=0)
).xml()
@@ -632,15 +632,15 @@ def hooks():
if len(functions):
method_hooks.append({'name': op, 'functions':functions})
if len(method_hooks):
tables.append({'name': "%s.%s" % (db_str, t), 'slug': IS_SLUG()("%s.%s" % (db_str,t))[0], 'method_hooks':method_hooks})
tables.append({'name': '%s.%s' % (db_str, t), 'slug': IS_SLUG()('%s.%s' % (db_str,t))[0], 'method_hooks':method_hooks})
# Render
ul_main = UL(_class='nav nav-list')
for t in tables:
ul_main.append(A(t['name'], _onclick="collapse('a_%s')" % t['slug']))
ul_t = UL(_class='nav nav-list', _id="a_%s" % t['slug'], _style='display:none')
ul_t = UL(_class='nav nav-list', _id='a_%s' % t['slug'], _style='display:none')
for op in t['method_hooks']:
ul_t.append(LI(op['name']))
ul_t.append(UL([LI(A(f['funcname'], _class="editor_filelink", _href=f['url']if 'url' in f else None, **{'_data-lineno':f['lineno']-1})) for f in op['functions']]))
ul_t.append(UL([LI(A(f['funcname'], _class='editor_filelink', _href=f['url']if 'url' in f else None, **{'_data-lineno':f['lineno']-1})) for f in op['functions']]))
ul_main.append(ul_t)
return ul_main
@@ -650,11 +650,11 @@ def hooks():
# ###########################################################
def d3_graph_model():
""" See https://www.facebook.com/web2py/posts/145613995589010 from Bruno Rocha
''' See https://www.facebook.com/web2py/posts/145613995589010 from Bruno Rocha
and also the app_admin bg_graph_model function
Create a list of table dicts, called "nodes"
"""
Create a list of table dicts, called 'nodes'
'''
nodes = []
links = []
@@ -670,10 +670,10 @@ def d3_graph_model():
elif f_type == 'string':
disp = field.length
elif f_type == 'id':
disp = "PK"
disp = 'PK'
elif f_type.startswith('reference') or \
f_type.startswith('list:reference'):
disp = "FK"
disp = 'FK'
else:
disp = ' '
fields.append(dict(name=field.name, type=field.type, disp=disp))
@@ -685,7 +685,7 @@ def d3_graph_model():
links.append(dict(source=tablename, target = referenced_table))
nodes.append(dict(name=tablename, type="table", fields = fields))
nodes.append(dict(name=tablename, type='table', fields = fields))
# d3 v4 allows individual modules to be specified. The complete d3 library is included below.
response.files.append(URL('admin','static','js/d3.min.js'))

0
applications/welcome/languages/ar.py Executable file → Normal file
View File

0
applications/welcome/languages/ca.py Executable file → Normal file
View File

0
applications/welcome/languages/cs.py Executable file → Normal file
View File

0
applications/welcome/languages/en.py Executable file → Normal file
View File

0
applications/welcome/languages/es.py Executable file → Normal file
View File

0
applications/welcome/languages/fr-ca.py Executable file → Normal file
View File

0
applications/welcome/languages/fr.py Executable file → Normal file
View File

0
applications/welcome/languages/hi.py Executable file → Normal file
View File

0
applications/welcome/languages/hu.py Executable file → Normal file
View File

0
applications/welcome/languages/id.py Executable file → Normal file
View File

0
applications/welcome/languages/it.py Executable file → Normal file
View File

0
applications/welcome/languages/my-mm.py Executable file → Normal file
View File

0
applications/welcome/languages/my.py Executable file → Normal file
View File

0
applications/welcome/languages/nl.py Executable file → Normal file
View File

0
applications/welcome/languages/pl.py Executable file → Normal file
View File

0
applications/welcome/languages/plural-cs.py Executable file → Normal file
View File

0
applications/welcome/languages/plural-en.py Executable file → Normal file
View File

0
applications/welcome/languages/plural-es.py Executable file → Normal file
View File

0
applications/welcome/languages/plural-ru.py Executable file → Normal file
View File

0
applications/welcome/languages/plural-uk.py Executable file → Normal file
View File

208
applications/welcome/languages/pt-br.py Executable file → Normal file
View File

@@ -1,8 +1,10 @@
# -*- coding: utf-8 -*-
{
'!=': '!=',
'!langcode!': 'pt-br',
'!langname!': 'Português (do Brasil)',
'"update" is an optional expression like "field1=\'newvalue\'". You cannot update or delete the results of a JOIN': '"update" é uma expressão opcional como "campo1=\'novovalor\'". Você não pode atualizar ou apagar os resultados de um JOIN',
'%(nrows)s records found': '%(nrows)s registros encontrados',
'%s %%{row} deleted': '%s linha apagadas',
'%s %%{row} updated': '%s linha atualizadas',
'%s selected': '%s selecionado',
@@ -12,6 +14,13 @@
'**%(items)s** %%{item(items)}, **%(bytes)s** %%{byte(bytes)}': '**%(items)s** %%{item(items)}, **%(bytes)s** %%{byte(bytes)}',
'**%(items)s** items, **%(bytes)s** %%{byte(bytes)}': '**%(items)s** items, **%(bytes)s** %%{byte(bytes)}',
'**not available** (requires the Python [[guppy http://pypi.python.org/pypi/guppy/ popup]] library)': '**not available** (requires the Python [[guppy http://pypi.python.org/pypi/guppy/ popup]] library)',
'+ And': '+ E',
'+ Or': '+ Ou',
'<': '<',
'<=': '<=',
'=': '=',
'>': '>',
'>=': '>=',
'?': '?',
'@markmin\x01(**%.0d MB**)': '(**%.0d MB**)',
'@markmin\x01**%(items)s** %%{item(items)}, **%(bytes)s** %%{byte(bytes)}': '**%(items)s** %%{item(items)}, **%(bytes)s** %%{byte(bytes)}',
@@ -22,23 +31,28 @@
'@markmin\x01Cache contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.': 'Cache contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.',
'@markmin\x01DISK contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.': 'DISK contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.',
'@markmin\x01Hit Ratio: **%(ratio)s%%** (**%(hits)s** %%{hit(hits)} and **%(misses)s** %%{miss(misses)})': 'Hit Ratio: **%(ratio)s%%** (**%(hits)s** %%{hit(hits)} and **%(misses)s** %%{miss(misses)})',
'@markmin\x01Number of entries: **%s**': 'Number of entries: **%s**',
'@markmin\x01Number of entries: **%s**': 'Número de entradas: **%s**',
'@markmin\x01RAM contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.': 'RAM contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.',
'``**not available**``:red (requires the Python [[guppy http://pypi.python.org/pypi/guppy/ popup]] library)': '``**not available**``:red (requires the Python [[guppy http://pypi.python.org/pypi/guppy/ popup]] library)',
'A new password was emailed to you': 'A new password was emailed to you',
'A new password was emailed to you': 'Uma nova senha foi enviada por email para você',
'About': 'Sobre',
'Access Control': 'Controle de Acesso',
'Add Record': 'Novo Registro',
'Add record to database': 'Adicionar registro ao banco de dados',
'Add this to the search as an AND term': 'Adicionar à pesquisa como um termo E',
'Add this to the search as an OR term': 'Adicionar à pesquisa como um termo OU',
'admin': 'admin',
'Administrative Interface': 'Interface Administrativa',
'Administrative interface': 'Interface administrativa',
'Ajax Recipes': 'Receitas de Ajax',
'An error occured, please [[reload %s]] the page': 'An error occured, please [[reload %s]] the page',
'API Example': 'API Example',
'API Example': 'Exmplo de API',
'appadmin is disabled because insecure channel': 'Administração desativada porque o canal não é seguro',
'Apply changes': 'Apply changes',
'Apply changes': 'Aplicar Mudanças',
'Are you sure you want to delete this object?': 'Você tem certeza que quer apagar este objeto?',
'Authentication code': 'Authentication code',
'Authentication code': 'Código de autenticação',
'Available Databases and Tables': 'Bancos de dados e tabelas disponíveis',
'Back': 'Voltar',
'Buy this book': 'Compre o livro',
"Buy web2py's book": 'Compre o livro do web2py',
'cache': 'cache',
@@ -48,19 +62,27 @@
'Cache Keys': 'Chaves de cache',
'Cannot be empty': 'Não pode estar vazio',
'change password': 'mudar senha',
'Change Password': 'Change Password',
'Change password': 'Change password',
'Change Password': 'Trocar Senhar',
'Change password': 'Trocar senha',
'Check to delete': 'Marque para apagar',
'Clear': 'Limpar',
'Clear CACHE?': 'Limpar CACHE?',
'Clear DISK': 'Limpar DISCO',
'Clear RAM': 'Limpar memória RAM',
'Click on the link %(link)s to reset your password': 'Click on the link %(link)s to reset your password',
'Client IP': 'IP do cliente',
'Close': 'Fechar',
'Comma-separated export including columns not shown; fields from other tables are exported as raw values for faster export': 'Comma-separated export including columns not shown; fields from other tables are exported as raw values for faster export',
'Comma-separated export of visible columns. Fields from other tables are exported as they appear on-screen but this may be slow for many rows': 'Comma-separated export of visible columns. Fields from other tables are exported as they appear on-screen but this may be slow for many rows',
'Community': 'Comunidade',
'Components and Plugins': 'Componentes e Plugins',
'Config.ini': 'Config.ini',
'Confirm Password': 'Confirme a Senha',
'contains': 'contém',
'Controller': 'Controlador',
'Copyright': 'Copyright',
'CSV': 'CSV',
'CSV (hidden cols)': 'CSV (col. ocultas)',
'Current request': 'Requisição atual',
'Current response': 'Resposta atual',
'Current session': 'Sessão atual',
@@ -68,9 +90,10 @@
'data uploaded': 'dados enviados',
'Database': 'banco de dados',
'Database %s select': 'Selecionar banco de dados %s',
'Database Administration (appadmin)': 'Database Administration (appadmin)',
'Database Administration (appadmin)': 'Administração de Banco de Dados (appadmin)',
'db': 'bd',
'DB Model': 'Modelo BD',
'Delete': 'Excluir',
'Delete:': 'Apagar:',
'Demo': 'Demo',
'Deployment Recipes': 'Receitas de deploy',
@@ -91,50 +114,57 @@
'edit profile': 'editar perfil',
'Edit This App': 'Editar esta aplicação',
'Email and SMS': 'Email e SMS',
'Email sent': 'Email sent',
'Email verification': 'Email verification',
'Email verified': 'Email verified',
'Email sent': 'Email enviado',
'Email verification': 'Verificação de email',
'Email verified': 'Email verificado',
'Enter an integer between %(min)g and %(max)g': 'Informe um valor inteiro entre %(min)g e %(max)g',
'Errors': 'Erros',
'export as csv file': 'exportar como um arquivo csv',
'Export:': 'Exportar:',
'FAQ': 'Perguntas frequentes',
'First name': 'Nome',
'Forms and Validators': 'Formulários e Validadores',
'Free Applications': 'Aplicações gratuitas',
'Function disabled': 'Function disabled',
'Graph Model': 'Graph Model',
'Function disabled': 'Função desabilitada',
'Graph Model': 'Modelo em Grafo',
'Grid Example': 'Exemplo de Grade',
'Group %(group_id)s created': 'Group %(group_id)s created',
'Group %(group_id)s deleted': 'Group %(group_id)s deleted',
'Group %(group_id)s created': 'Grupo %(group_id)s criado',
'Group %(group_id)s deleted': 'Grupo %(group_id)s excluído',
'Group ID': 'ID do Grupo',
'Group uniquely assigned to user %(id)s': 'Group uniquely assigned to user %(id)s',
'Group uniquely assigned to user %(id)s': 'Gurpo unicamente atribuído ao usuário %(id)s',
'Groups': 'Grupos',
'Hello World': 'Olá Mundo',
'Helping web2py': 'Helping web2py',
'Helping web2py': 'Ajudando web2py',
'Hit Ratio: **%(ratio)s%%** (**%(hits)s** %%{hit(hits)} and **%(misses)s** %%{miss(misses)})': 'Hit Ratio: **%(ratio)s%%** (**%(hits)s** %%{hit(hits)} and **%(misses)s** %%{miss(misses)})',
'Home': 'Principal',
'How did you get here?': 'Como você chegou aqui?',
'HTML': 'HTML',
'HTML export of visible columns': 'HTML exportar colunas visíveis',
'Id': 'Id',
'import': 'importar',
'Import/Export': 'Importar/Exportar',
'in': 'em',
'Incorrect code. {0} more attempt(s) remaining.': 'Incorrect code. {0} more attempt(s) remaining.',
'Index': 'Início',
'insert new': 'inserir novo',
'insert new %s': 'inserir novo %s',
'Insufficient privileges': 'Insufficient privileges',
'Insufficient privileges': 'Privilégios insuficientes',
'Internal State': 'Estado Interno',
'Introduction': 'Introdução',
'Invalid email': 'Email inválido',
'Invalid key': 'Invalid key',
'Invalid login': 'Invalid login',
'Invalid password': 'Invalid password',
'Invalid key': 'Chave inválida',
'Invalid login': 'Login Inválido',
'Invalid password': 'Senha inválida',
'Invalid Query': 'Consulta Inválida',
'invalid request': 'requisição inválida',
'Invalid reset password': 'Invalid reset password',
'Invalid user': 'Invalid user',
'Invalid username': 'Invalid username',
'Invitation to join %(site)s': 'Invitation to join %(site)s',
'Invalid reset password': 'Recriação de senha inválida',
'Invalid user': 'Usuário inválido',
'Invalid username': 'Nome de usuário inválido',
'Invitation to join %(site)s': 'Convite para entrar %(site)s',
'JSON': 'JSON',
'JSON export of visible columns': 'JSON exportar colunas visíveis',
'Key': 'Chave',
'Key verified': 'Key verified',
'Key verified': 'Chave verificada',
'Last name': 'Sobrenome',
'Layout': 'Layout',
'Layout Plugins': 'Plugins de Layout',
@@ -142,13 +172,13 @@
'Live chat': 'Chat ao vivo',
'Live Chat': 'Chat ao vivo',
'Log In': 'Entrar',
'Logged in': 'Logged in',
'Logged out': 'Logged out',
'Logged in': 'Conectado',
'Logged out': 'Desconectado',
'login': 'Entrar',
'Login': 'Entrar',
'Login disabled by administrator': 'Login disabled by administrator',
'Login disabled by administrator': 'Login desabilitado pelo administrador',
'logout': 'Sair',
'Logout': 'Logout',
'Logout': 'Sair',
'Lost Password': 'Esqueceu sua senha?',
'lost password?': 'esqueceu sua senha?',
'Lost your password?': 'Esqueceu sua senha?',
@@ -160,16 +190,19 @@
'Menu Model': 'Modelo de Menu',
'My Sites': 'Meus sites',
'Name': 'Nome',
'New password': 'New password',
'New password': 'Nova senha',
'New Record': 'Novo Registro',
'new record inserted': 'novo registro inserido',
'New Search': 'Nova pesquisa',
'next %s rows': 'próximas %s ´linhas',
'next 100 rows': 'próximas 100 linhas',
'No databases in this application': 'Não há bancos de dados nesta aplicação',
'No records found': 'Não foram encontrados registros',
'not in': 'não está em',
'Number of entries: **%s**': 'Número de entradas: **%s**',
'Object or table name': 'Nome do objeto do da tabela',
'Old password': 'Old password',
'Online book': 'Online book',
'Old password': 'Senha antiga',
'Online book': 'Livro online',
'Online examples': 'Exemplos online',
'or import from csv file': 'ou importar de um arquivo csv',
'Origin': 'Origem',
@@ -177,66 +210,71 @@
'Other Recipes': 'Outras Receitas',
'Overview': 'Visão Geral',
'Password': 'Senha',
'Password changed': 'Password changed',
"Password fields don't match": "Password fields don't match",
'Password reset': 'Password reset',
'Password retrieve': 'Password retrieve',
'Permission': 'Permission',
'Permissions': 'Permissions',
'please input your password again': 'please input your password again',
'Password changed': 'Senha trocada',
"Password fields don't match": 'Senhas não conferem',
'Password reset': 'Recriar senha',
'Password retrieve': 'Recuperar senha',
'Permission': 'Permissão',
'Permissions': 'Permissões',
'please input your password again': 'por favor digite a senha novamente',
'Plugins': 'Plugins',
'Powered by': 'Desenvolvido com',
'Preface': 'Prefácio',
'previous %s rows': '%s linhas anteriores',
'previous 100 rows': '100 linhas anteriores',
'Profile': 'Profile',
'Profile updated': 'Profile updated',
'Profile': 'Perfil',
'Profile updated': 'Perfil atualizado',
'pygraphviz library not found': 'biblioteca pygraphviz não encontrada',
'Python': 'Python',
'Query:': 'Consulta:',
'Quick Examples': 'Exemplos rápidos',
'RAM': 'RAM',
'RAM Cache Keys': 'RAM Cache Keys',
'RAM Cache Keys': 'Chaves de Cache RAM ',
'Ram Cleared': 'Ram Limpa',
'RAM contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.': 'RAM contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.',
'Recipes': 'Receitas',
'Record': 'Registro',
'Record %(id)s created': 'Record %(id)s created',
'Record %(id)s deleted': 'Record %(id)s deleted',
'Record %(id)s read': 'Record %(id)s read',
'Record %(id)s updated': 'Record %(id)s updated',
'Record Created': 'Record Created',
'Record Deleted': 'Record Deleted',
'Record %(id)s created': 'Registro %(id)s criado',
'Record %(id)s deleted': 'Registro %(id)s excluído',
'Record %(id)s read': 'Registro %(id)s lido',
'Record %(id)s updated': 'Registro %(id)s atualizado',
'Record Created': 'Registro Criado',
'Record Deleted': 'Registro Excluído',
'record does not exist': 'registro não existe',
'Record ID': 'ID do Registro',
'Record id': 'id do registro',
'Record Updated': 'Record Updated',
'register': 'Registre-se',
'Register': 'Registre-se',
'Registration identifier': 'Idenficador de registro',
'Registration is pending approval': 'Registration is pending approval',
'Registration key': 'Chave de registro',
'Registration needs verification': 'Registration needs verification',
'Registration successful': 'Registration successful',
'Record Updated': 'Registro Atualizado',
'register': 'Cadastre-se',
'Register': 'Cadastre-se',
'Registration identifier': 'Idenficador de Cadastro',
'Registration is pending approval': 'Aprovação de cadastro pendente',
'Registration key': 'Chave de cadastro',
'Registration needs verification': 'Cadastro necessita verficação',
'Registration successful': 'Cadastro finalizado',
'Remember me (for 30 days)': 'Mantenha-me logado (por 30 dias)',
'Request reset password': 'Request reset password',
'Request reset password': 'Requerer recriação de senha',
'Reset Password key': 'Resetar chave de senha',
'Resources': 'Recursos',
'Role': 'Papel',
'Roles': 'Roles',
'Roles': 'Papéis',
'Rows in Table': 'Linhas na tabela',
'Rows selected': 'Linhas selecionadas',
'Save model as...': 'Salvar modelo como...',
'Search': 'Pesquisar',
'Semantic': 'Semântico',
'Services': 'Serviço',
'Sign Up': 'Cadastrar',
'Sign up': 'Cadastrar',
'Size of cache:': 'Tamanho do cache:',
'Spreadsheet-optimised export of tab-separated content including hidden columns. May be slow': 'Spreadsheet-optimised export of tab-separated content including hidden columns. May be slow',
'Spreadsheet-optimised export of tab-separated content, visible columns only. May be slow.': 'Spreadsheet-optimised export of tab-separated content, visible columns only. May be slow.',
'Start building a new search': 'Comerçar um nova pesquisa',
'starts with': 'começa com',
'state': 'estado',
'Statistics': 'Estatísticas',
'Stylesheet': 'Folha de estilo',
'submit': 'enviar',
'Submit': 'Submit',
'Submit': 'Enviar',
'Support': 'Suporte',
'Sure you want to delete this object?': 'Está certo(a) que deseja apagar este objeto?',
'Table': 'Tabela',
@@ -252,31 +290,33 @@
'Time in Cache (h:m:s)': 'Tempo em Cache (h:m:s)',
'Timestamp': 'Timestamp',
'Traceback': 'Traceback',
'TSV (Spreadsheets)': 'TSV (Planilhas)',
'TSV (Spreadsheets, hidden cols)': 'TSV (Planilhas, col. ocultas)',
'Twitter': 'Twitter',
'Two-step Login Authentication Code': 'Two-step Login Authentication Code',
'Two-step Login Authentication Code': 'Código de Autenticação de Login em Dois Fatores',
'unable to parse csv file': 'não foi possível analisar arquivo csv',
'Unable to send email': 'Unable to send email',
'Unable to send email': 'Não foi possível enviar email',
'Update:': 'Atualizar:',
'Use (...)&(...) for AND, (...)|(...) for OR, and ~(...) for NOT to build more complex queries.': 'Use (...)&(...) para AND, (...)|(...) para OR, e ~(...) para NOT para construir consultas mais complexas.',
'User': 'User',
'User': 'Usuário',
'User %(id)s is impersonating %(other_id)s': 'User %(id)s is impersonating %(other_id)s',
'User %(id)s Logged-in': 'User %(id)s Logged-in',
'User %(id)s Logged-out': 'User %(id)s Logged-out',
'User %(id)s Password changed': 'User %(id)s Password changed',
'User %(id)s Password reset': 'User %(id)s Password reset',
'User %(id)s Password retrieved': 'User %(id)s Password retrieved',
'User %(id)s Profile updated': 'User %(id)s Profile updated',
'User %(id)s Registered': 'User %(id)s Registered',
'User %(id)s Username retrieved': 'User %(id)s Username retrieved',
'User %(id)s Verification email sent': 'User %(id)s Verification email sent',
'User %(id)s verified registration key': 'User %(id)s verified registration key',
'User %(id)s Logged-in': 'Usuário %(id)s entrou',
'User %(id)s Logged-out': 'Usuário %(id)s saiu',
'User %(id)s Password changed': 'Usuário %(id)s trocou a senha',
'User %(id)s Password reset': 'Usuário %(id)s recirar a senha',
'User %(id)s Password retrieved': 'Usuário %(id)s Recuperou a senha',
'User %(id)s Profile updated': 'Usuário %(id)s Atualizou perfil',
'User %(id)s Registered': 'Usuário %(id)s Cadastrou-se',
'User %(id)s Username retrieved': 'Usuário %(id)s Recuperou nome de usuário',
'User %(id)s Verification email sent': 'Usuário %(id)s Email de verificação enviado',
'User %(id)s verified registration key': 'Usuário %(id)s chave de cadastro verificada',
'User ID': 'ID do Usuário',
'User Voice': 'Opinião dos usuários',
'Username': 'Username',
'Username already taken': 'Username already taken',
'Username retrieve': 'Username retrieve',
'Users': 'Users',
'Verify Password': 'Verify Password',
'Username': 'Nome de Usuário',
'Username already taken': 'Nome de usuário já existe',
'Username retrieve': 'Recuperar nome de usuário',
'Users': 'Usuários',
'Verify Password': 'Verificar Senha',
'Videos': 'Vídeos',
'View': 'Visualização',
'Web2py': 'Web2py',
@@ -286,15 +326,17 @@
'Welcome to web2py': 'Bem-vindo ao web2py',
'Welcome to web2py!': 'Bem-vindo ao web2py!',
'Which called the function %s located in the file %s': 'Que chamou a função %s localizada no arquivo %s',
'Wiki Example': 'Wiki Example',
'Wiki Example': 'Exmplo de Wiki',
'Working...': 'Trabalhando...',
'XML': 'XML',
'XML export of columns shown': 'XML exportar colunas visíveis',
'You are successfully running web2py': 'Você está executando o web2py com sucesso',
'You are successfully running web2py.': 'Você está executando o web2py com sucesso.',
'You can modify this application and adapt it to your needs': 'Você pode modificar esta aplicação e adaptá-la às suas necessidades',
'You have been invited to join %(site)s, click %(link)s to complete the process': 'You have been invited to join %(site)s, click %(link)s to complete the process',
'You visited the url %s': 'Você acessou a url %s',
'Your password is: %(password)s': 'Your password is: %(password)s',
'Your temporary login code is {0}': 'Your temporary login code is {0}',
'Your username is: %(username)s': 'Your username is: %(username)s',
'Your username was emailed to you': 'Your username was emailed to you',
'Your password is: %(password)s': 'Sua senha é: %(password)s',
'Your temporary login code is {0}': 'Seu código temporário de login é {0}',
'Your username is: %(username)s': 'Seu nome de usuário é: %(username)s',
'Your username was emailed to you': 'Seu nome de usuário foi enviado por email para você',
}

0
applications/welcome/languages/pt.py Executable file → Normal file
View File

0
applications/welcome/languages/ro.py Executable file → Normal file
View File

0
applications/welcome/languages/ru.py Executable file → Normal file
View File

0
applications/welcome/languages/sk.py Executable file → Normal file
View File

0
applications/welcome/languages/tr.py Executable file → Normal file
View File

0
applications/welcome/languages/uk.py Executable file → Normal file
View File

0
applications/welcome/languages/zh-cn.py Executable file → Normal file
View File

0
applications/welcome/languages/zh-tw.py Executable file → Normal file
View File

0
applications/welcome/languages/zh.py Executable file → Normal file
View File

View File

@@ -283,7 +283,11 @@
doc.ajaxSuccess(function (e, xhr) {
var redirect = xhr.getResponseHeader('web2py-redirect-location');
if (redirect !== null) {
window.location = redirect;
if (!redirect.endsWith('#')) {
window.location.href = redirect;
} else {
window.location.reload();
}
}
/* run this here only if this Ajax request is NOT for a web2py component. */
if (xhr.getResponseHeader('web2py-component-content') === null) {
@@ -335,7 +339,7 @@
} else {
formData = form.serialize(); // Fallback for older browsers.
}
web2py.ajax_page('post', url, formData, target, form);
web2py.ajax_page('post', url, formData, target);
e.preventDefault();
});
@@ -367,6 +371,24 @@
'data': data,
'processData': !isFormData,
'contentType': contentType,
'xhr': function() {
var xhr = new window.XMLHttpRequest();
xhr.upload.addEventListener("progress", function(evt) {
if (evt.lengthComputable) {
var percentComplete = evt.loaded / evt.total;
percentComplete = parseInt(percentComplete * 100);
web2py.fire(element, 'w2p:uploadProgress', [percentComplete], target);
if (percentComplete === 100) {
web2py.fire(element, 'w2p:uploadComplete', [], target);
}
}
}, false);
return xhr;
},
'beforeSend': function (xhr, settings) {
xhr.setRequestHeader('web2py-component-location', document.location);
xhr.setRequestHeader('web2py-component-element', target);

View File

@@ -1,4 +1,8 @@
build: false
before_build:
- choco install redis-64
- redis-server --service-install
- redis-server --service-start
environment:
matrix:
@@ -26,7 +30,7 @@ init:
install:
- python -m ensurepip
- pip install codecov
- pip install codecov redis
- git submodule update --init --recursive
# Check that we have the expected version and architecture for Python
- "python --version"

0
docker/alpine/web2py-gevent/Dockerfile Executable file → Normal file
View File

0
docker/alpine/web2py-gevent/README.md Executable file → Normal file
View File

0
docker/alpine/web2py-gevent/docker-compose.yml Executable file → Normal file
View File

0
docker/alpine/web2py-gunicorn/Dockerfile Executable file → Normal file
View File

0
docker/alpine/web2py-gunicorn/README.md Executable file → Normal file
View File

0
docker/alpine/web2py-gunicorn/docker-compose.yml Executable file → Normal file
View File

0
docker/alpine/web2py-paste/Dockerfile Executable file → Normal file
View File

0
docker/alpine/web2py-paste/README.md Executable file → Normal file
View File

0
docker/alpine/web2py-paste/docker-compose.yml Executable file → Normal file
View File

2
docker/alpine/web2py-rocket-ssl/Dockerfile Executable file → Normal file
View File

@@ -19,4 +19,4 @@ WORKDIR /web2py
EXPOSE 443
CMD python /web2py/web2py.py --nogui --no-banner -a 'a' -c web2py.crt -k web2py.key -i 0.0.0.0 -p 443
CMD python /web2py/web2py.py --no_gui --no_banner -a 'a' -k web2py.key -c web2py.crt -i 0.0.0.0 -p 443

0
docker/alpine/web2py-rocket-ssl/README.md Executable file → Normal file
View File

0
docker/alpine/web2py-rocket-ssl/docker-compose.yml Executable file → Normal file
View File

2
docker/alpine/web2py-rocket/Dockerfile Executable file → Normal file
View File

@@ -24,4 +24,4 @@ WORKDIR /home/web2py/web2py
EXPOSE 8000
CMD . /home/web2py/bin/activate && python /home/web2py/web2py/web2py.py --nogui --no-banner -a 'a' -i 0.0.0.0 -p 8000
CMD . /home/web2py/bin/activate && python /home/web2py/web2py/web2py.py --no_gui --no_banner -a 'a' -i 0.0.0.0 -p 8000

0
docker/alpine/web2py-rocket/README.md Executable file → Normal file
View File

0
docker/alpine/web2py-rocket/docker-compose.yml Executable file → Normal file
View File

0
docker/alpine/web2py-tornado/Dockerfile Executable file → Normal file
View File

Some files were not shown because too many files have changed in this diff Show More