Compare commits
283 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| f463de5a45 | |||
| 8829780def | |||
| a302d52698 | |||
| 00087198e0 | |||
| ea3aa62476 | |||
| 176c9f4ad9 | |||
| 0fdab02d68 | |||
| 0fcb5f2ccd | |||
| 27287d246a | |||
| 2234cd245c | |||
| c5980cd312 | |||
| 4e8dbffd0e | |||
| 50dcd7a572 | |||
| 35f1cca768 | |||
| e5bde6c0b1 | |||
| d31bba2670 | |||
| 4f806a1db9 | |||
| f64232df30 | |||
| ecc2f0004c | |||
| 4f2e327d33 | |||
| 3ce3171dff | |||
| 0850cadfdc | |||
| 53a5a44def | |||
| ad1d414485 | |||
| ba22f9a3a5 | |||
| 51de1740f9 | |||
| 1c012b92d5 | |||
| 7377922211 | |||
| fae120f1ea | |||
| a915054602 | |||
| dd97b9c8dd | |||
| d1e25796e9 | |||
| e38cfc5767 | |||
| 69c888d071 | |||
| 0138b1782d | |||
| 9b1b9e73c5 | |||
| 0fc60eedfb | |||
| 9e19833421 | |||
| 31318340e2 | |||
| 6cef27e69c | |||
| 4f6ab86491 | |||
| 4147867098 | |||
| a0dead1586 | |||
| 0afc18fd24 | |||
| 9f695c783e | |||
| 15263ea1d6 | |||
| 693c5cd5e4 | |||
| cc3f045efa | |||
| 43806a26e7 | |||
| cb4c4b3eb5 | |||
| 39558267b9 | |||
| 59a3c5a6e6 | |||
| 2c9eeccc0e | |||
| 7576d85dba | |||
| 579f0d752f | |||
| 65e9cc2127 | |||
| dc2fd49ecb | |||
| a380ae69d5 | |||
| 0b84911d38 | |||
| e64c556f84 | |||
| 18644e027e | |||
| 65642c029c | |||
| 11540a6132 | |||
| a6e728316b | |||
| 4cb5e3c674 | |||
| d918a6b2e2 | |||
| d721451d15 | |||
| c5aaebd4a8 | |||
| 4c1dbf4e40 | |||
| c20c055788 | |||
| 44c13f9fa3 | |||
| ae44a9e0ac | |||
| 97ba47f339 | |||
| 8671b897d0 | |||
| 1a3361a1bb | |||
| 9ac438d05a | |||
| 18e45ab994 | |||
| f00090846e | |||
| 6590de030c | |||
| 714fcc5202 | |||
| becc947556 | |||
| d547a955ac | |||
| 97e0736d8e | |||
| 20db6daa65 | |||
| 3aefb5f6de | |||
| 30818cdf5e | |||
| 4089cf2145 | |||
| d7893c5292 | |||
| cdd3f6ed00 | |||
| e44254346c | |||
| adf82c1267 | |||
| 4d98b72702 | |||
| f02240acd3 | |||
| cabef57851 | |||
| 98ad12a06c | |||
| d454eb2fe7 | |||
| 0facbe04ef | |||
| 8f9f4aae32 | |||
| d5bfaf83ee | |||
| 9e46c3cbc4 | |||
| d431206e30 | |||
| 6adfb8b944 | |||
| 0c8ccaac9a | |||
| 4f0ee4543b | |||
| 1383d13334 | |||
| 1b260c4b84 | |||
| 0ff586a1ca | |||
| 95adb233f7 | |||
| e7f2e494af | |||
| ded9e5886d | |||
| d2757294af | |||
| 39da6a68fe | |||
| 8e4bc72fca | |||
| bc481e954c | |||
| e4ba924dc1 | |||
| 193510b57d | |||
| 88ad882d83 | |||
| a90c4f7953 | |||
| 0c2d97b9db | |||
| 1c77fdd9e1 | |||
| 681bc9755e | |||
| 31e992696c | |||
| 813411a408 | |||
| 1702d1ac1f | |||
| 022a2af8b1 | |||
| d46d16bc2b | |||
| ae3ff2313d | |||
| 669586f15e | |||
| 46fbcc8d22 | |||
| 178f94af8c | |||
| 2f6b3a0bda | |||
| 97b70eff9f | |||
| 3efa77b57a | |||
| 48977ba04c | |||
| 94e3271481 | |||
| 04f6e7ee38 | |||
| 15c9e685c8 | |||
| b00463bdf4 | |||
| c17e642f1f | |||
| a2e118ec50 | |||
| 45bda63ed3 | |||
| c909af4a86 | |||
| b5a7c7e30f | |||
| 6594e7a607 | |||
| 4d8dedeb27 | |||
| b0e3e386e7 | |||
| ad4870e338 | |||
| c1f0bc3a6d | |||
| 887d4cc136 | |||
| bbe787b7b4 | |||
| 7341988b01 | |||
| 44eb880108 | |||
| c01f860009 | |||
| f9315a8cc7 | |||
| 40918f44fd | |||
| 9fdb586d03 | |||
| 448c398341 | |||
| 618c322603 | |||
| b5c9ed633b | |||
| 80342a22f5 | |||
| c999b16a27 | |||
| 9bda793d46 | |||
| 5e9fbdd24f | |||
| 446e641e64 | |||
| 7d53ec6d71 | |||
| 7b0cf5bc12 | |||
| a82034d516 | |||
| 4973361136 | |||
| 3b69d4bf7b | |||
| fd5e14ea0d | |||
| 9fc3b2bc26 | |||
| 19cc977917 | |||
| ce481d9002 | |||
| 2421a31b25 | |||
| 94c79820b9 | |||
| 80b38a743f | |||
| af01b45852 | |||
| a2de6f12d1 | |||
| 2af81d2e7a | |||
| 0f691f2757 | |||
| be021db3d3 | |||
| acd0ebd09d | |||
| 3d5e594070 | |||
| 58247e3d6b | |||
| 9f35635233 | |||
| 2119bacd22 | |||
| d55fab540c | |||
| 1344c50f85 | |||
| e8d97f5706 | |||
| 35704f3527 | |||
| 96fb5b0755 | |||
| 81f017a7c0 | |||
| aca3d43f0a | |||
| 5a898cc80a | |||
| bfb3a320bd | |||
| c0b1e387b1 | |||
| c175e6340d | |||
| 3a5f7b05df | |||
| 26babd7e96 | |||
| 349088a96e | |||
| a4ff77bdb9 | |||
| 8f70d3a802 | |||
| 89021b6409 | |||
| 4a078705b3 | |||
| 6eea834777 | |||
| b863ff048e | |||
| 79a4693f34 | |||
| 0f0a62ef7f | |||
| cc8a21aedf | |||
| 38fff6fb91 | |||
| e87a2bf0d5 | |||
| 6b3cdb5a99 | |||
| e2191175da | |||
| 4a7f15bb04 | |||
| e6c58c3c6f | |||
| bb2407b468 | |||
| 07e809acb3 | |||
| 7714b5dc7b | |||
| ca85d9adab | |||
| 41a9f12024 | |||
| 669691bbea | |||
| 6ac38e7c56 | |||
| 359758804b | |||
| 9400a0c7a1 | |||
| ea34d1b3a0 | |||
| 72e9921901 | |||
| d6af8279bc | |||
| cd005b01c0 | |||
| fa04c23bbf | |||
| 6ecc09f286 | |||
| 4b0f6aff73 | |||
| c451f57d4e | |||
| 721cb2b90a | |||
| 01d5302a2d | |||
| 706324b9c6 | |||
| 244d3c68eb | |||
| fcfa8aa917 | |||
| 8438a432e9 | |||
| 9d5e0b24f7 | |||
| 4480acd6f7 | |||
| cd1ce28639 | |||
| bf5fbd8b09 | |||
| 515e284c22 | |||
| f98548827a | |||
| b67e57f275 | |||
| 7005fb655c | |||
| b9189771d0 | |||
| b15211064d | |||
| 30ea9ac56b | |||
| dab4950f14 | |||
| 0fce3655d5 | |||
| 91504fbc2c | |||
| 4b17684980 | |||
| 675245eb15 | |||
| 3494fa2d0d | |||
| 87a593845c | |||
| b9d80fcdc7 | |||
| 3f7d085f73 | |||
| d57dd72780 | |||
| a8d1d5cfcf | |||
| 8857e3d521 | |||
| 3b1a5be1be | |||
| c9a63a8524 | |||
| cd967d2551 | |||
| 92b5247f9f | |||
| 45a5b436c8 | |||
| bfd385f969 | |||
| f693fe6b2a | |||
| b040159a9b | |||
| f3af2a1999 | |||
| f613a4cc99 | |||
| e4a96125a6 | |||
| e48074ff54 | |||
| 2ed122a534 | |||
| 65c0d9b18b | |||
| 6702694590 | |||
| 6f0d4d039e | |||
| 1325b0e48f | |||
| 7421eb8068 | |||
| 6c7a9a4030 | |||
| ba0a143717 | |||
| 28bcb5ed6c | |||
| 44fd637a1f |
+38
@@ -0,0 +1,38 @@
|
||||
language: python
|
||||
|
||||
python:
|
||||
- '2.5'
|
||||
- '2.6'
|
||||
- '2.7'
|
||||
- 'pypy'
|
||||
install:
|
||||
- pip install -e . --use-mirrors
|
||||
env:
|
||||
- DB=sqlite:memory
|
||||
- DB=mysql://root:@localhost/test_w2p
|
||||
- DB=postgres://postgres:@localhost/test_w2p
|
||||
before_script:
|
||||
- if [[ $TRAVIS_PYTHON_VERSION != '2.7' ]]; then pip install --use-mirrors unittest2; fi
|
||||
- if [[ $TRAVIS_PYTHON_VERSION == '2.7' ]]; then pip install --use-mirrors coverage; fi;
|
||||
- if [[ $TRAVIS_PYTHON_VERSION == '2.7' ]]; then pip install --use-mirrors python-coveralls; fi
|
||||
- if [[ $DB == postgres* ]]; then pip install --use-mirrors psycopg2; fi;
|
||||
- if [[ $TRAVIS_PYTHON_VERSION == '2.5' ]]; then pip install --use-mirrors pysqlite; fi
|
||||
- if [[ $DB == mysql* ]]; then mysql -e 'create database test_w2p;'; fi
|
||||
- if [[ $DB == postgres* ]]; then psql -c 'create database test_w2p;' -U postgres; fi
|
||||
#Temporal solution to travis issue #155
|
||||
- sudo chmod 777 /dev/shm
|
||||
- sudo rm -rf /dev/shm && sudo ln -s /run/shm /dev/shm
|
||||
matrix:
|
||||
exclude:
|
||||
- python: 'pypy'
|
||||
env: DB=postgres://postgres:@localhost/test_w2p
|
||||
- python: 'pypy'
|
||||
env: DB=mysql://root:@localhost/test_w2p
|
||||
|
||||
script: export COVERAGE_PROCESS_START=gluon/tests/coverage.ini; ./web2py.py --run_system_tests --with_coverage
|
||||
after_success:
|
||||
- if [[ $TRAVIS_PYTHON_VERSION == '2.7' ]]; then coverage combine; fi
|
||||
- if [[ $TRAVIS_PYTHON_VERSION == '2.7' ]]; then coveralls --config_file=gluon/tests/coverage.ini; fi
|
||||
|
||||
notifications:
|
||||
email: true
|
||||
@@ -1,3 +1,30 @@
|
||||
## 2.5.1
|
||||
|
||||
- New style virtual fields in grid
|
||||
- Conditional fields (experimental) ``db.table.field.show_id = db.table.otherfield==True`` or ``db.table.field.show_id = db.table.otherfiel.contains(values)``
|
||||
- auth.settings.manager_group_role="manager" enables http://.../app/appadmin/auth_manage and http://.../app/appadmin/manage for members of the "manager" group. (also experimental)
|
||||
- support for POST variables in DELETE
|
||||
- Fixed memory leak when using the TAG helper
|
||||
|
||||
|
||||
## 2.4.7
|
||||
|
||||
- pypy support, thanks Niphlod
|
||||
- more bug fixes
|
||||
- ...
|
||||
|
||||
## 2.4.6
|
||||
|
||||
- better tests
|
||||
- new ANY_OF and IS_IPV6 validators
|
||||
- new custom save option
|
||||
- many small bug fixes
|
||||
|
||||
## 2.4.5
|
||||
|
||||
- travis.ci integration (thanks Marc Abramowitz and Niphlod). Passes all tests (thanks Niplod).
|
||||
- IS_DATE and IS_DATETIME can specify timezone
|
||||
|
||||
## 2.4.1- 2.4.3
|
||||
|
||||
- 2D GEO API: geoPoint, getLine, geoPolygon
|
||||
|
||||
@@ -5,7 +5,7 @@ all:
|
||||
clean:
|
||||
rm -f httpserver.log
|
||||
rm -f parameters*.py
|
||||
rm -f -r applications/*/compiled
|
||||
rm -f -r applications/*/compiled
|
||||
find ./ -name '*~' -exec rm -f {} \;
|
||||
find ./ -name '*.orig' -exec rm -f {} \;
|
||||
find ./ -name '*.rej' -exec rm -f {} \;
|
||||
@@ -30,7 +30,7 @@ update:
|
||||
echo "remember that pymysql was tweaked"
|
||||
src:
|
||||
### Use semantic versioning
|
||||
echo 'Version 2.4.3-stable+timestamp.'`date +%Y.%m.%d.%H.%M.%S` > VERSION
|
||||
echo 'Version 2.5.1-stable+timestamp.'`date +%Y.%m.%d.%H.%M.%S` > VERSION
|
||||
### rm -f all junk files
|
||||
make clean
|
||||
### clean up baisc apps
|
||||
@@ -64,9 +64,10 @@ app:
|
||||
python2.7 -c 'import compileall; compileall.compile_dir("gluon/")'
|
||||
#python web2py.py -S welcome -R __exit__.py
|
||||
#cd ../web2py_osx/site-packages/; unzip ../site-packages.zip
|
||||
find gluon -path '*.pyc' -exec cp {} ../web2py_osx/site-packages/{} \;
|
||||
cd ../web2py_osx/site-packages/; zip -r ../site-packages.zip *
|
||||
mv ../web2py_osx/site-packages.zip ../web2py_osx/web2py/web2py.app/Contents/Resources/lib/python2.7
|
||||
#find gluon -path '*.pyc' -exec cp {} ../web2py_osx/site-packages/{} \;
|
||||
#cd ../web2py_osx/site-packages/; zip -r ../site-packages.zip *
|
||||
#mv ../web2py_osx/site-packages.zip ../web2py_osx/web2py/web2py.app/Contents/Resources/lib/python2.7
|
||||
find gluon -path '*.py' -exec cp {} ../web2py_osx/web2py/web2py.app/Contents/Resources/{} \;
|
||||
cp README.markdown ../web2py_osx/web2py/web2py.app/Contents/Resources
|
||||
cp NEWINSTALL ../web2py_osx/web2py/web2py.app/Contents/Resources
|
||||
cp LICENSE ../web2py_osx/web2py/web2py.app/Contents/Resources
|
||||
@@ -114,11 +115,11 @@ commit:
|
||||
make src
|
||||
echo '' > NEWINSTALL
|
||||
hg commit -m "$(S)"
|
||||
#bzr commit -m "$(S)"
|
||||
git commit -a -m "$(S)"
|
||||
push:
|
||||
hg push
|
||||
git push
|
||||
git push --tags
|
||||
tag:
|
||||
git tag -l '$(S)'
|
||||
hg tag -l '$(S)'
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
|
||||
@@ -6,6 +6,13 @@ It is written and programmable in Python. LGPLv3 License
|
||||
|
||||
Learn more at http://web2py.com
|
||||
|
||||
|
||||
## Tests
|
||||
|
||||
[](https://travis-ci.org/web2py/web2py)
|
||||
|
||||
[](https://coveralls.io/r/web2py/web2py)
|
||||
|
||||
## Installation Instructions
|
||||
|
||||
To start web2py there is NO NEED to install it. Just unzip and do:
|
||||
|
||||
@@ -1 +1 @@
|
||||
Version 2.4.3-stable+timestamp.2013.03.11.14.40.17
|
||||
Version 2.5.1-stable+timestamp.2013.06.06.10.35.58
|
||||
|
||||
@@ -180,6 +180,9 @@ def run(servername, ip, port, softcron=True, logging=False, profiler=None):
|
||||
if servername == 'gevent':
|
||||
from gevent import monkey
|
||||
monkey.patch_all()
|
||||
elif servername == 'eventlet':
|
||||
import eventlet
|
||||
eventlet.monkey_patch()
|
||||
|
||||
import gluon.main
|
||||
|
||||
|
||||
+11
-1
@@ -21,7 +21,17 @@ default_expiration: "24h" # for static files
|
||||
|
||||
handlers:
|
||||
|
||||
- url: /(?P<a>.+?)/static/(?P<b>.+)
|
||||
# Warning! Static mapping - below - isn't compatible with
|
||||
# the parametric router's language logic.
|
||||
# You cannot use them together.
|
||||
|
||||
- url: /(.+?)/[^_]*\/?static/_\d.\d.\d\/?(.+)
|
||||
static_files: applications/\1/static/\2
|
||||
upload: applications/(.+?)/static/(.+)
|
||||
secure: optional
|
||||
expiration: "365d"
|
||||
|
||||
- url: /(.+?)/[^_]*\/?static/?(.+)
|
||||
static_files: applications/\1/static/\2
|
||||
upload: applications/(.+?)/static/(.+)
|
||||
secure: optional
|
||||
|
||||
@@ -37,14 +37,20 @@ if request.env.http_x_forwarded_for or request.is_https:
|
||||
elif (remote_addr not in hosts) and (remote_addr != "127.0.0.1"):
|
||||
raise HTTP(200, T('appadmin is disabled because insecure channel'))
|
||||
|
||||
if (request.application == 'admin' and not session.authorized) or \
|
||||
(request.application != 'admin' and not gluon.fileutils.check_credentials(request)):
|
||||
if request.function in ('auth_manage','manage') and 'auth' in globals():
|
||||
auth.requires_membership(auth.settings.manager_group_role)(lambda: None)()
|
||||
menu = False
|
||||
elif (request.application == 'admin' and not session.authorized) or \
|
||||
(request.application != 'admin' and not gluon.fileutils.check_credentials(request)):
|
||||
redirect(URL('admin', 'default', 'index',
|
||||
vars=dict(send=URL(args=request.args, vars=request.vars))))
|
||||
else:
|
||||
menu = True
|
||||
|
||||
ignore_rw = True
|
||||
response.view = 'appadmin.html'
|
||||
response.menu = [[T('design'), False, URL('admin', 'default', 'design',
|
||||
if menu:
|
||||
response.menu = [[T('design'), False, URL('admin', 'default', 'design',
|
||||
args=[request.application])], [T('db'), False,
|
||||
URL('index')], [T('state'), False,
|
||||
URL('state')], [T('cache'), False,
|
||||
@@ -54,6 +60,10 @@ response.menu = [[T('design'), False, URL('admin', 'default', 'design',
|
||||
# ## auxiliary functions
|
||||
# ###########################################################
|
||||
|
||||
if False and request.tickets_db:
|
||||
from gluon.restricted import TicketStorage
|
||||
ts = TicketStorage()
|
||||
ts._get_table(request.tickets_db, ts.tablename, request.application)
|
||||
|
||||
def get_databases(request):
|
||||
dbs = {}
|
||||
@@ -275,14 +285,15 @@ def update():
|
||||
(db, table) = get_table(request)
|
||||
keyed = hasattr(db[table], '_primarykey')
|
||||
record = None
|
||||
db[table]._common_filter = None
|
||||
if keyed:
|
||||
key = [f for f in request.vars if f in db[table]._primarykey]
|
||||
if key:
|
||||
record = db(db[table][key[0]] == request.vars[key[
|
||||
0]], ignore_common_filters=True).select().first()
|
||||
0]]).select().first()
|
||||
else:
|
||||
record = db(db[table].id == request.args(
|
||||
2), ignore_common_filters=True).select().first()
|
||||
2)).select().first()
|
||||
|
||||
if not record:
|
||||
qry = query_by_table_type(table, db)
|
||||
@@ -568,3 +579,35 @@ def bg_graph_model():
|
||||
|
||||
def graph_model():
|
||||
return dict(databases=databases, pgv=pgv)
|
||||
|
||||
def auth_manage():
|
||||
tablename = request.args(0)
|
||||
if not tablename or not tablename in auth.db.tables:
|
||||
return dict()
|
||||
table = auth.db[tablename]
|
||||
formname = '%s_grid' % tablename
|
||||
if tablename == auth.settings.table_user_name:
|
||||
auth.settings.table_user._plural = T('Users')
|
||||
auth.settings.table_membership._plural = T('Roles')
|
||||
auth.settings.table_membership._id.readable = False
|
||||
auth.settings.table_membership.user_id.label = T('User')
|
||||
auth.settings.table_membership.group_id.label = T('Role')
|
||||
grid = SQLFORM.smartgrid(table, args=request.args[:1], user_signature=True,
|
||||
linked_tables=[auth.settings.table_membership_name],
|
||||
maxtextlength=1000, formname=formname)
|
||||
else:
|
||||
table._id.readable = False
|
||||
auth.settings.table_permission.group_id.label = T('Role')
|
||||
auth.settings.table_permission.name.label = T('Permission')
|
||||
orderby = 'role' if table == auth.settings.table_group_name else 'group_id'
|
||||
grid = SQLFORM.grid(table, args=request.args[:1], orderby=table[orderby],
|
||||
user_signature=True, maxtextlength=1000, formname=formname)
|
||||
return grid if request.extension=='load' else dict(grid=grid)
|
||||
|
||||
def manage():
|
||||
tablename = request.args(0)
|
||||
if tablename in auth.db.tables:
|
||||
grid = SQLFORM.smartgrid(auth.db[tablename], args=request.args[:1])
|
||||
else:
|
||||
return dict()
|
||||
return grid if request.extension=='load' else dict(grid=grid)
|
||||
|
||||
@@ -27,7 +27,7 @@ from gluon.languages import (read_possible_languages, read_dict, write_dict,
|
||||
read_plural_dict, write_plural_dict)
|
||||
|
||||
|
||||
if DEMO_MODE and request.function in ['change_password', 'pack', 'pack_plugin', 'upgrade_web2py', 'uninstall', 'cleanup', 'compile_app', 'remove_compiled_app', 'delete', 'delete_plugin', 'create_file', 'upload_file', 'update_languages', 'reload_routes', 'git_push', 'git_pull']:
|
||||
if DEMO_MODE and request.function in ['change_password', 'pack', 'pack_custom','pack_plugin', 'upgrade_web2py', 'uninstall', 'cleanup', 'compile_app', 'remove_compiled_app', 'delete', 'delete_plugin', 'create_file', 'upload_file', 'update_languages', 'reload_routes', 'git_push', 'git_pull']:
|
||||
session.flash = T('disabled in demo mode')
|
||||
redirect(URL('site'))
|
||||
|
||||
@@ -138,17 +138,17 @@ def check_version():
|
||||
session.forget()
|
||||
session._unlock(response)
|
||||
|
||||
new_version, version_number = check_new_version(request.env.web2py_version,
|
||||
WEB2PY_VERSION_URL)
|
||||
new_version, version = check_new_version(request.env.web2py_version,
|
||||
WEB2PY_VERSION_URL)
|
||||
|
||||
if new_version == -1:
|
||||
return A(T('Unable to check for upgrades'), _href=WEB2PY_URL)
|
||||
elif new_version != True:
|
||||
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 version %s.%s.%s' % version_number[:3])
|
||||
return SPAN('You should upgrade to %s' % version.split('(')[0])
|
||||
else:
|
||||
return sp_button(URL('upgrade_web2py'), T('upgrade now to %s') % version_number.split('-')[0])
|
||||
return sp_button(URL('upgrade_web2py'), T('upgrade now to %s') % version.split('(')[0])
|
||||
|
||||
|
||||
def logout():
|
||||
@@ -341,7 +341,6 @@ def pack():
|
||||
session.flash = T('internal error: %s' % e)
|
||||
redirect(URL('site'))
|
||||
|
||||
|
||||
def pack_plugin():
|
||||
app = get_app()
|
||||
if len(request.args) == 2:
|
||||
@@ -356,6 +355,33 @@ def pack_plugin():
|
||||
session.flash = T('internal error')
|
||||
redirect(URL('plugin', args=request.args))
|
||||
|
||||
def pack_custom():
|
||||
app = get_app()
|
||||
base = apath(app, r=request)
|
||||
if request.post_vars.file:
|
||||
files = request.post_vars.file
|
||||
files = [files] if not isinstance(files,list) else files
|
||||
fname = 'web2py.app.%s.w2p' % app
|
||||
try:
|
||||
filename = app_pack(app, request, raise_ex=True, filenames=files)
|
||||
except Exception, e:
|
||||
filename = None
|
||||
if filename:
|
||||
response.headers['Content-Type'] = 'application/w2p'
|
||||
disposition = 'attachment; filename=%s' % fname
|
||||
response.headers['Content-Disposition'] = disposition
|
||||
return safe_read(filename, 'rb')
|
||||
else:
|
||||
session.flash = T('internal error: %s' % e)
|
||||
redirect(URL(args=request.args))
|
||||
def ignore(fs):
|
||||
return [f for f in fs if not (
|
||||
f[:1] in '#' or f.endswith('~') or f.endswith('.bak'))]
|
||||
files = {}
|
||||
for (r,d,f) in os.walk(base):
|
||||
files[r] = {'folders':ignore(d),'files':ignore(f)}
|
||||
return locals()
|
||||
|
||||
|
||||
def upgrade_web2py():
|
||||
dialog = FORM.confirm(T('Upgrade'),
|
||||
@@ -682,7 +708,7 @@ def edit():
|
||||
cfilename = os.path.join(request.args[0], 'controllers',
|
||||
request.args[2] + '.py')
|
||||
if os.path.exists(apath(cfilename, r=request)):
|
||||
edit_controller = URL('edit', args=[cfilename])
|
||||
edit_controller = URL('edit',args=[cfilename.replace(os.sep, "/")])
|
||||
view = request.args[3].replace('.html', '')
|
||||
view_link = URL(request.args[0], request.args[2], view)
|
||||
elif filetype == 'python' and request.args[1] == 'controllers':
|
||||
@@ -1651,26 +1677,6 @@ def update_languages():
|
||||
redirect(URL('design', args=app, anchor='languages'))
|
||||
|
||||
|
||||
def twitter():
|
||||
session.forget()
|
||||
session._unlock(response)
|
||||
import gluon.tools
|
||||
import gluon.contrib.simplejson as sj
|
||||
try:
|
||||
if TWITTER_HASH:
|
||||
page = urllib.urlopen("http://search.twitter.com/search.json?q=%%40%s" % TWITTER_HASH).read()
|
||||
data = sj.loads(page, encoding="utf-8")['results']
|
||||
d = dict()
|
||||
for e in data:
|
||||
d[e["id"]] = e
|
||||
r = reversed(sorted(d))
|
||||
return dict(tweets=[d[k] for k in r])
|
||||
else:
|
||||
return 'disabled'
|
||||
except Exception, e:
|
||||
return DIV(T('Unable to download because:'), BR(), str(e))
|
||||
|
||||
|
||||
def user():
|
||||
if MULTI_USER_MODE:
|
||||
if not db(db.auth_user).count():
|
||||
|
||||
+480
-390
@@ -1,390 +1,480 @@
|
||||
# coding: utf8
|
||||
{
|
||||
'!langcode!': 'cs-cz',
|
||||
'!langname!': '?e?tina',
|
||||
'"update" is an optional expression like "field1=\'newvalue\'". You cannot update or delete the results of a JOIN': 'Kolonka "Upravit" je nepovinn? v?raz, nap??klad "pole1=\'nov?hodnota\'". V?sledky datab?zov?ho JOINu nem??ete mazat ani upravovat.',
|
||||
'%%{Row} in Table': '%%{??dek} v tabulce',
|
||||
'%%{Row} selected': 'ozna?en?ch %%{??dek}',
|
||||
'%s %%{row} deleted': '%s smazan?ch %%{z?znam}',
|
||||
'%s %%{row} updated': '%s upraven?ch %%{z?znam}',
|
||||
'%s selected': '%s ozna?en?ch',
|
||||
'%Y-%m-%d': '%d.%m.%Y',
|
||||
'%Y-%m-%d %H:%M:%S': '%d.%m.%Y %H:%M:%S',
|
||||
'(requires internet access)': '(vy?aduje p?ipojen? k internetu)',
|
||||
'(something like "it-it")': '(nap??klad "cs-cs")',
|
||||
'@markmin\x01(file **gluon/contrib/plural_rules/%s.py** is not found)': '(soubor **gluon/contrib/plural_rules/%s.py** nenalezen)',
|
||||
'@markmin\x01Searching: **%s** %%{file}': 'Hled?n?: **%s** %%{soubor}',
|
||||
'About': 'O programu',
|
||||
'About application': 'O aplikaci',
|
||||
'Access Control': '??zen? p??stupu',
|
||||
'Add breakpoint': 'P?idat bod p?eru?en?',
|
||||
'Additional code for your application': 'Dal?? k?d pro Va?i aplikaci',
|
||||
'Admin language': 'jazyk rozhran?',
|
||||
'Administrative interface': 'pro administr?torsk? rozhran? klikn?te sem',
|
||||
'Administrative Interface': 'Administr?torsk? rozhran?',
|
||||
'administrative interface': 'rozhran? pro spr?vu',
|
||||
'Administrator Password:': 'Administr?torsk? heslo:',
|
||||
'Ajax Recipes': 'Recepty s ajaxem',
|
||||
'and rename it:': 'a p?ejmenovat na:',
|
||||
'appadmin': 'appadmin',
|
||||
'appadmin is disabled because insecure channel': 'appadmin je zak?zan? bez zabezpe?en?ho spojen?',
|
||||
'application "%s" uninstalled': 'application "%s" odinstalov?na',
|
||||
'application compiled': 'aplikace zkompilov?na',
|
||||
'Application name:': 'N?zev aplikace:',
|
||||
'are not used': 'nepou?ita',
|
||||
'are not used yet': 'je?t? nepou?ita',
|
||||
'Are you sure you want to delete this object?': 'Opravdu chcete odstranit tento objekt?',
|
||||
'Are you sure you want to uninstall application "%s"?': 'Opravdu chcete odinstalovat aplikaci "%s"?',
|
||||
'Available Databases and Tables': 'Dostupn? datab?ze a tabulky',
|
||||
'back': 'zp?t',
|
||||
'Basics': 'Basics',
|
||||
'Begin': 'Za??t',
|
||||
'breakpoint': 'bod p?eru?en?',
|
||||
'Breakpoints': 'Body p?eru?en?',
|
||||
'breakpoints': 'body p?eru?en?',
|
||||
'Buy this book': 'Koupit web2py knihu',
|
||||
'Cache': 'Cache',
|
||||
'cache': 'cache',
|
||||
'Cache Keys': 'Kl??e cache',
|
||||
'cache, errors and sessions cleaned': 'cache, chyby a relace byly pro?i?t?ny',
|
||||
'can be a git repo': 'm??e to b?t git repo',
|
||||
'Cancel': 'Storno',
|
||||
'Cannot be empty': 'Nem??e b?t pr?zdn?',
|
||||
'Change admin password': 'Zm?nit heslo pro str?vu aplikac?',
|
||||
'Change password': 'Zm?na hesla',
|
||||
'check all': 'v?e ozna?it',
|
||||
'Check for upgrades': 'Zkusit aktualizovat',
|
||||
'Check to delete': 'Ozna?it ke smaz?n?',
|
||||
'Check to delete:': 'Ozna?it ke smaz?n?:',
|
||||
'Checking for upgrades...': 'Zji??uji, zda jsou k dispozici aktualizace...',
|
||||
'Clean': 'Pro?istit',
|
||||
'Clear CACHE?': 'Vymazat CACHE?',
|
||||
'Clear DISK': 'Vymazat DISK',
|
||||
'Clear RAM': 'Vymazat RAM',
|
||||
'Click row to expand traceback': 'Pro rozbalen? stopy, klikn?te na ??dek',
|
||||
'Click row to view a ticket': 'Pro zobrazen? chyby (ticketu), klikn?te na ??dku...',
|
||||
'Client IP': 'IP adresa klienta',
|
||||
'collapse/expand all': 'v?e sbalit/rozbalit',
|
||||
'Community': 'Komunita',
|
||||
'Compile': 'Zkompilovat',
|
||||
'compiled application removed': 'zkompilovan? aplikace smaz?na',
|
||||
'Components and Plugins': 'Komponenty a z?suvn? moduly',
|
||||
'Condition': 'Podm?nka',
|
||||
'Controller': 'Kontrol?r (Controller)',
|
||||
'Controllers': 'Kontrol?ry',
|
||||
'controllers': 'kontrol?ry',
|
||||
'Copyright': 'Copyright',
|
||||
'Count': 'Po?et',
|
||||
'Create': 'Vytvo?it',
|
||||
'create file with filename:': 'vytvo?it soubor s n?zvem:',
|
||||
'created by': 'vytvo?il',
|
||||
'Created By': 'Vytvo?eno - k?m',
|
||||
'Created On': 'Vytvo?eno - kdy',
|
||||
'crontab': 'crontab',
|
||||
'Current request': 'Aktu?ln? po?adavek',
|
||||
'Current response': 'Aktu?ln? odpov??',
|
||||
'Current session': 'Aktu?ln? relace',
|
||||
'currently running': 'pr?v? b???',
|
||||
'currently saved or': 'ulo?eno nebo',
|
||||
'customize me!': 'upravte m?!',
|
||||
'data uploaded': 'data nahr?na',
|
||||
'Database': 'Rozhran? datab?ze',
|
||||
'Database %s select': 'datab?ze %s v?b?r',
|
||||
'database administration': 'spr?va datab?ze',
|
||||
'Date and Time': 'Datum a ?as',
|
||||
'day': 'den',
|
||||
'db': 'db',
|
||||
'DB Model': 'Datab?zov? model',
|
||||
'Debug': 'Lad?n?',
|
||||
'Delete': 'Smazat',
|
||||
'delete': 'smazat',
|
||||
'delete all checked': 'smazat v?e ozna?en?',
|
||||
'Delete this file (you will be asked to confirm deletion)': 'Smazat tento soubor (budete po??d?n o potvrzen? maz?n?)',
|
||||
'Delete:': 'Smazat:',
|
||||
'deleted after first hit': 'smazat po prvn?m dosa?en?',
|
||||
'Demo': 'Demo',
|
||||
'Deploy': 'Nahr?t',
|
||||
'Deploy on Google App Engine': 'Nahr?t na Google App Engine',
|
||||
'Deploy to OpenShift': 'Nahr?t na OpenShift',
|
||||
'Deployment Recipes': 'Postupy pro deployment',
|
||||
'Description': 'Popis',
|
||||
'design': 'n?vrh',
|
||||
'direction: ltr': 'direction: ltr',
|
||||
'Disable': 'Zablokovat',
|
||||
'DISK': 'DISK',
|
||||
'Disk Cache Keys': 'Kl??e diskov? cache',
|
||||
'Disk Cleared': 'Disk smaz?n',
|
||||
'docs': 'dokumentace',
|
||||
'Documentation': 'Dokumentace',
|
||||
"Don't know what to do?": 'Nev?te kudy kam?',
|
||||
'done!': 'hotovo!',
|
||||
'Download': 'St?hnout',
|
||||
'download layouts': 'st?hnout moduly rozvr?en? str?nky',
|
||||
'download plugins': 'st?hnout z?suvn? moduly',
|
||||
'E-mail': 'E-mail',
|
||||
'Edit': 'Upravit',
|
||||
'edit all': 'edit all',
|
||||
'Edit application': 'Spr?va aplikace',
|
||||
'Edit current record': 'Upravit aktu?ln? z?znam',
|
||||
'Edit Profile': 'Upravit profil',
|
||||
'Editing file "%s"': '?prava souboru "%s"',
|
||||
'Editing Language file': '?prava jazykov?ho souboru',
|
||||
'Email and SMS': 'Email a SMS',
|
||||
'Enable': 'Odblokovat',
|
||||
'enter a number between %(min)g and %(max)g': 'zadejte ??slo mezi %(min)g a %(max)g',
|
||||
'enter an integer between %(min)g and %(max)g': 'zadejte cel? ??slo mezi %(min)g a %(max)g',
|
||||
'Error': 'Chyba',
|
||||
'Error logs for "%(app)s"': 'Seznam v?skytu chyb pro aplikaci "%(app)s"',
|
||||
'Errors': 'Chyby',
|
||||
'export as csv file': 'exportovat do .csv souboru',
|
||||
'exposes': 'vystavuje',
|
||||
'extends': 'roz?i?uje',
|
||||
'FAQ': '?asto kladen? dotazy',
|
||||
'File': 'Soubor',
|
||||
'file': 'soubor',
|
||||
'file saved on %(time)s': 'soubor ulo?en %(time)s',
|
||||
'Filename': 'N?zev souboru',
|
||||
'filter': 'filtr',
|
||||
'Find Next': 'Naj?t dal??',
|
||||
'Find Previous': 'Naj?t p?edchoz?',
|
||||
'First name': 'K?estn? jm?no',
|
||||
'Forgot username?': 'Zapomn?l jste svoje p?ihla?ovac? jm?no?',
|
||||
'forgot username?': 'zapomn?l jste svoje p?ihla?ovac? jm?no?',
|
||||
'Forms and Validators': 'Formul??e a valid?tory',
|
||||
'Free Applications': 'Aplikace zdarma',
|
||||
'Generate': 'Vytvo?it',
|
||||
'Get from URL:': 'St?hnout z internetu:',
|
||||
'Git Pull': 'Git Pull',
|
||||
'Git Push': 'Git Push',
|
||||
'Globals##debug': 'Glob?ln? prom?nn?',
|
||||
'go!': 'OK!',
|
||||
'Group %(group_id)s created': 'Skupina %(group_id)s vytvo?ena',
|
||||
'Group ID': 'ID skupiny',
|
||||
'Groups': 'Skupiny',
|
||||
'Hello World': 'Ahoj sv?te',
|
||||
'Help': 'N?pov?da',
|
||||
'Hide/Show Translated strings': 'Skr?t/Zobrazit p?elo?en? texty',
|
||||
'Hits': 'Kolikr?t dosa?eno',
|
||||
'Home': 'Domovsk? str?nka',
|
||||
'honored only if the expression evaluates to true': 'br?t v potaz jen kdy? se tato podm?nka vyhodnot? kladn?',
|
||||
'How did you get here?': 'Jak jste se sem vlastn? dostal?',
|
||||
'import': 'import',
|
||||
'Import/Export': 'Import/Export',
|
||||
'includes': 'zahrnuje',
|
||||
'Index': 'Index',
|
||||
'insert new': 'vlo?it nov? z?znam ',
|
||||
'insert new %s': 'vlo?it nov? z?znam %s',
|
||||
'Install': 'Instalovat',
|
||||
'Installed applications': 'Nainstalovan? aplikace',
|
||||
'Internal State': 'Vnit?n? stav',
|
||||
'Introduction': '?vod',
|
||||
'Invalid email': 'Neplatn? email',
|
||||
'Invalid password': 'Nespr?vn? heslo',
|
||||
'invalid password.': 'neplatn? heslo',
|
||||
'Invalid Query': 'Neplatn? dotaz',
|
||||
'invalid request': 'Neplatn? po?adavek',
|
||||
'Is Active': 'Je aktivn?',
|
||||
'It is %s %%{day} today.': 'Dnes je to %s %%{den}.',
|
||||
'Key': 'Kl??',
|
||||
'Key bindings': 'Vazby kl???',
|
||||
'languages': 'jazyky',
|
||||
'Languages': 'Jazyky',
|
||||
'Last name': 'P??jmen?',
|
||||
'Last saved on:': 'Naposledy ulo?eno:',
|
||||
'Layout': 'Rozvr?en? str?nky (layout)',
|
||||
'Layout Plugins': 'Moduly rozvr?en? str?nky (Layout Plugins)',
|
||||
'Layouts': 'Rozvr?en? str?nek',
|
||||
'License for': 'Licence pro',
|
||||
'Line number': '??slo ??dku',
|
||||
'LineNo': '?.??dku',
|
||||
'Live Chat': 'Online pokec',
|
||||
'loading...': 'nahr?v?m...',
|
||||
'Locals##debug': 'Lok?ln? prom?nn?',
|
||||
'Logged in': 'P?ihl??en? prob?hlo ?sp??n?',
|
||||
'Logged out': 'Odhl??en? prob?hlo ?sp??n?',
|
||||
'Login': 'P?ihl?sit se',
|
||||
'login': 'p?ihl?sit se',
|
||||
'Login to the Administrative Interface': 'P?ihl?sit se do Spr?vce aplikac?',
|
||||
'logout': 'odhl?sit se',
|
||||
'Logout': 'Odhl?sit se',
|
||||
'Lost Password': 'Zapomn?l jste heslo',
|
||||
'Lost password?': 'Zapomn?l jste heslo?',
|
||||
'lost password?': 'zapomn?l jste heslo?',
|
||||
'Manage Cache': 'Manage Cache',
|
||||
'Menu Model': 'Model rozbalovac? nab?dky',
|
||||
'Models': 'Modely',
|
||||
'models': 'modely',
|
||||
'Modified By': 'Zm?n?no - k?m',
|
||||
'Modified On': 'Zm?n?no - kdy',
|
||||
'Modules': 'Moduly',
|
||||
'modules': 'moduly',
|
||||
'My Sites': 'Spr?va aplikac?',
|
||||
'Name': 'Jm?no',
|
||||
'New Application Wizard': 'Nov? pr?vodce aplikac?',
|
||||
'New application wizard': 'Nov? pr?vodce aplikac?',
|
||||
'New password': 'Nov? heslo',
|
||||
'New Record': 'Nov? z?znam',
|
||||
'new record inserted': 'nov? z?znam byl zalo?en',
|
||||
'New simple application': 'Vytvo?it primitivn? aplikaci',
|
||||
'next 100 rows': 'dal??ch 100 ??dk?',
|
||||
'No databases in this application': 'V t?to aplik?ci nejsou ??dn? datab?ze',
|
||||
'No Interaction yet': 'Je?t? ??dn? interakce nenastala',
|
||||
'No ticket_storage.txt found under /private folder': 'Soubor ticket_storage.txt v adres??i /private nenalezen',
|
||||
'Object or table name': 'Objekt ?i tabulka',
|
||||
'Old password': 'P?vodn? heslo',
|
||||
'online designer': 'online n?vrh??',
|
||||
'Online examples': 'P??klady online',
|
||||
'or import from csv file': 'nebo importovat z .csv souboru',
|
||||
'Origin': 'P?vod',
|
||||
'Original/Translation': 'Origin?l/P?eklad',
|
||||
'Other Plugins': 'Ostatn? moduly',
|
||||
'Other Recipes': 'Ostatn? z?suvn? moduly',
|
||||
'Overview': 'P?ehled',
|
||||
'Overwrite installed app': 'P?epsat instalovanou aplikaci',
|
||||
'Pack all': 'Zabalit',
|
||||
'Pack compiled': 'Zabalit zkompilovan?',
|
||||
'password': 'heslo',
|
||||
'Password': 'Heslo',
|
||||
"Password fields don't match": 'Hesla se neshoduj?',
|
||||
'Please': 'Pros?m',
|
||||
'plugins': 'z?suvn? moduly',
|
||||
'Plugins': 'Z?suvn? moduly',
|
||||
'Plural-Forms:': 'Mno?n? ??sla:',
|
||||
'Powered by': 'Poh?n?no',
|
||||
'Preface': 'P?edmluva',
|
||||
'previous 100 rows': 'p?edchoz?ch 100 ??dk?',
|
||||
'Private files': 'Soukrom? soubory',
|
||||
'private files': 'soukrom? soubory',
|
||||
'profile': 'profil',
|
||||
'Project Progress': 'V?voj projektu',
|
||||
'Python': 'Python',
|
||||
'Query:': 'Dotaz:',
|
||||
'Quick Examples': 'Kr?tk? p??klady',
|
||||
'RAM': 'RAM',
|
||||
'RAM Cache Keys': 'Kl??e RAM Cache',
|
||||
'Ram Cleared': 'RAM smaz?na',
|
||||
'Readme': 'N?pov?da',
|
||||
'Recipes': 'Postupy jak na to',
|
||||
'Record': 'Z?znam',
|
||||
'record does not exist': 'z?znam neexistuje',
|
||||
'Record ID': 'ID z?znamu',
|
||||
'Record id': 'id z?znamu',
|
||||
'refresh': 'obnovte',
|
||||
'register': 'registrovat',
|
||||
'Register': 'Zaregistrovat se',
|
||||
'Registration identifier': 'Registra?n? identifik?tor',
|
||||
'Registration key': 'Registra?n? kl??',
|
||||
'Reload routes': 'Znovu nahr?t cesty',
|
||||
'Remember me (for 30 days)': 'Zapamatovat na 30 dn?',
|
||||
'Remove compiled': 'Odstranit zkompilovan?',
|
||||
'Removed Breakpoint on %s at line %s': 'Bod p?eru?en? smaz?n - soubor %s na ??dce %s',
|
||||
'Replace': 'Zam?nit',
|
||||
'Replace All': 'Zam?nit v?e',
|
||||
'Reset Password key': 'Reset registra?n?ho kl??e',
|
||||
'restart': 'restart',
|
||||
'restore': 'obnovit',
|
||||
'Retrieve username': 'Z?skat p?ihla?ovac? jm?no',
|
||||
'revert': 'vr?tit se k p?vodn?mu',
|
||||
'Role': 'Role',
|
||||
'Rows in Table': 'Z?znamy v tabulce',
|
||||
'Rows selected': 'Z?znam? zobrazeno',
|
||||
'rules are not defined': 'pravidla nejsou definov?na',
|
||||
"Run tests in this file (to run all files, you may also use the button labelled 'test')": "Spust? testy v tomto souboru (ke spu?t?n? v?ech test?, pou?ijte tla??tko 'test')",
|
||||
'Running on %s': 'B??? na %s',
|
||||
'Save': 'Ulo?it',
|
||||
'Save via Ajax': 'Ulo?it pomoc? Ajaxu',
|
||||
'Saved file hash:': 'hash ulo?en?ho souboru:',
|
||||
'Semantic': 'Modul semantic',
|
||||
'Services': 'Slu?by',
|
||||
'Set Breakpoint on %s at line %s: %s': 'Bod p?eru?en? nastaven v souboru %s na ??dce %s: %s',
|
||||
'shell': 'p??kazov? ??dka',
|
||||
'Site': 'Spr?va aplikac?',
|
||||
'Size of cache:': 'Velikost cache:',
|
||||
'skip to generate': 'skip to generate',
|
||||
'Sorry, could not find mercurial installed': 'Bohu?el mercurial nen? nainstalov?n.',
|
||||
'Start a new app': 'Vytvo?it novou aplikaci',
|
||||
'Start searching': 'Za??t hled?n?',
|
||||
'Start wizard': 'Spustit pr?vodce',
|
||||
'state': 'stav',
|
||||
'static': 'statick? soubory',
|
||||
'Static files': 'Statick? soubory',
|
||||
'Statistics': 'Statistika',
|
||||
'Step': 'Step',
|
||||
'Stylesheet': 'CSS styly',
|
||||
'submit': 'odeslat',
|
||||
'Submit': 'Odeslat',
|
||||
'successful': '?sp??n?',
|
||||
'Support': 'Podpora',
|
||||
'Sure you want to delete this object?': 'Opravdu chcete smazat tento objekt?',
|
||||
'Table': 'tabulka',
|
||||
'Table name': 'N?zev tabulky',
|
||||
'Temporary': 'Do?asn?',
|
||||
'test': 'test',
|
||||
'The "query" is a condition like "db.table1.field1==\'value\'". Something like "db.table1.field1==db.table2.field2" results in a SQL JOIN.': '"Dotaz" je podm?nka, nap??klad "db.tabulka1.pole1==\'hodnota\'". Podm?nka "db.tabulka1.pole1==db.tabulka2.pole2" pak vytvo?? SQL JOIN.',
|
||||
'The application logic, each URL path is mapped in one exposed function in the controller': 'Logika aplikace: ka?d? URL je mapov?na na funkci vystavovanou kontrol?rem.',
|
||||
'The Core': 'J?dro (The Core)',
|
||||
'The data representation, define database tables and sets': 'Reprezentace dat: definovat tabulky datab?ze a z?znamy',
|
||||
'The output of the file is a dictionary that was rendered by the view %s': 'V?stup ze souboru je slovn?k, kter? se zobrazil v pohledu %s.',
|
||||
'The presentations layer, views are also known as templates': 'Prezenta?n? vrstva: pohledy ?i templaty (?ablony)',
|
||||
'The Views': 'Pohledy (The Views)',
|
||||
'There are no plugins': '??dn? moduly nejsou instalov?ny.',
|
||||
'There are no private files': '??dn? soukrom? soubory neexistuj?.',
|
||||
'These files are not served, they are only available from within your app': 'Tyto soubory jsou klient?m nep??stupn?. K dispozici jsou pouze v r?mci aplikace.',
|
||||
'These files are served without processing, your images go here': 'Tyto soubory jsou serv?rov?ny bez p??davn? logiky, sem pat?? nap?. obr?zky.',
|
||||
'This App': 'Tato aplikace',
|
||||
'This is a copy of the scaffolding application': 'Toto je kopie aplikace skelet.',
|
||||
'this page to see if a breakpoint was hit and debug interaction is required.': 'tuto str?nku, abyste uvid?li, zda se dos?hlo bodu p?eru?en?.',
|
||||
'Ticket': 'Ticket',
|
||||
'Time in Cache (h:m:s)': '?as v Cache (h:m:s)',
|
||||
'Timestamp': '?asov? raz?tko',
|
||||
'to previous version.': 'k p?edchoz? verzi.',
|
||||
'To create a plugin, name a file/folder plugin_[name]': 'Z?suvn? modul vytvo??te tak, ?e pojmenujete soubor/adres?? plugin_[jm?no modulu]',
|
||||
'To emulate a breakpoint programatically, write:': 'K nastaven? bodu p?eru?en? v k?du programu, napi?te:',
|
||||
'to use the debugger!': ', abyste mohli lad?c? program pou??vat!',
|
||||
'toggle breakpoint': 'vyp./zap. bod p?eru?en?',
|
||||
'Toggle Fullscreen': 'Na celou obrazovku a zp?t',
|
||||
'too short': 'P??li? kr?tk?',
|
||||
'Translation strings for the application': 'P?eklad text? pro aplikaci',
|
||||
'Try the mobile interface': 'Zkuste rozhran? pro mobiln? za??zen?',
|
||||
'Twitter': 'Twitter',
|
||||
'unable to parse csv file': 'csv soubor ned? sa zpracovat',
|
||||
'uncheck all': 'v?e odzna?it',
|
||||
'Uninstall': 'Odinstalovat',
|
||||
'update': 'aktualizovat',
|
||||
'update all languages': 'aktualizovat v?echny jazyky',
|
||||
'Update:': 'Upravit:',
|
||||
'upload': 'nahr?t',
|
||||
'Upload a package:': 'Nahr?t bal?k:',
|
||||
'Upload and install packed application': 'Nahr?t a instalovat zabalenou aplikaci',
|
||||
'upload file:': 'nahr?t soubor:',
|
||||
'upload plugin file:': 'nahr?t soubor modulu:',
|
||||
'Use (...)&(...) for AND, (...)|(...) for OR, and ~(...) for NOT to build more complex queries.': 'Pou?ijte (...)&(...) pro AND, (...)|(...) pro OR a ~(...) pro NOT pro sestaven? slo?it?j??ch dotaz?.',
|
||||
'User %(id)s Logged-in': 'U?ivatel %(id)s p?ihl??en',
|
||||
'User %(id)s Logged-out': 'U?ivatel %(id)s odhl??en',
|
||||
'User %(id)s Password changed': 'U?ivatel %(id)s zm?nil heslo',
|
||||
'User %(id)s Profile updated': 'U?ivatel %(id)s upravil profil',
|
||||
'User %(id)s Registered': 'U?ivatel %(id)s se zaregistroval',
|
||||
'User %(id)s Username retrieved': 'U?ivatel %(id)s si nachal zaslat p?ihla?ovac? jm?no',
|
||||
'User ID': 'ID u?ivatele',
|
||||
'Username': 'P?ihla?ovac? jm?no',
|
||||
'Verify Password': 'Zopakujte heslo',
|
||||
'Version %s.%s.%s (%s) %s': 'Verze %s.%s.%s (%s) %s',
|
||||
'Versioning': 'Verzov?n?',
|
||||
'Videos': 'Videa',
|
||||
'View': 'Pohled (View)',
|
||||
'Views': 'Pohledy',
|
||||
'views': 'pohledy',
|
||||
'Web Framework': 'Web Framework',
|
||||
'web2py is up to date': 'M?te aktu?ln? verzi web2py.',
|
||||
'web2py online debugger': 'Lad?c? online web2py program',
|
||||
'web2py Recent Tweets': '?t?bet?n? na Twitteru o web2py',
|
||||
'Welcome': 'V?tejte',
|
||||
'Welcome to web2py': 'Vitejte ve web2py',
|
||||
'Welcome to web2py!': 'V?tejte ve web2py!',
|
||||
'Which called the function %s located in the file %s': 'kter? zavolala funkci %s v souboru (kontrol?ru) %s.',
|
||||
'You are successfully running web2py': '?sp??n? jste spustili web2py.',
|
||||
'You can also set and remove breakpoint in the edit window, using the Toggle Breakpoint button': 'Nastavovat a mazat body p?eru?en? je t?? mo?no v r?mci editov?n? zdrojov?ho souboru p?es tla??tko Vyp./Zap. bod p?eru?en?',
|
||||
'You can modify this application and adapt it to your needs': 'Tuto aplikaci si m??ete upravit a p?izp?sobit ji sv?m pot?eb?m.',
|
||||
'You need to set up and reach a': 'Je t?eba nejprve nastavit a doj?t a? na',
|
||||
'You visited the url %s': 'Nav?t?vili jste str?nku %s,',
|
||||
}
|
||||
# coding: utf8
|
||||
{
|
||||
'!langcode!': 'cs-cz',
|
||||
'!langname!': 'čeština',
|
||||
'"update" is an optional expression like "field1=\'newvalue\'". You cannot update or delete the results of a JOIN': 'Kolonka "Upravit" je nepovinný výraz, například "pole1=\'nováhodnota\'". Výsledky databázového JOINu nemůžete mazat ani upravovat.',
|
||||
'"User Exception" debug mode. An error ticket could be issued!': '"User Exception" debug mode. An error ticket could be issued!',
|
||||
'%%{Row} in Table': '%%{řádek} v tabulce',
|
||||
'%%{Row} selected': 'označených %%{řádek}',
|
||||
'%s %%{row} deleted': '%s smazaných %%{záznam}',
|
||||
'%s %%{row} updated': '%s upravených %%{záznam}',
|
||||
'%s selected': '%s označených',
|
||||
'%Y-%m-%d': '%d.%m.%Y',
|
||||
'%Y-%m-%d %H:%M:%S': '%d.%m.%Y %H:%M:%S',
|
||||
'(requires internet access)': '(vyžaduje připojení k internetu)',
|
||||
'(requires internet access, experimental)': '(requires internet access, experimental)',
|
||||
'(something like "it-it")': '(například "cs-cs")',
|
||||
'@markmin\x01(file **gluon/contrib/plural_rules/%s.py** is not found)': '(soubor **gluon/contrib/plural_rules/%s.py** nenalezen)',
|
||||
'@markmin\x01Searching: **%s** %%{file}': 'Hledání: **%s** %%{soubor}',
|
||||
'About': 'O programu',
|
||||
'About application': 'O aplikaci',
|
||||
'Access Control': 'Řízení přístupu',
|
||||
'Add breakpoint': 'Přidat bod přerušení',
|
||||
'Additional code for your application': 'Další kód pro Vaši aplikaci',
|
||||
'Admin design page': 'Admin design page',
|
||||
'Admin language': 'jazyk rozhraní',
|
||||
'Administrative interface': 'pro administrátorské rozhraní klikněte sem',
|
||||
'Administrative Interface': 'Administrátorské rozhraní',
|
||||
'administrative interface': 'rozhraní pro správu',
|
||||
'Administrator Password:': 'Administrátorské heslo:',
|
||||
'Ajax Recipes': 'Recepty s ajaxem',
|
||||
'An error occured, please %s the page': 'An error occured, please %s the page',
|
||||
'and rename it:': 'a přejmenovat na:',
|
||||
'appadmin': 'appadmin',
|
||||
'appadmin is disabled because insecure channel': 'appadmin je zakázaná bez zabezpečeného spojení',
|
||||
'Application': 'Application',
|
||||
'application "%s" uninstalled': 'application "%s" odinstalována',
|
||||
'application compiled': 'aplikace zkompilována',
|
||||
'Application name:': 'Název aplikace:',
|
||||
'are not used': 'nepoužita',
|
||||
'are not used yet': 'ještě nepoužita',
|
||||
'Are you sure you want to delete this object?': 'Opravdu chcete odstranit tento objekt?',
|
||||
'Are you sure you want to uninstall application "%s"?': 'Opravdu chcete odinstalovat aplikaci "%s"?',
|
||||
'arguments': 'arguments',
|
||||
'at char %s': 'at char %s',
|
||||
'at line %s': 'at line %s',
|
||||
'ATTENTION:': 'ATTENTION:',
|
||||
'ATTENTION: TESTING IS NOT THREAD SAFE SO DO NOT PERFORM MULTIPLE TESTS CONCURRENTLY.': 'ATTENTION: TESTING IS NOT THREAD SAFE SO DO NOT PERFORM MULTIPLE TESTS CONCURRENTLY.',
|
||||
'Available Databases and Tables': 'Dostupné databáze a tabulky',
|
||||
'back': 'zpět',
|
||||
'Back to wizard': 'Back to wizard',
|
||||
'Basics': 'Basics',
|
||||
'Begin': 'Začít',
|
||||
'breakpoint': 'bod přerušení',
|
||||
'Breakpoints': 'Body přerušení',
|
||||
'breakpoints': 'body přerušení',
|
||||
'Buy this book': 'Koupit web2py knihu',
|
||||
'Cache': 'Cache',
|
||||
'cache': 'cache',
|
||||
'Cache Keys': 'Klíče cache',
|
||||
'cache, errors and sessions cleaned': 'cache, chyby a relace byly pročištěny',
|
||||
'can be a git repo': 'může to být git repo',
|
||||
'Cancel': 'Storno',
|
||||
'Cannot be empty': 'Nemůže být prázdné',
|
||||
'Change Admin Password': 'Změnit heslo pro správu',
|
||||
'Change admin password': 'Změnit heslo pro správu aplikací',
|
||||
'Change password': 'Změna hesla',
|
||||
'check all': 'vše označit',
|
||||
'Check for upgrades': 'Zkusit aktualizovat',
|
||||
'Check to delete': 'Označit ke smazání',
|
||||
'Check to delete:': 'Označit ke smazání:',
|
||||
'Checking for upgrades...': 'Zjišťuji, zda jsou k dispozici aktualizace...',
|
||||
'Clean': 'Pročistit',
|
||||
'Clear CACHE?': 'Vymazat CACHE?',
|
||||
'Clear DISK': 'Vymazat DISK',
|
||||
'Clear RAM': 'Vymazat RAM',
|
||||
'Click row to expand traceback': 'Pro rozbalení stopy, klikněte na řádek',
|
||||
'Click row to view a ticket': 'Pro zobrazení chyby (ticketu), klikněte na řádku...',
|
||||
'Client IP': 'IP adresa klienta',
|
||||
'code': 'code',
|
||||
'Code listing': 'Code listing',
|
||||
'collapse/expand all': 'vše sbalit/rozbalit',
|
||||
'Community': 'Komunita',
|
||||
'Compile': 'Zkompilovat',
|
||||
'compiled application removed': 'zkompilovaná aplikace smazána',
|
||||
'Components and Plugins': 'Komponenty a zásuvné moduly',
|
||||
'Condition': 'Podmínka',
|
||||
'continue': 'continue',
|
||||
'Controller': 'Kontrolér (Controller)',
|
||||
'Controllers': 'Kontroléry',
|
||||
'controllers': 'kontroléry',
|
||||
'Copyright': 'Copyright',
|
||||
'Count': 'Počet',
|
||||
'Create': 'Vytvořit',
|
||||
'create file with filename:': 'vytvořit soubor s názvem:',
|
||||
'created by': 'vytvořil',
|
||||
'Created By': 'Vytvořeno - kým',
|
||||
'Created On': 'Vytvořeno - kdy',
|
||||
'crontab': 'crontab',
|
||||
'Current request': 'Aktuální požadavek',
|
||||
'Current response': 'Aktuální odpověď',
|
||||
'Current session': 'Aktuální relace',
|
||||
'currently running': 'právě běží',
|
||||
'currently saved or': 'uloženo nebo',
|
||||
'customize me!': 'upravte mě!',
|
||||
'data uploaded': 'data nahrána',
|
||||
'Database': 'Rozhraní databáze',
|
||||
'Database %s select': 'databáze %s výběr',
|
||||
'Database administration': 'Database administration',
|
||||
'database administration': 'správa databáze',
|
||||
'Date and Time': 'Datum a čas',
|
||||
'day': 'den',
|
||||
'db': 'db',
|
||||
'DB Model': 'Databázový model',
|
||||
'Debug': 'Ladění',
|
||||
'defines tables': 'defines tables',
|
||||
'Delete': 'Smazat',
|
||||
'delete': 'smazat',
|
||||
'delete all checked': 'smazat vše označené',
|
||||
'delete plugin': 'delete plugin',
|
||||
'Delete this file (you will be asked to confirm deletion)': 'Smazat tento soubor (budete požádán o potvrzení mazání)',
|
||||
'Delete:': 'Smazat:',
|
||||
'deleted after first hit': 'smazat po prvním dosažení',
|
||||
'Demo': 'Demo',
|
||||
'Deploy': 'Nahrát',
|
||||
'Deploy on Google App Engine': 'Nahrát na Google App Engine',
|
||||
'Deploy to OpenShift': 'Nahrát na OpenShift',
|
||||
'Deployment Recipes': 'Postupy pro deployment',
|
||||
'Description': 'Popis',
|
||||
'design': 'návrh',
|
||||
'Detailed traceback description': 'Podrobný výpis prostředí',
|
||||
'details': 'podrobnosti',
|
||||
'direction: ltr': 'směr: ltr',
|
||||
'Disable': 'Zablokovat',
|
||||
'DISK': 'DISK',
|
||||
'Disk Cache Keys': 'Klíče diskové cache',
|
||||
'Disk Cleared': 'Disk smazán',
|
||||
'docs': 'dokumentace',
|
||||
'Documentation': 'Dokumentace',
|
||||
"Don't know what to do?": 'Nevíte kudy kam?',
|
||||
'done!': 'hotovo!',
|
||||
'Download': 'Stáhnout',
|
||||
'download layouts': 'stáhnout moduly rozvržení stránky',
|
||||
'download plugins': 'stáhnout zásuvné moduly',
|
||||
'E-mail': 'E-mail',
|
||||
'Edit': 'Upravit',
|
||||
'edit all': 'edit all',
|
||||
'Edit application': 'Správa aplikace',
|
||||
'edit controller': 'edit controller',
|
||||
'Edit current record': 'Upravit aktuální záznam',
|
||||
'Edit Profile': 'Upravit profil',
|
||||
'edit views:': 'upravit pohled:',
|
||||
'Editing file "%s"': 'Úprava souboru "%s"',
|
||||
'Editing Language file': 'Úprava jazykového souboru',
|
||||
'Editing Plural Forms File': 'Editing Plural Forms File',
|
||||
'Email and SMS': 'Email a SMS',
|
||||
'Enable': 'Odblokovat',
|
||||
'enter a number between %(min)g and %(max)g': 'zadejte číslo mezi %(min)g a %(max)g',
|
||||
'enter an integer between %(min)g and %(max)g': 'zadejte celé číslo mezi %(min)g a %(max)g',
|
||||
'Error': 'Chyba',
|
||||
'Error logs for "%(app)s"': 'Seznam výskytu chyb pro aplikaci "%(app)s"',
|
||||
'Error snapshot': 'Snapshot chyby',
|
||||
'Error ticket': 'Ticket chyby',
|
||||
'Errors': 'Chyby',
|
||||
'Exception %(extype)s: %(exvalue)s': 'Exception %(extype)s: %(exvalue)s',
|
||||
'Exception %s': 'Exception %s',
|
||||
'Exception instance attributes': 'Prvky instance výjimky',
|
||||
'Expand Abbreviation': 'Expand Abbreviation',
|
||||
'export as csv file': 'exportovat do .csv souboru',
|
||||
'exposes': 'vystavuje',
|
||||
'exposes:': 'vystavuje funkce:',
|
||||
'extends': 'rozšiřuje',
|
||||
'failed to compile file because:': 'soubor se nepodařilo zkompilovat, protože:',
|
||||
'FAQ': 'Často kladené dotazy',
|
||||
'File': 'Soubor',
|
||||
'file': 'soubor',
|
||||
'file "%(filename)s" created': 'file "%(filename)s" created',
|
||||
'file saved on %(time)s': 'soubor uložen %(time)s',
|
||||
'file saved on %s': 'soubor uložen %s',
|
||||
'Filename': 'Název souboru',
|
||||
'filter': 'filtr',
|
||||
'Find Next': 'Najít další',
|
||||
'Find Previous': 'Najít předchozí',
|
||||
'First name': 'Křestní jméno',
|
||||
'Forgot username?': 'Zapomněl jste svoje přihlašovací jméno?',
|
||||
'forgot username?': 'zapomněl jste svoje přihlašovací jméno?',
|
||||
'Forms and Validators': 'Formuláře a validátory',
|
||||
'Frames': 'Frames',
|
||||
'Free Applications': 'Aplikace zdarma',
|
||||
'Functions with no doctests will result in [passed] tests.': 'Functions with no doctests will result in [passed] tests.',
|
||||
'Generate': 'Vytvořit',
|
||||
'Get from URL:': 'Stáhnout z internetu:',
|
||||
'Git Pull': 'Git Pull',
|
||||
'Git Push': 'Git Push',
|
||||
'Globals##debug': 'Globální proměnné',
|
||||
'go!': 'OK!',
|
||||
'Goto': 'Goto',
|
||||
'graph model': 'graph model',
|
||||
'Group %(group_id)s created': 'Skupina %(group_id)s vytvořena',
|
||||
'Group ID': 'ID skupiny',
|
||||
'Groups': 'Skupiny',
|
||||
'Hello World': 'Ahoj světe',
|
||||
'Help': 'Nápověda',
|
||||
'Hide/Show Translated strings': 'Skrýt/Zobrazit přeložené texty',
|
||||
'Hits': 'Kolikrát dosaženo',
|
||||
'Home': 'Domovská stránka',
|
||||
'honored only if the expression evaluates to true': 'brát v potaz jen když se tato podmínka vyhodnotí kladně',
|
||||
'How did you get here?': 'Jak jste se sem vlastně dostal?',
|
||||
'If start the upgrade, be patient, it may take a while to download': 'If start the upgrade, be patient, it may take a while to download',
|
||||
'If the report above contains a ticket number it indicates a failure in executing the controller, before any attempt to execute the doctests. This is usually due to an indentation error or an error outside function code.\nA green title indicates that all tests (if defined) passed. In this case test results are not shown.': 'If the report above contains a ticket number it indicates a failure in executing the controller, before any attempt to execute the doctests. This is usually due to an indentation error or an error outside function code.\nA green title indicates that all tests (if defined) passed. In this case test results are not shown.',
|
||||
'import': 'import',
|
||||
'Import/Export': 'Import/Export',
|
||||
'includes': 'zahrnuje',
|
||||
'Index': 'Index',
|
||||
'insert new': 'vložit nový záznam ',
|
||||
'insert new %s': 'vložit nový záznam %s',
|
||||
'inspect attributes': 'inspect attributes',
|
||||
'Install': 'Instalovat',
|
||||
'Installed applications': 'Nainstalované aplikace',
|
||||
'Interaction at %s line %s': 'Interakce v %s, na řádce %s',
|
||||
'Interactive console': 'Interaktivní příkazová řádka',
|
||||
'Internal State': 'Vnitřní stav',
|
||||
'Introduction': 'Úvod',
|
||||
'Invalid email': 'Neplatný email',
|
||||
'Invalid password': 'Nesprávné heslo',
|
||||
'invalid password.': 'neplatné heslo',
|
||||
'Invalid Query': 'Neplatný dotaz',
|
||||
'invalid request': 'Neplatný požadavek',
|
||||
'Is Active': 'Je aktivní',
|
||||
'It is %s %%{day} today.': 'Dnes je to %s %%{den}.',
|
||||
'Key': 'Klíč',
|
||||
'Key bindings': 'Vazby klíčů',
|
||||
'Key bindings for ZenCoding Plugin': 'Key bindings for ZenCoding Plugin',
|
||||
'languages': 'jazyky',
|
||||
'Languages': 'Jazyky',
|
||||
'Last name': 'Příjmení',
|
||||
'Last saved on:': 'Naposledy uloženo:',
|
||||
'Layout': 'Rozvržení stránky (layout)',
|
||||
'Layout Plugins': 'Moduly rozvržení stránky (Layout Plugins)',
|
||||
'Layouts': 'Rozvržení stránek',
|
||||
'License for': 'Licence pro',
|
||||
'Line number': 'Číslo řádku',
|
||||
'LineNo': 'Č.řádku',
|
||||
'Live Chat': 'Online pokec',
|
||||
'loading...': 'nahrávám...',
|
||||
'locals': 'locals',
|
||||
'Locals##debug': 'Lokální proměnné',
|
||||
'Logged in': 'Přihlášení proběhlo úspěšně',
|
||||
'Logged out': 'Odhlášení proběhlo úspěšně',
|
||||
'Login': 'Přihlásit se',
|
||||
'login': 'přihlásit se',
|
||||
'Login to the Administrative Interface': 'Přihlásit se do Správce aplikací',
|
||||
'logout': 'odhlásit se',
|
||||
'Logout': 'Odhlásit se',
|
||||
'Lost Password': 'Zapomněl jste heslo',
|
||||
'Lost password?': 'Zapomněl jste heslo?',
|
||||
'lost password?': 'zapomněl jste heslo?',
|
||||
'Manage': 'Manage',
|
||||
'Manage Cache': 'Manage Cache',
|
||||
'Menu Model': 'Model rozbalovací nabídky',
|
||||
'Models': 'Modely',
|
||||
'models': 'modely',
|
||||
'Modified By': 'Změněno - kým',
|
||||
'Modified On': 'Změněno - kdy',
|
||||
'Modules': 'Moduly',
|
||||
'modules': 'moduly',
|
||||
'My Sites': 'Správa aplikací',
|
||||
'Name': 'Jméno',
|
||||
'new application "%s" created': 'nová aplikace "%s" vytvořena',
|
||||
'New Application Wizard': 'Nový průvodce aplikací',
|
||||
'New application wizard': 'Nový průvodce aplikací',
|
||||
'New password': 'Nové heslo',
|
||||
'New Record': 'Nový záznam',
|
||||
'new record inserted': 'nový záznam byl založen',
|
||||
'New simple application': 'Vytvořit primitivní aplikaci',
|
||||
'next': 'next',
|
||||
'next 100 rows': 'dalších 100 řádků',
|
||||
'No databases in this application': 'V této aplikaci nejsou žádné databáze',
|
||||
'No Interaction yet': 'Ještě žádná interakce nenastala',
|
||||
'No ticket_storage.txt found under /private folder': 'Soubor ticket_storage.txt v adresáři /private nenalezen',
|
||||
'Object or table name': 'Objekt či tabulka',
|
||||
'Old password': 'Původní heslo',
|
||||
'online designer': 'online návrhář',
|
||||
'Online examples': 'Příklady online',
|
||||
'Open new app in new window': 'Open new app in new window',
|
||||
'or alternatively': 'or alternatively',
|
||||
'Or Get from URL:': 'Or Get from URL:',
|
||||
'or import from csv file': 'nebo importovat z .csv souboru',
|
||||
'Origin': 'Původ',
|
||||
'Original/Translation': 'Originál/Překlad',
|
||||
'Other Plugins': 'Ostatní moduly',
|
||||
'Other Recipes': 'Ostatní zásuvné moduly',
|
||||
'Overview': 'Přehled',
|
||||
'Overwrite installed app': 'Přepsat instalovanou aplikaci',
|
||||
'Pack all': 'Zabalit',
|
||||
'Pack compiled': 'Zabalit zkompilované',
|
||||
'pack plugin': 'pack plugin',
|
||||
'password': 'heslo',
|
||||
'Password': 'Heslo',
|
||||
"Password fields don't match": 'Hesla se neshodují',
|
||||
'Peeking at file': 'Peeking at file',
|
||||
'Please': 'Prosím',
|
||||
'Plugin "%s" in application': 'Plugin "%s" in application',
|
||||
'plugins': 'zásuvné moduly',
|
||||
'Plugins': 'Zásuvné moduly',
|
||||
'Plural Form #%s': 'Plural Form #%s',
|
||||
'Plural-Forms:': 'Množná čísla:',
|
||||
'Powered by': 'Poháněno',
|
||||
'Preface': 'Předmluva',
|
||||
'previous 100 rows': 'předchozích 100 řádků',
|
||||
'Private files': 'Soukromé soubory',
|
||||
'private files': 'soukromé soubory',
|
||||
'profile': 'profil',
|
||||
'Project Progress': 'Vývoj projektu',
|
||||
'Python': 'Python',
|
||||
'Query:': 'Dotaz:',
|
||||
'Quick Examples': 'Krátké příklady',
|
||||
'RAM': 'RAM',
|
||||
'RAM Cache Keys': 'Klíče RAM Cache',
|
||||
'Ram Cleared': 'RAM smazána',
|
||||
'Readme': 'Nápověda',
|
||||
'Recipes': 'Postupy jak na to',
|
||||
'Record': 'Záznam',
|
||||
'record does not exist': 'záznam neexistuje',
|
||||
'Record ID': 'ID záznamu',
|
||||
'Record id': 'id záznamu',
|
||||
'refresh': 'obnovte',
|
||||
'register': 'registrovat',
|
||||
'Register': 'Zaregistrovat se',
|
||||
'Registration identifier': 'Registrační identifikátor',
|
||||
'Registration key': 'Registrační klíč',
|
||||
'reload': 'reload',
|
||||
'Reload routes': 'Znovu nahrát cesty',
|
||||
'Remember me (for 30 days)': 'Zapamatovat na 30 dní',
|
||||
'Remove compiled': 'Odstranit zkompilované',
|
||||
'Removed Breakpoint on %s at line %s': 'Bod přerušení smazán - soubor %s na řádce %s',
|
||||
'Replace': 'Zaměnit',
|
||||
'Replace All': 'Zaměnit vše',
|
||||
'request': 'request',
|
||||
'Reset Password key': 'Reset registračního klíče',
|
||||
'response': 'response',
|
||||
'restart': 'restart',
|
||||
'restore': 'obnovit',
|
||||
'Retrieve username': 'Získat přihlašovací jméno',
|
||||
'return': 'return',
|
||||
'revert': 'vrátit se k původnímu',
|
||||
'Role': 'Role',
|
||||
'Rows in Table': 'Záznamy v tabulce',
|
||||
'Rows selected': 'Záznamů zobrazeno',
|
||||
'rules are not defined': 'pravidla nejsou definována',
|
||||
"Run tests in this file (to run all files, you may also use the button labelled 'test')": "Spustí testy v tomto souboru (ke spuštění všech testů, použijte tlačítko 'test')",
|
||||
'Running on %s': 'Běží na %s',
|
||||
'Save': 'Uložit',
|
||||
'Save file:': 'Save file:',
|
||||
'Save via Ajax': 'Uložit pomocí Ajaxu',
|
||||
'Saved file hash:': 'hash uloženého souboru:',
|
||||
'Semantic': 'Modul semantic',
|
||||
'Services': 'Služby',
|
||||
'session': 'session',
|
||||
'session expired': 'session expired',
|
||||
'Set Breakpoint on %s at line %s: %s': 'Bod přerušení nastaven v souboru %s na řádce %s: %s',
|
||||
'shell': 'příkazová řádka',
|
||||
'Singular Form': 'Singular Form',
|
||||
'Site': 'Správa aplikací',
|
||||
'Size of cache:': 'Velikost cache:',
|
||||
'skip to generate': 'skip to generate',
|
||||
'Sorry, could not find mercurial installed': 'Bohužel mercurial není nainstalován.',
|
||||
'Start a new app': 'Vytvořit novou aplikaci',
|
||||
'Start searching': 'Začít hledání',
|
||||
'Start wizard': 'Spustit průvodce',
|
||||
'state': 'stav',
|
||||
'Static': 'Static',
|
||||
'static': 'statické soubory',
|
||||
'Static files': 'Statické soubory',
|
||||
'Statistics': 'Statistika',
|
||||
'Step': 'Step',
|
||||
'step': 'step',
|
||||
'stop': 'stop',
|
||||
'Stylesheet': 'CSS styly',
|
||||
'submit': 'odeslat',
|
||||
'Submit': 'Odeslat',
|
||||
'successful': 'úspěšně',
|
||||
'Support': 'Podpora',
|
||||
'Sure you want to delete this object?': 'Opravdu chcete smazat tento objekt?',
|
||||
'Table': 'tabulka',
|
||||
'Table name': 'Název tabulky',
|
||||
'Temporary': 'Dočasný',
|
||||
'test': 'test',
|
||||
'Testing application': 'Testing application',
|
||||
'The "query" is a condition like "db.table1.field1==\'value\'". Something like "db.table1.field1==db.table2.field2" results in a SQL JOIN.': '"Dotaz" je podmínka, například "db.tabulka1.pole1==\'hodnota\'". Podmínka "db.tabulka1.pole1==db.tabulka2.pole2" pak vytvoří SQL JOIN.',
|
||||
'The application logic, each URL path is mapped in one exposed function in the controller': 'Logika aplikace: každá URL je mapována na funkci vystavovanou kontrolérem.',
|
||||
'The Core': 'Jádro (The Core)',
|
||||
'The data representation, define database tables and sets': 'Reprezentace dat: definovat tabulky databáze a záznamy',
|
||||
'The output of the file is a dictionary that was rendered by the view %s': 'Výstup ze souboru je slovník, který se zobrazil v pohledu %s.',
|
||||
'The presentations layer, views are also known as templates': 'Prezentační vrstva: pohledy či templaty (šablony)',
|
||||
'The Views': 'Pohledy (The Views)',
|
||||
'There are no controllers': 'There are no controllers',
|
||||
'There are no modules': 'There are no modules',
|
||||
'There are no plugins': 'Žádné moduly nejsou instalovány.',
|
||||
'There are no private files': 'Žádné soukromé soubory neexistují.',
|
||||
'There are no static files': 'There are no static files',
|
||||
'There are no translators, only default language is supported': 'There are no translators, only default language is supported',
|
||||
'There are no views': 'There are no views',
|
||||
'These files are not served, they are only available from within your app': 'Tyto soubory jsou klientům nepřístupné. K dispozici jsou pouze v rámci aplikace.',
|
||||
'These files are served without processing, your images go here': 'Tyto soubory jsou servírovány bez přídavné logiky, sem patří např. obrázky.',
|
||||
'This App': 'Tato aplikace',
|
||||
'This is a copy of the scaffolding application': 'Toto je kopie aplikace skelet.',
|
||||
'This is an experimental feature and it needs more testing. If you decide to upgrade you do it at your own risk': 'This is an experimental feature and it needs more testing. If you decide to upgrade you do it at your own risk',
|
||||
'This is the %(filename)s template': 'This is the %(filename)s template',
|
||||
'this page to see if a breakpoint was hit and debug interaction is required.': 'tuto stránku, abyste uviděli, zda se dosáhlo bodu přerušení.',
|
||||
'Ticket': 'Ticket',
|
||||
'Ticket ID': 'Ticket ID',
|
||||
'Time in Cache (h:m:s)': 'Čas v Cache (h:m:s)',
|
||||
'Timestamp': 'Časové razítko',
|
||||
'to previous version.': 'k předchozí verzi.',
|
||||
'To create a plugin, name a file/folder plugin_[name]': 'Zásuvný modul vytvoříte tak, že pojmenujete soubor/adresář plugin_[jméno modulu]',
|
||||
'To emulate a breakpoint programatically, write:': 'K nastavení bodu přerušení v kódu programu, napište:',
|
||||
'to use the debugger!': ', abyste mohli ladící program používat!',
|
||||
'toggle breakpoint': 'vyp./zap. bod přerušení',
|
||||
'Toggle Fullscreen': 'Na celou obrazovku a zpět',
|
||||
'too short': 'Příliš krátké',
|
||||
'Traceback': 'Traceback',
|
||||
'Translation strings for the application': 'Překlad textů pro aplikaci',
|
||||
'try something like': 'try something like',
|
||||
'Try the mobile interface': 'Zkuste rozhraní pro mobilní zařízení',
|
||||
'try view': 'try view',
|
||||
'Twitter': 'Twitter',
|
||||
'Type python statement in here and hit Return (Enter) to execute it.': 'Type python statement 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': 'Unable to check for upgrades',
|
||||
'unable to parse csv file': 'csv soubor nedá sa zpracovat',
|
||||
'uncheck all': 'vše odznačit',
|
||||
'Uninstall': 'Odinstalovat',
|
||||
'update': 'aktualizovat',
|
||||
'update all languages': 'aktualizovat všechny jazyky',
|
||||
'Update:': 'Upravit:',
|
||||
'Upgrade': 'Upgrade',
|
||||
'upgrade now': 'upgrade now',
|
||||
'upgrade now to %s': 'upgrade now to %s',
|
||||
'upload': 'nahrát',
|
||||
'Upload': 'Upload',
|
||||
'Upload a package:': 'Nahrát balík:',
|
||||
'Upload and install packed application': 'Nahrát a instalovat zabalenou aplikaci',
|
||||
'upload file:': 'nahrát soubor:',
|
||||
'upload plugin file:': 'nahrát soubor modulu:',
|
||||
'Use (...)&(...) for AND, (...)|(...) for OR, and ~(...) for NOT to build more complex queries.': 'Použijte (...)&(...) pro AND, (...)|(...) pro OR a ~(...) pro NOT pro sestavení složitějších dotazů.',
|
||||
'User %(id)s Logged-in': 'Uživatel %(id)s přihlášen',
|
||||
'User %(id)s Logged-out': 'Uživatel %(id)s odhlášen',
|
||||
'User %(id)s Password changed': 'Uživatel %(id)s změnil heslo',
|
||||
'User %(id)s Profile updated': 'Uživatel %(id)s upravil profil',
|
||||
'User %(id)s Registered': 'Uživatel %(id)s se zaregistroval',
|
||||
'User %(id)s Username retrieved': 'Uživatel %(id)s si nachal zaslat přihlašovací jméno',
|
||||
'User ID': 'ID uživatele',
|
||||
'Username': 'Přihlašovací jméno',
|
||||
'variables': 'variables',
|
||||
'Verify Password': 'Zopakujte heslo',
|
||||
'Version': 'Verze',
|
||||
'Version %s.%s.%s (%s) %s': 'Verze %s.%s.%s (%s) %s',
|
||||
'Versioning': 'Verzování',
|
||||
'Videos': 'Videa',
|
||||
'View': 'Pohled (View)',
|
||||
'Views': 'Pohledy',
|
||||
'views': 'pohledy',
|
||||
'Web Framework': 'Web Framework',
|
||||
'web2py is up to date': 'Máte aktuální verzi web2py.',
|
||||
'web2py online debugger': 'Ladící online web2py program',
|
||||
'web2py Recent Tweets': 'Štěbetání na Twitteru o web2py',
|
||||
'web2py upgrade': 'web2py upgrade',
|
||||
'web2py upgraded; please restart it': 'web2py upgraded; please restart it',
|
||||
'Welcome': 'Vítejte',
|
||||
'Welcome to web2py': 'Vitejte ve web2py',
|
||||
'Welcome to web2py!': 'Vítejte ve web2py!',
|
||||
'Which called the function %s located in the file %s': 'která zavolala funkci %s v souboru (kontroléru) %s.',
|
||||
'You are successfully running web2py': 'Úspěšně jste spustili web2py.',
|
||||
'You can also set and remove breakpoint in the edit window, using the Toggle Breakpoint button': 'Nastavovat a mazat body přerušení je též možno v rámci editování zdrojového souboru přes tlačítko Vyp./Zap. bod přerušení',
|
||||
'You can modify this application and adapt it to your needs': 'Tuto aplikaci si můžete upravit a přizpůsobit ji svým potřebám.',
|
||||
'You need to set up and reach a': 'Je třeba nejprve nastavit a dojít až na',
|
||||
'You visited the url %s': 'Navštívili jste stránku %s,',
|
||||
'Your application will be blocked until you click an action button (next, step, continue, etc.)': 'Aplikace bude blokována než se klikne na jedno z tlačítek (další, krok, pokračovat, atd.)',
|
||||
'Your can inspect variables using the console bellow': 'Níže pomocí příkazové řádky si můžete prohlédnout proměnné',
|
||||
}
|
||||
|
||||
+160
-129
@@ -1,119 +1,126 @@
|
||||
# coding: utf8
|
||||
# Translation by: Klaus Kappel <kkappel@yahoo.de>
|
||||
{
|
||||
'!langcode!': 'de',
|
||||
'!langname!': 'Deutsch',
|
||||
'"update" is an optional expression like "field1=\'newvalue\'". You cannot update or delete the results of a JOIN': '"Update" ist ein optionaler Ausdruck wie "Feld1 = \'newvalue". JOIN Ergebnisse können nicht aktualisiert oder gelöscht werden',
|
||||
'%s %%{row} deleted': '%s Zeilen gelöscht',
|
||||
'%s %%{row} updated': '%s Zeilen aktualisiert',
|
||||
'%Y-%m-%d': '%Y-%m-%d',
|
||||
'%Y-%m-%d %H:%M:%S': '%Y-%m-%d %H:%M:%S',
|
||||
'(requires internet access)': '(requires internet access)',
|
||||
'"update" is an optional expression like "field1=\'newvalue\'". You cannot update or delete the results of a JOIN': '"Update" ist ein optionaler Ausdruck wie "Feld1 = \'newvalue". JOIN Ergebnisse k?nnen nicht aktualisiert oder gel?scht werden',
|
||||
'%s %%{row} deleted': '%s %%{row} Zeilen gel?scht',
|
||||
'%s %%{row} updated': '%s %%{row} Zeilen aktualisiert',
|
||||
'%Y-%m-%d': '%d.%m.%Y',
|
||||
'%Y-%m-%d %H:%M:%S': '%d.%m.%Y %H:%M:%S',
|
||||
'(requires internet access)': '(Internet Zugang wir ben?tigt)',
|
||||
'(requires internet access, experimental)': '(ben?tigt Internet Zugang)',
|
||||
'(something like "it-it")': '(so etwas wie "it-it")',
|
||||
'@markmin\x01Searching: **%s** %%{file}': 'Searching: **%s** files',
|
||||
'A new version of web2py is available': 'Eine neue Version von web2py ist verfügbar',
|
||||
'A new version of web2py is available: %s': 'Eine neue Version von web2py ist verfügbar: %s',
|
||||
'@markmin\x01Searching: **%s** %%{file}': '@markmin\x01Suche: **%s** Dateien',
|
||||
'A new version of web2py is available': 'Eine neue Version von web2py ist verf?gbar',
|
||||
'A new version of web2py is available: %s': 'Eine neue Version von web2py ist verf?gbar: %s',
|
||||
'Abort': 'Abbrechen',
|
||||
'About': 'Über',
|
||||
'About application': 'Über die Anwendung',
|
||||
'Additional code for your application': 'Additional code for your application',
|
||||
'additional code for your application': 'zusätzlicher Code für Ihre Anwendung',
|
||||
'admin disabled because no admin password': ' admin ist deaktiviert, weil kein Admin-Passwort gesetzt ist',
|
||||
'admin disabled because not supported on google apps engine': 'admin ist deaktiviert, es existiert dafür keine Unterstützung auf der google apps engine',
|
||||
'About': '?ber',
|
||||
'About application': '?ber die Anwendung',
|
||||
'Additional code for your application': 'zus?tzlicher Code f?r Ihre Anwendung',
|
||||
'admin disabled because no admin password': 'admin ist deaktiviert, weil kein Admin-Passwort gesetzt ist',
|
||||
'admin disabled because not supported on google apps engine': 'admin ist deaktiviert, es existiert daf?r keine Unterst?tzung auf der google apps engine',
|
||||
'admin disabled because unable to access password file': 'admin ist deaktiviert, weil kein Zugriff auf die Passwortdatei besteht',
|
||||
'Admin is disabled because insecure channel': 'Appadmin ist deaktiviert, wegen der Benutzung eines unsicheren Kanals',
|
||||
'Admin is disabled because unsecure channel': 'Appadmin ist deaktiviert, wegen der Benutzung eines unsicheren Kanals',
|
||||
'Admin language': 'Admin language',
|
||||
'administrative interface': 'administrative interface',
|
||||
'Admin language': 'Admin-Sprache',
|
||||
'administrative interface': 'Administrative Schnittstelle',
|
||||
'Administrator Password:': 'Administrator Passwort:',
|
||||
'An error occured, please %s the page': 'Ein Fehler ist aufgetereten, bitte %s die Seite',
|
||||
'and rename it (required):': 'und benenne sie um (erforderlich):',
|
||||
'and rename it:': ' und benenne sie um:',
|
||||
'appadmin': 'appadmin',
|
||||
'appadmin is disabled because insecure channel': 'Appadmin ist deaktiviert, wegen der Benutzung eines unsicheren Kanals',
|
||||
'Application': 'Anwendung',
|
||||
'application "%s" uninstalled': 'Anwendung "%s" deinstalliert',
|
||||
'application compiled': 'Anwendung kompiliert',
|
||||
'application is compiled and cannot be designed': 'Die Anwendung ist kompiliert kann deswegen nicht mehr geändert werden',
|
||||
'Application name:': 'Application name:',
|
||||
'Are you sure you want to delete file "%s"?': 'Sind Sie sich sicher, dass Sie diese Datei löschen wollen "%s"?',
|
||||
'application is compiled and cannot be designed': 'Die Anwendung ist kompiliert kann deswegen nicht mehr ge?ndert werden',
|
||||
'Application name:': 'Name der Applikation:',
|
||||
'Are you sure you want to delete file "%s"?': 'Sind Sie sich sicher, dass Sie diese Datei l?schen wollen "%s"?',
|
||||
'Are you sure you want to delete this object?': 'Are you sure you want to delete this object?',
|
||||
'Are you sure you want to uninstall application "%s"': 'Sind Sie sich sicher, dass Sie diese Anwendung deinstallieren wollen "%s"',
|
||||
'Are you sure you want to uninstall application "%s"?': 'Sind Sie sich sicher, dass Sie diese Anwendung deinstallieren wollen "%s"?',
|
||||
'Are you sure you want to upgrade web2py now?': 'Sind Sie sich sicher, dass Sie web2py jetzt upgraden möchten?',
|
||||
'Are you sure you want to upgrade web2py now?': 'Sind Sie sich sicher, dass Sie web2py jetzt upgraden m?chten?',
|
||||
'arguments': 'arguments',
|
||||
'ATTENTION: Login requires a secure (HTTPS) connection or running on localhost.': 'ACHTUNG: Die Einwahl benötigt eine sichere (HTTPS) Verbindung. Es sei denn sie läuft Lokal(localhost).',
|
||||
'ATTENTION: TESTING IS NOT THREAD SAFE SO DO NOT PERFORM MULTIPLE TESTS CONCURRENTLY.': 'ACHTUNG: Testen ist nicht threadsicher. Führen sie also nicht mehrere Tests gleichzeitig aus.',
|
||||
'ATTENTION: This is an experimental feature and it needs more testing.': 'ACHTUNG: Dies ist eine experimentelle Funktion und benötigt noch weitere Tests.',
|
||||
'ATTENTION: Login requires a secure (HTTPS) connection or running on localhost.': 'ACHTUNG: Die Einwahl ben?tigt eine sichere (HTTPS) Verbindung. Es sei denn sie l?uft Lokal(localhost).',
|
||||
'ATTENTION: TESTING IS NOT THREAD SAFE SO DO NOT PERFORM MULTIPLE TESTS CONCURRENTLY.': 'ACHTUNG: Testen ist nicht threadsicher. F?hren sie also nicht mehrere Tests gleichzeitig aus.',
|
||||
'ATTENTION: This is an experimental feature and it needs more testing.': 'ACHTUNG: Dies ist eine experimentelle Funktion und ben?tigt noch weitere Tests.',
|
||||
'ATTENTION: you cannot edit the running application!': 'ACHTUNG: Eine laufende Anwendung kann nicht editiert werden!',
|
||||
'Authentication': 'Authentifizierung',
|
||||
'Available databases and tables': 'Verfügbare Datenbanken und Tabellen',
|
||||
'back': 'zurück',
|
||||
'beautify': 'beautify',
|
||||
'cache': 'Cache',
|
||||
'cache, errors and sessions cleaned': 'Zwischenspeicher (cache), Fehler und Sitzungen (sessions) gelöscht',
|
||||
'call': 'call',
|
||||
'can be a git repo': 'can be a git repo',
|
||||
'Available databases and tables': 'Verf?gbare Datenbanken und Tabellen',
|
||||
'back': 'zur?ck',
|
||||
'beautify': 'versch?nern',
|
||||
'cache': 'Pufferspeicher',
|
||||
'cache, errors and sessions cleaned': 'Zwischenspeicher (cache), Fehler und Sitzungen (sessions) gel?scht',
|
||||
'call': 'Aufruf',
|
||||
'can be a git repo': 'kann ein git Repository sein',
|
||||
'Cannot be empty': 'Darf nicht leer sein',
|
||||
'Cannot compile: there are errors in your app. Debug it, correct errors and try again.': 'Nicht Kompilierbar:Es sind Fehler in der Anwendung. Beseitigen Sie die Fehler und versuchen Sie es erneut.',
|
||||
'cannot create file': 'Kann Datei nicht erstellen',
|
||||
'cannot upload file "%(filename)s"': 'Kann Datei nicht Hochladen "%(filename)s"',
|
||||
'Change admin password': 'Administrator-Passwort ändern',
|
||||
'Change Password': 'Passwort ändern',
|
||||
'change password': 'Passwort ändern',
|
||||
'check all': 'alles auswählen',
|
||||
'Change admin password': 'Administrator-Passwort ?ndern',
|
||||
'Change Password': 'Passwort ?ndern',
|
||||
'change password': 'Passwort ?ndern',
|
||||
'check all': 'alles ausw?hlen',
|
||||
'Check for upgrades': 'check for upgrades',
|
||||
'Check to delete': 'Markiere zum löschen',
|
||||
'Checking for upgrades...': 'Auf Updates überprüfen...',
|
||||
'Clean': 'löschen',
|
||||
'click here for online examples': 'hier klicken für online Beispiele',
|
||||
'click here for the administrative interface': 'hier klicken für die Administrationsoberfläche ',
|
||||
'Check to delete': 'Markiere zum l?schen',
|
||||
'Checking for upgrades...': 'Auf Updates ?berpr?fen...',
|
||||
'Clean': 'leeren',
|
||||
'click here for online examples': 'hier klicken f?r online Beispiele',
|
||||
'click here for the administrative interface': 'hier klicken f?r die Administrationsoberfl?che ',
|
||||
'Click row to expand traceback': 'Klicke auf die Zeile f?r Fehlerverfolgung',
|
||||
'click to check for upgrades': 'hier klicken um nach Upgrades zu suchen',
|
||||
'Client IP': 'Client IP',
|
||||
'code': 'code',
|
||||
'collapse/expand all': 'collapse/expand all',
|
||||
'collapse/expand all': 'alles zu- bzw. aufklappen',
|
||||
'Compile': 'kompilieren',
|
||||
'compiled application removed': 'kompilierte Anwendung gelöscht',
|
||||
'compiled application removed': 'kompilierte Anwendung gel?scht',
|
||||
'Controller': 'Controller',
|
||||
'Controllers': 'Controller',
|
||||
'controllers': 'Controllers',
|
||||
'Copyright': 'Urheberrecht',
|
||||
'Count': 'Anzahl',
|
||||
'Create': 'erstellen',
|
||||
'create file with filename:': 'erzeuge Datei mit Dateinamen:',
|
||||
'create new application:': 'erzeuge neue Anwendung:',
|
||||
'Create new simple application': 'Erzeuge neue Anwendung',
|
||||
'created by': 'created by',
|
||||
'created by': 'erstellt von',
|
||||
'crontab': 'crontab',
|
||||
'Current request': 'Aktuelle Anfrage (request)',
|
||||
'Current response': 'Aktuelle Antwort (response)',
|
||||
'Current session': 'Aktuelle Sitzung (session)',
|
||||
'currently running': 'currently running',
|
||||
'currently running': 'aktuell in Betrieb',
|
||||
'currently saved or': 'des derzeit gespeicherten oder',
|
||||
'customize me!': 'pass mich an!',
|
||||
'data uploaded': 'Daten hochgeladen',
|
||||
'Database': 'Datenbank',
|
||||
'database': 'Datenbank',
|
||||
'database %s select': 'Datenbank %s ausgewählt',
|
||||
'database %s select': 'Datenbank %s ausgew?hlt',
|
||||
'database administration': 'Datenbankadministration',
|
||||
'Date and Time': 'Datum und Uhrzeit',
|
||||
'db': 'db',
|
||||
'DB Model': 'DB Modell',
|
||||
'Debug': 'Debug',
|
||||
'defines tables': 'definiere Tabellen',
|
||||
'Delete': 'Löschen',
|
||||
'delete': 'löschen',
|
||||
'delete all checked': 'lösche alle markierten',
|
||||
'delete plugin': 'Plugin löschen',
|
||||
'Delete:': 'Löschen:',
|
||||
'Deploy': 'deploy',
|
||||
'Delete': 'L?schen',
|
||||
'delete': 'l?schen',
|
||||
'delete all checked': 'l?sche alle markierten',
|
||||
'delete plugin': 'Plugin l?schen',
|
||||
'Delete:': 'L?schen:',
|
||||
'Deploy': 'Installieren',
|
||||
'Deploy on Google App Engine': 'Auf Google App Engine installieren',
|
||||
'Deploy to OpenShift': 'Deploy to OpenShift',
|
||||
'Deploy to OpenShift': 'Auf OpenShift installieren',
|
||||
'Description': 'Beschreibung',
|
||||
'design': 'design',
|
||||
'DESIGN': 'design',
|
||||
'Design for': 'Design für',
|
||||
'Design for': 'Design f?r',
|
||||
'Detailed traceback description': 'Detailed traceback description',
|
||||
'direction: ltr': 'direction: ltr',
|
||||
'Disable': 'Disable',
|
||||
'Disable': 'Deaktivieren',
|
||||
'documentation': 'Dokumentation',
|
||||
'done!': 'fertig!',
|
||||
'download layouts': 'download layouts',
|
||||
'Download .w2p': 'Download .w2p',
|
||||
'download layouts': 'Layouts herunterladen',
|
||||
'download plugins': 'download plugins',
|
||||
'E-mail': 'E-mail',
|
||||
'EDIT': 'BEARBEITEN',
|
||||
@@ -129,56 +136,64 @@
|
||||
'Editing file "%s"': 'Bearbeite Datei "%s"',
|
||||
'Editing Language file': 'Sprachdatei bearbeiten',
|
||||
'Enterprise Web Framework': 'Enterprise Web Framework',
|
||||
'Error logs for "%(app)s"': 'Fehlerprotokoll für "%(app)s"',
|
||||
'Error': 'Fehler',
|
||||
'Error logs for "%(app)s"': 'Fehlerprotokoll f?r "%(app)s"',
|
||||
'Error snapshot': 'Error snapshot',
|
||||
'Error ticket': 'Error ticket',
|
||||
'Errors': 'Fehler',
|
||||
'escape': 'escape',
|
||||
'Exception instance attributes': 'Atribute der Ausnahmeinstanz',
|
||||
'Expand Abbreviation': 'Kürzel erweitern',
|
||||
'Expand Abbreviation': 'K?rzel erweitern',
|
||||
'export as csv file': 'Exportieren als CSV-Datei',
|
||||
'exposes': 'stellt zur Verfügung',
|
||||
'exposes': 'stellt zur Verf?gung',
|
||||
'extends': 'erweitert',
|
||||
'failed to reload module': 'neu laden des Moduls fehlgeschlagen',
|
||||
'File': 'Datei',
|
||||
'file "%(filename)s" created': 'Datei "%(filename)s" erstellt',
|
||||
'file "%(filename)s" deleted': 'Datei "%(filename)s" gelöscht',
|
||||
'file "%(filename)s" deleted': 'Datei "%(filename)s" gel?scht',
|
||||
'file "%(filename)s" uploaded': 'Datei "%(filename)s" hochgeladen',
|
||||
'file "%(filename)s" was not deleted': 'Datei "%(filename)s" wurde nicht gelöscht',
|
||||
'file "%(filename)s" was not deleted': 'Datei "%(filename)s" wurde nicht gel?scht',
|
||||
'file "%s" of %s restored': 'Datei "%s" von %s wiederhergestellt',
|
||||
'file changed on disk': 'Datei auf Festplatte geändert',
|
||||
'file changed on disk': 'Datei auf Festplatte ge?ndert',
|
||||
'file does not exist': 'Datei existiert nicht',
|
||||
'file saved on %(time)s': 'Datei gespeichert am %(time)s',
|
||||
'file saved on %s': 'Datei gespeichert auf %s',
|
||||
'filter': 'filter',
|
||||
'First name': 'Vorname',
|
||||
'Frames': 'Frames',
|
||||
'Functions with no doctests will result in [passed] tests.': 'Funktionen ohne doctests erzeugen [passed] in Tests',
|
||||
'Get from URL:': 'Get from URL:',
|
||||
'Git Pull': 'Git Pull',
|
||||
'Git Push': 'Git Push',
|
||||
'Go to Matching Pair': 'gehe zum übereinstimmenden Paar',
|
||||
'Go to Matching Pair': 'gehe zum ?bereinstimmenden Paar',
|
||||
'Goto': 'Goto',
|
||||
'Group ID': 'Gruppen ID',
|
||||
'Hello World': 'Hallo Welt',
|
||||
'Help': 'Hilfe',
|
||||
'Home': 'Home',
|
||||
'htmledit': 'htmledit',
|
||||
'If the report above contains a ticket number it indicates a failure in executing the controller, before any attempt to execute the doctests. This is usually due to an indentation error or an error outside function code.\nA green title indicates that all tests (if defined) passed. In this case test results are not shown.': 'Falls der obere Test eine Fehler-Ticketnummer enthält deutet das auf einen Fehler in der Ausführung des Controllers hin, noch bevor der Doctest ausgeführt werden konnte. Gewöhnlich führen fehlerhafte Einrückungen oder fehlerhafter Code ausserhalb der Funktion zu solchen Fehlern. Ein grüner Titel deutet darauf hin, dass alle Test(wenn sie vorhanden sind) erfolgreich durchlaufen wurden. In diesem Fall werden die Testresultate nicht angezeigt.',
|
||||
'If the report above contains a ticket number it indicates a failure in executing the controller, before any attempt to execute the doctests. This is usually due to an indentation error or an error outside function code.\nA green title indicates that all tests (if defined) passed. In this case test results are not shown.': 'Falls der obere Test eine Fehler-Ticketnummer enth?lt deutet das auf einen Fehler in der Ausf?hrung des Controllers hin, noch bevor der Doctest ausgef?hrt werden konnte. Gew?hnlich f?hren fehlerhafte Einr?ckungen oder fehlerhafter Code ausserhalb der Funktion zu solchen Fehlern. Ein gr?ner Titel deutet darauf hin, dass alle Test(wenn sie vorhanden sind) erfolgreich durchlaufen wurden. In diesem Fall werden die Testresultate nicht angezeigt.',
|
||||
'If you answer "yes", be patient, it may take a while to download': '',
|
||||
'If you answer yes, be patient, it may take a while to download': 'If you answer yes, be patient, it may take a while to download',
|
||||
'Import/Export': 'Importieren/Exportieren',
|
||||
'includes': 'Einfügen',
|
||||
'includes': 'Einf?gen',
|
||||
'Index': 'Index',
|
||||
'index': 'index',
|
||||
'insert new': 'neu einfügen',
|
||||
'insert new %s': 'neu einfügen %s',
|
||||
'insert new': 'neu einf?gen',
|
||||
'insert new %s': 'neu einf?gen %s',
|
||||
'inspect attributes': 'inspect attributes',
|
||||
'Install': 'installieren',
|
||||
'Installed applications': 'Installierte Anwendungen',
|
||||
'internal error': 'interner Fehler',
|
||||
'Internal State': 'interner Status',
|
||||
'Invalid action': 'Ungültige Aktion',
|
||||
'Invalid email': 'Ungültige Email',
|
||||
'invalid password': 'Ungültiges Passwort',
|
||||
'Invalid Query': 'Ungültige Abfrage',
|
||||
'invalid request': 'ungültige Anfrage',
|
||||
'invalid ticket': 'ungültiges Ticket',
|
||||
'Invalid action': 'Ung?ltige Aktion',
|
||||
'Invalid email': 'Ung?ltige Email',
|
||||
'invalid password': 'Ung?ltiges Passwort',
|
||||
'Invalid Query': 'Ung?ltige Abfrage',
|
||||
'invalid request': 'ung?ltige Anfrage',
|
||||
'invalid ticket': 'ung?ltiges Ticket',
|
||||
'Key bindings': 'Tastenbelegungen',
|
||||
'Key bindings for ZenConding Plugin': 'Tastenbelegungen für das ZenConding Plugin',
|
||||
'Key bindings for ZenConding Plugin': 'Tastenbelegungen f?r das ZenConding Plugin',
|
||||
'language file "%(filename)s" created/updated': 'Sprachdatei "%(filename)s" erstellt/aktualisiert',
|
||||
'Language files (static strings) updated': 'Sprachdatei (statisch Strings) aktualisiert',
|
||||
'languages': 'Sprachen',
|
||||
@@ -187,8 +202,9 @@
|
||||
'Last name': 'Nachname',
|
||||
'Last saved on:': 'Zuletzt gespeichert am:',
|
||||
'Layout': 'Layout',
|
||||
'License for': 'Lizenz für',
|
||||
'License for': 'Lizenz f?r',
|
||||
'loading...': 'lade...',
|
||||
'locals': 'locals',
|
||||
'located in the file': 'located in Datei',
|
||||
'Login': 'Anmelden',
|
||||
'login': 'anmelden',
|
||||
@@ -196,33 +212,37 @@
|
||||
'Logout': 'abmelden',
|
||||
'Lost Password': 'Passwort vergessen',
|
||||
'lost password?': 'Passwort vergessen?',
|
||||
'Main Menu': 'Menú principal',
|
||||
'Main Menu': 'Men? principal',
|
||||
'Manage': 'Verwalten',
|
||||
'Match Pair': 'Paare finden',
|
||||
'Menu Model': 'Menü Modell',
|
||||
'Menu Model': 'Men? Modell',
|
||||
'merge': 'verbinden',
|
||||
'Merge Lines': 'Zeilen zusammenfügen',
|
||||
'Merge Lines': 'Zeilen zusammenf?gen',
|
||||
'Models': 'Modelle',
|
||||
'models': 'Modelle',
|
||||
'Modules': 'Module',
|
||||
'modules': 'Module',
|
||||
'Name': 'Name',
|
||||
'new application "%s" created': 'neue Anwendung "%s" erzeugt',
|
||||
'New application wizard': 'New application wizard',
|
||||
'New application wizard': 'Neue Anwendung per Assistent',
|
||||
'New Record': 'Neuer Datensatz',
|
||||
'new record inserted': 'neuer Datensatz eingefügt',
|
||||
'New simple application': 'New simple application',
|
||||
'next 100 rows': 'nächsten 100 Zeilen',
|
||||
'Next Edit Point': 'nächster Bearbeitungsschritt',
|
||||
'new record inserted': 'neuer Datensatz eingef?gt',
|
||||
'New simple application': 'Neue einfache Anwendung',
|
||||
'next 100 rows': 'n?chsten 100 Zeilen',
|
||||
'Next Edit Point': 'n?chster Bearbeitungsschritt',
|
||||
'NO': 'NEIN',
|
||||
'No databases in this application': 'Keine Datenbank in dieser Anwendung',
|
||||
'No ticket_storage.txt found under /private folder': 'No ticket_storage.txt found under /private folder',
|
||||
'Or Get from URL:': 'oder hole es von folgender URL:',
|
||||
'or import from csv file': 'oder importieren von cvs Datei',
|
||||
'or provide app url:': 'oder geben Sie eine Anwendungs-URL an:',
|
||||
'or provide application url:': 'oder geben Sie eine Anwendungs-URL an:',
|
||||
'Origin': 'Herkunft',
|
||||
'Original/Translation': 'Original/Übersetzung',
|
||||
'Overwrite installed app': 'installierte Anwendungen überschreiben',
|
||||
'Original/Translation': 'Original/?bersetzung',
|
||||
'Overwrite installed app': 'installierte Anwendungen ?berschreiben',
|
||||
'Pack all': 'verpacke alles',
|
||||
'Pack compiled': 'Verpacke kompiliert',
|
||||
'Pack custom': 'Verpacke individuell',
|
||||
'pack plugin': 'Plugin verpacken',
|
||||
'Password': 'Passwort',
|
||||
'Peeking at file': 'Dateiansicht',
|
||||
@@ -230,9 +250,10 @@
|
||||
'Plugin "%s" in application': 'Plugin "%s" in Anwendung',
|
||||
'plugins': 'plugins',
|
||||
'Plugins': 'Plugins',
|
||||
'Powered by': 'Unterstützt von',
|
||||
'Powered by': 'Unterst?tzt von',
|
||||
'previous 100 rows': 'vorherige 100 zeilen',
|
||||
'Previous Edit Point': 'vorheriger Bearbeitungsschritt',
|
||||
'Project Progress': 'Projekt Fortschritt',
|
||||
'Query:': 'Abfrage:',
|
||||
'record': 'Datensatz',
|
||||
'record does not exist': 'Datensatz existiert nicht',
|
||||
@@ -240,33 +261,38 @@
|
||||
'Record ID': 'Datensatz ID',
|
||||
'register': 'Registrierung',
|
||||
'Register': 'registrieren',
|
||||
'Registration key': 'Registrierungsschlüssel',
|
||||
'Reload routes': 'Reload routes',
|
||||
'Remove compiled': 'kompilat gelöscht',
|
||||
'Reset Password key': 'Passwortschlüssel zurücksetzen',
|
||||
'Registration key': 'Registrierungsschl?ssel',
|
||||
'reload': 'Neu laden',
|
||||
'Reload routes': 'Routen neu laden',
|
||||
'Remove compiled': 'Bytecode l?schen',
|
||||
'request': 'request',
|
||||
'Reset Password key': 'Passwortschl?ssel zur?cksetzen',
|
||||
'Resolve Conflict file': 'bereinige Konflikt-Datei',
|
||||
'response': 'Antwort',
|
||||
'restore': 'wiederherstellen',
|
||||
'revert': 'zurückkehren',
|
||||
'revert': 'zur?ckkehren',
|
||||
'Role': 'Rolle',
|
||||
'Rows in table': 'Zeilen in Tabelle',
|
||||
'Rows selected': 'Zeilen ausgewählt',
|
||||
'Running on %s': 'Running on %s',
|
||||
'Rows selected': 'Zeilen ausgew?hlt',
|
||||
'Running on %s': 'L?uft auf %s',
|
||||
'save': 'sichern',
|
||||
'Save via Ajax': 'via Ajax sichern',
|
||||
'Saved file hash:': 'Gespeicherter Datei-Hash:',
|
||||
'selected': 'ausgewählt(e)',
|
||||
'session expired': 'Sitzung Abgelaufen',
|
||||
'Select Files to Package': 'Dateien zum Paketieren w?hlen',
|
||||
'selected': 'ausgew?hlt(e)',
|
||||
'session': 'Sitzung',
|
||||
'session expired': 'Sitzung abgelaufen',
|
||||
'shell': 'shell',
|
||||
'Site': 'Seite',
|
||||
'some files could not be removed': 'einige Dateien konnten nicht gelöscht werden',
|
||||
'Start wizard': 'start wizard',
|
||||
'some files could not be removed': 'einige Dateien konnten nicht gel?scht werden',
|
||||
'Start wizard': 'Assistent starten',
|
||||
'state': 'Status',
|
||||
'static': 'statische Dateien',
|
||||
'Static files': 'statische Dateien',
|
||||
'Stylesheet': 'Stylesheet',
|
||||
'Submit': 'Submit',
|
||||
'submit': 'Absenden',
|
||||
'Sure you want to delete this object?': 'Wollen Sie das Objekt wirklich löschen?',
|
||||
'Sure you want to delete this object?': 'Wollen Sie das Objekt wirklich l?schen?',
|
||||
'table': 'Tabelle',
|
||||
'Table name': 'Tabellen Name',
|
||||
'test': 'Test',
|
||||
@@ -276,42 +302,45 @@
|
||||
'test_try': 'test_try',
|
||||
'Testing application': 'Teste die Anwendung',
|
||||
'Testing controller': 'teste Controller',
|
||||
'The "query" is a condition like "db.table1.field1==\'value\'". Something like "db.table1.field1==db.table2.field2" results in a SQL JOIN.': 'Die "query" ist eine Bedingung wie "db.table1.field1 == \'Wert\'". Etwas wie "db.table1.field1 db.table2.field2 ==" führt zu einem SQL JOIN.',
|
||||
'the application logic, each URL path is mapped in one exposed function in the controller': 'Die Logik der Anwendung, jeder URL-Pfad wird auf eine Funktion abgebildet die der Controller zur Verfügung stellt',
|
||||
'The "query" is a condition like "db.table1.field1==\'value\'". Something like "db.table1.field1==db.table2.field2" results in a SQL JOIN.': 'Die "query" ist eine Bedingung wie "db.table1.field1 == \'Wert\'". Etwas wie "db.table1.field1 db.table2.field2 ==" f?hrt zu einem SQL JOIN.',
|
||||
'the application logic, each URL path is mapped in one exposed function in the controller': 'Die Logik der Anwendung, jeder URL-Pfad wird auf eine Funktion abgebildet die der Controller zur Verf?gung stellt',
|
||||
'The application logic, each URL path is mapped in one exposed function in the controller': 'The application logic, each URL path is mapped in one exposed function in the controller',
|
||||
'the data representation, define database tables and sets': 'Die Datenrepräsentation definiert Mengen von Tabellen und Datenbanken ',
|
||||
'the data representation, define database tables and sets': 'Die Datenrepr?sentation definiert Mengen von Tabellen und Datenbanken ',
|
||||
'The data representation, define database tables and sets': 'The data representation, define database tables and sets',
|
||||
'The output of the file is a dictionary that was rendered by the view': 'The output of the file is a dictionary that was rendered by the view',
|
||||
'The presentations layer, views are also known as templates': 'The presentations layer, views are also known as templates',
|
||||
'the presentations layer, views are also known as templates': 'Die Präsentationsschicht, Views sind auch bekannt als Vorlagen/Templates',
|
||||
'the presentations layer, views are also known as templates': 'Die Pr?sentationsschicht, Views sind auch bekannt als Vorlagen/Templates',
|
||||
'There are no controllers': 'Keine Controller vorhanden',
|
||||
'There are no models': 'Keine Modelle vorhanden',
|
||||
'There are no modules': 'Keine Module vorhanden',
|
||||
'There are no plugins': 'There are no plugins',
|
||||
'There are no static files': 'Keine statischen Dateien vorhanden',
|
||||
'There are no translators, only default language is supported': 'Keine Übersetzungen vorhanden, nur die voreingestellte Sprache wird unterstützt',
|
||||
'There are no translators, only default language is supported': 'Keine ?bersetzungen vorhanden, nur die voreingestellte Sprache wird unterst?tzt',
|
||||
'There are no views': 'Keine Views vorhanden',
|
||||
'These files are served without processing, your images go here': 'These files are served without processing, your images go here',
|
||||
'these files are served without processing, your images go here': 'Diese Dateien werden ohne Verarbeitung ausgeliefert. Beispielsweise Bilder kommen hier hin.',
|
||||
'This is a copy of the scaffolding application': 'Dies ist eine Kopie einer Grundgerüst-Anwendung',
|
||||
'This is a copy of the scaffolding application': 'Dies ist eine Kopie einer Grundger?st-Anwendung',
|
||||
'This is the %(filename)s template': 'Dies ist das Template %(filename)s',
|
||||
'Ticket': 'Ticket',
|
||||
'Timestamp': 'Timestamp',
|
||||
'Ticket ID': 'Ticket ID',
|
||||
'Timestamp': 'Zeitstempel',
|
||||
'TM': 'TM',
|
||||
'to previous version.': 'zu einer früheren Version.',
|
||||
'to previous version.': 'zu einer fr?heren Version.',
|
||||
'To create a plugin, name a file/folder plugin_[name]': 'Um ein Plugin zu erstellen benennen Sie eine(n) Datei/Ordner plugin_[Name]',
|
||||
'translation strings for the application': 'Übersetzungs-Strings für die Anwendung',
|
||||
'Translation strings for the application': 'Translation strings for the application',
|
||||
'Traceback': 'Traceback',
|
||||
'translation strings for the application': '?bersetzungs-Strings f?r die Anwendung',
|
||||
'Translation strings for the application': '?bersetzungs-Strings f?r die Anwendung',
|
||||
'try': 'versuche',
|
||||
'try something like': 'versuche so etwas wie',
|
||||
'Unable to check for upgrades': 'überprüfen von Upgrades nicht möglich',
|
||||
'unable to create application "%s"': 'erzeugen von Anwendung "%s" nicht möglich',
|
||||
'unable to delete file "%(filename)s"': 'löschen von Datein "%(filename)s" nicht möglich',
|
||||
'Unable to download': 'herunterladen nicht möglich',
|
||||
'Unable to download app': 'herunterladen der Anwendung nicht möglich',
|
||||
'unable to parse csv file': 'analysieren der cvs Datei nicht möglich',
|
||||
'unable to uninstall "%s"': 'deinstallieren von "%s" nicht möglich',
|
||||
'uncheck all': 'alles demarkieren',
|
||||
'Try the mobile interface': 'Try the mobile interface',
|
||||
'Unable to check for upgrades': '?berpr?fen von Upgrades nicht m?glich',
|
||||
'unable to create application "%s"': 'erzeugen von Anwendung "%s" nicht m?glich',
|
||||
'unable to delete file "%(filename)s"': 'l?schen von Datein "%(filename)s" nicht m?glich',
|
||||
'Unable to download': 'herunterladen nicht m?glich',
|
||||
'Unable to download app': 'herunterladen der Anwendung nicht m?glich',
|
||||
'unable to parse csv file': 'analysieren der cvs Datei nicht m?glich',
|
||||
'unable to uninstall "%s"': 'deinstallieren von "%s" nicht m?glich',
|
||||
'uncheck all': 'Selektionen entfernen',
|
||||
'Uninstall': 'deinstallieren',
|
||||
'update': 'aktualisieren',
|
||||
'update all languages': 'aktualisiere alle Sprachen',
|
||||
@@ -319,33 +348,35 @@
|
||||
'upgrade web2py now': 'jetzt web2py upgraden',
|
||||
'upload': 'upload',
|
||||
'Upload & install packed application': 'Verpackte Anwendung hochladen und installieren',
|
||||
'Upload a package:': 'Upload a package:',
|
||||
'Upload and install packed application': 'Upload and install packed application',
|
||||
'Upload a package:': 'Ein Packet hochladen:',
|
||||
'Upload and install packed application': 'Verpackte Anwendung hochladen und installieren',
|
||||
'upload application:': 'lade Anwendung hoch:',
|
||||
'Upload existing application': 'lade existierende Anwendung hoch',
|
||||
'upload file:': 'lade Datei hoch:',
|
||||
'upload plugin file:': 'Plugin-Datei hochladen:',
|
||||
'Use (...)&(...) for AND, (...)|(...) for OR, and ~(...) for NOT to build more complex queries.': 'Benutze (...)&(...) für AND, (...)|(...) für OR, und ~(...) für NOT, um komplexe Abfragen zu erstellen.',
|
||||
'Use an url:': 'Use an url:',
|
||||
'user': 'user',
|
||||
'Use (...)&(...) for AND, (...)|(...) for OR, and ~(...) for NOT to build more complex queries.': 'Benutze (...)&(...) f?r AND, (...)|(...) f?r OR, und ~(...) f?r NOT, um komplexe Abfragen zu erstellen.',
|
||||
'Use an url:': 'Verwende URL:',
|
||||
'user': 'Nutzer',
|
||||
'User ID': 'Benutzer ID',
|
||||
'variables': 'variables',
|
||||
'variables': 'Variablen',
|
||||
'Version': 'Version',
|
||||
'Version %s.%s.%s (%s) %s': 'Version %s.%s.%s (%s) %s',
|
||||
'versioning': 'Versionierung',
|
||||
'View': 'View',
|
||||
'view': 'View',
|
||||
'Views': 'Views',
|
||||
'views': 'Views',
|
||||
'Versioning': 'Versionierung',
|
||||
'View': 'Ansicht',
|
||||
'view': 'Ansicht',
|
||||
'Views': 'Ansichten',
|
||||
'views': 'Ansichten',
|
||||
'Web Framework': 'Web Framework',
|
||||
'web2py is up to date': 'web2py ist auf dem neuesten Stand',
|
||||
'web2py Recent Tweets': 'neuste Tweets von web2py',
|
||||
'Welcome %s': 'Willkommen %s',
|
||||
'Welcome to web2py': 'Willkommen zu web2py',
|
||||
'Which called the function': 'Which called the function',
|
||||
'Wrap with Abbreviation': 'mit Kürzel einhüllen',
|
||||
'Which called the function': 'welche die Funktion aufrief',
|
||||
'Wrap with Abbreviation': 'mit K?rzel einh?llen',
|
||||
'xml': 'xml',
|
||||
'YES': 'JA',
|
||||
'You are successfully running web2py': 'web2by wird erfolgreich ausgeführt',
|
||||
'You can modify this application and adapt it to your needs': 'Sie können diese Anwendung verändern und Ihren Bedürfnissen anpassen',
|
||||
'You are successfully running web2py': 'web2by wird erfolgreich ausgef?hrt',
|
||||
'You can modify this application and adapt it to your needs': 'Sie k?nnen diese Anwendung ver?ndern und Ihren Bed?rfnissen anpassen',
|
||||
'You visited the url': 'Sie besuchten die URL',
|
||||
}
|
||||
|
||||
@@ -5,11 +5,11 @@
|
||||
'"update" is an optional expression like "field1=\'newvalue\'". You cannot update or delete the results of a JOIN': '"update" est une expression en option tels que "field1 = \'newvalue\'". Vous ne pouvez pas mettre à jour ou supprimer les résultats d\'une jointure "a JOIN"',
|
||||
'%Y-%m-%d': '%d-%m-%Y',
|
||||
'%Y-%m-%d %H:%M:%S': '%d-%m-%Y %H:%M:%S',
|
||||
'%s %%{row} deleted': 'lignes %s supprimé',
|
||||
'%s %%{row} updated': 'lignes %s mis à jour',
|
||||
'(requires internet access)': '(requires internet access)',
|
||||
'%s %%{row} deleted': 'lignes %s supprimées',
|
||||
'%s %%{row} updated': 'lignes %s mises à jour',
|
||||
'(requires internet access)': '(nécessite un accès Internet)',
|
||||
'(something like "it-it")': '(quelque chose comme "it-it") ',
|
||||
'@markmin\x01Searching: **%s** %%{file}': 'Searching: **%s** files',
|
||||
'@markmin\x01Searching: **%s** %%{file}': 'Cherche: **%s** fichiers',
|
||||
'A new version of web2py is available: %s': 'Une nouvelle version de web2py est disponible: %s ',
|
||||
'A new version of web2py is available: Version 1.68.2 (2009-10-21 09:59:29)\n': 'Une nouvelle version de web2py est disponible: Version 1.68.2 (2009-10-21 09:59:29)\r\n',
|
||||
'ATTENTION: Login requires a secure (HTTPS) connection or running on localhost.': 'ATTENTION: nécessite une connexion sécurisée (HTTPS) ou être en localhost. ',
|
||||
@@ -17,59 +17,59 @@
|
||||
'ATTENTION: you cannot edit the running application!': "ATTENTION: vous ne pouvez pas modifier l'application qui tourne!",
|
||||
'About': 'à propos',
|
||||
'About application': "A propos de l'application",
|
||||
'Additional code for your application': 'Additional code for your application',
|
||||
'Additional code for your application': 'Code additionnel pour votre application',
|
||||
'Admin is disabled because insecure channel': 'Admin est désactivé parce que canal non sécurisé',
|
||||
'Admin language': 'Admin language',
|
||||
'Admin language': "Language de l'admin",
|
||||
'Administrator Password:': 'Mot de passe Administrateur:',
|
||||
'Application name:': 'Application name:',
|
||||
'Are you sure you want to delete file "%s"?': 'Etes-vous sûr de vouloir supprimer le fichier «%s»?',
|
||||
'Are you sure you want to delete plugin "%s"?': 'Etes-vous sûr de vouloir effacer le plugin "%s"?',
|
||||
'Are you sure you want to delete this object?': 'Are you sure you want to delete this object?',
|
||||
'Application name:': "Nom de l'application:",
|
||||
'Are you sure you want to delete file "%s"?': 'Êtes-vous sûr de vouloir supprimer le fichier «%s»?',
|
||||
'Are you sure you want to delete plugin "%s"?': 'Êtes-vous sûr de vouloir supprimer le plugin "%s"?',
|
||||
'Are you sure you want to delete this object?': 'Êtes-vous sûr de vouloir supprimer cet objet?',
|
||||
'Are you sure you want to uninstall application "%s"?': "Êtes-vous sûr de vouloir désinstaller l'application «%s»?",
|
||||
'Are you sure you want to upgrade web2py now?': 'Are you sure you want to upgrade web2py now?',
|
||||
'Are you sure you want to upgrade web2py now?': 'Êtes-vous sûr de vouloir mettre à jour web2py maintenant?',
|
||||
'Available databases and tables': 'Bases de données et tables disponible',
|
||||
'Cannot be empty': 'Ne peut pas être vide',
|
||||
'Cannot compile: there are errors in your app. Debug it, correct errors and try again.': 'Ne peut pas compiler: il y a des erreurs dans votre application. corriger les erreurs et essayez à nouveau.',
|
||||
'Cannot compile: there are errors in your app:': 'Cannot compile: there are errors in your app:',
|
||||
'Change admin password': 'change admin password',
|
||||
'Check for upgrades': 'check for upgrades',
|
||||
'Cannot compile: there are errors in your app:': 'Ne peut pas compiler: il y a des erreurs dans votre application:',
|
||||
'Change admin password': 'Changer le mot de passe admin',
|
||||
'Check for upgrades': 'Vérifier les mises à jour',
|
||||
'Check to delete': 'Cocher pour supprimer',
|
||||
'Checking for upgrades...': 'Vérification des mises à jour ... ',
|
||||
'Clean': 'nettoyer',
|
||||
'Compile': 'compiler',
|
||||
'Controllers': 'Contrôleurs',
|
||||
'Create': 'create',
|
||||
'Create': 'Créer',
|
||||
'Create new simple application': 'Créer une nouvelle application',
|
||||
'Current request': 'Requête actuel',
|
||||
'Current request': 'Requête actuelle',
|
||||
'Current response': 'Réponse actuelle',
|
||||
'Current session': 'Session en cours',
|
||||
'Date and Time': 'Date et heure',
|
||||
'Delete': 'Supprimer',
|
||||
'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)': 'Supprimer ce fichier (on vous demandera de confirmer la suppression)',
|
||||
'Delete:': 'Supprimer:',
|
||||
'Deploy': 'deploy',
|
||||
'Deploy': 'Déployer',
|
||||
'Deploy on Google App Engine': 'Déployer sur Google App Engine',
|
||||
'EDIT': 'MODIFIER',
|
||||
'Edit': 'modifier',
|
||||
'Edit application': "Modifier l'application",
|
||||
'Edit current record': 'Modifier cet entrée',
|
||||
'Edit current record': 'Modifier cette entrée',
|
||||
'Editing Language file': 'Modifier le fichier de langue',
|
||||
'Editing file': 'Modifier le fichier',
|
||||
'Editing file "%s"': 'Modifier le fichier "% s" ',
|
||||
'Enterprise Web Framework': 'Enterprise Web Framework',
|
||||
'Error logs for "%(app)s"': 'Journal d\'erreurs pour "%(app)s"',
|
||||
'Errors': 'erreurs',
|
||||
'Exception instance attributes': 'Exception instance attributes',
|
||||
'Functions with no doctests will result in [passed] tests.': 'Des fonctions sans doctests entraînera tests [passed] .',
|
||||
'Exception instance attributes': "Attributs d'instance Exception",
|
||||
'Functions with no doctests will result in [passed] tests.': 'Des fonctions sans doctests entraîneront des tests [passed] .',
|
||||
'Help': 'aide',
|
||||
'If the report above contains a ticket number it indicates a failure in executing the controller, before any attempt to execute the doctests. This is usually due to an indentation error or an error outside function code.\nA green title indicates that all tests (if defined) passed. In this case test results are not shown.': "Si le rapport ci-dessus contient un numéro de ticket, cela indique une défaillance dans l'exécution du contrôleur, avant toute tentative d'exécuter les doctests. Cela est généralement dû à une erreur d'indentation ou une erreur à l'extérieur du code de la fonction.\r\nUn titre verte indique que tous les tests (si définie) passed. Dans ce cas, les résultats des essais ne sont pas affichées.",
|
||||
'If the report above contains a ticket number it indicates a failure in executing the controller, before any attempt to execute the doctests. This is usually due to an indentation error or an error outside function code.\nA green title indicates that all tests (if defined) passed. In this case test results are not shown.': "Si le rapport ci-dessus contient un numéro de ticket, cela indique une défaillance dans l'exécution du contrôleur, avant toute tentative d'exécuter les doctests. Cela est généralement dû à une erreur d'indentation ou une erreur à l'extérieur du code de la fonction.\r\nUn titre vert indique que tous les tests (si définis) sont passés. Dans ce cas, les résultats des essais ne sont pas affichées.",
|
||||
'Import/Export': 'Importer/Exporter',
|
||||
'Install': 'install',
|
||||
'Installed applications': 'Les applications installées',
|
||||
'Install': 'Installer',
|
||||
'Installed applications': 'Applications installées',
|
||||
'Internal State': 'État Interne',
|
||||
'Invalid Query': 'Requête non valide',
|
||||
'Invalid action': 'Action non valide',
|
||||
'Language files (static strings) updated': 'Fichiers de langue (static strings) Mise à jour ',
|
||||
'Language files (static strings) updated': 'Fichiers de langue (chaînes statiques) mis à jour ',
|
||||
'Languages': 'Langues',
|
||||
'Last saved on:': 'Dernière sauvegarde le:',
|
||||
'License for': 'Licence pour',
|
||||
@@ -79,13 +79,13 @@
|
||||
'Models': 'Modèles',
|
||||
'Modules': 'Modules',
|
||||
'NO': 'NON',
|
||||
'New Record': 'Nouvel Entrée',
|
||||
'New application wizard': 'New application wizard',
|
||||
'New simple application': 'New simple application',
|
||||
'New Record': 'Nouvelle Entrée',
|
||||
'New application wizard': 'Assistant nouvelle application',
|
||||
'New simple application': 'Nouvelle application simple',
|
||||
'No databases in this application': 'Aucune base de données dans cette application',
|
||||
'Original/Translation': 'Original / Traduction',
|
||||
'Overwrite installed app': 'overwrite installed app',
|
||||
'PAM authenticated user, cannot change password here': 'PAM authenticated user, cannot change password here',
|
||||
'Overwrite installed app': "Écraser l'application installée",
|
||||
'PAM authenticated user, cannot change password here': 'Utilisateur authentifié par PAM, vous ne pouvez pas changer le mot de passe ici',
|
||||
'Pack all': 'tout empaqueter',
|
||||
'Pack compiled': 'paquet compilé',
|
||||
'Peeking at file': 'Jeter un oeil au fichier',
|
||||
@@ -97,101 +97,101 @@
|
||||
'Resolve Conflict file': 'Résoudre les conflits de fichiers',
|
||||
'Rows in table': 'Lignes de la table',
|
||||
'Rows selected': 'Lignes sélectionnées',
|
||||
"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')",
|
||||
'Save': 'Save',
|
||||
"Run tests in this file (to run all files, you may also use the button labelled 'test')": "Lancer les tests dans ce fichier (pour lancer tous les fichiers, vous pouvez également utiliser le bouton nommé 'test')",
|
||||
'Save': 'Enregistrer',
|
||||
'Saved file hash:': 'Hash du Fichier enregistré:',
|
||||
'Site': 'site',
|
||||
'Start wizard': 'start wizard',
|
||||
'Site': 'Site',
|
||||
'Start wizard': "Démarrer l'assistant",
|
||||
'Static files': 'Fichiers statiques',
|
||||
'Sure you want to delete this object?': 'Vous êtes sûr de vouloir supprimer cet objet? ',
|
||||
'TM': 'MD',
|
||||
'Testing application': "Test de l'application",
|
||||
'The "query" is a condition like "db.table1.field1==\'value\'". Something like "db.table1.field1==db.table2.field2" results in a SQL JOIN.': 'La "requête" est une condition comme "db.table1.field1==\'value\'". Quelque chose comme "db.table1.field1==db.table2.field2" aboutit à un JOIN SQL.',
|
||||
'The application logic, each URL path is mapped in one exposed function in the controller': 'The application logic, each URL path is mapped in one exposed function in the controller',
|
||||
'The data representation, define database tables and sets': 'The data representation, define database tables and sets',
|
||||
'The presentations layer, views are also known as templates': 'The presentations layer, views are also known as templates',
|
||||
'There are no controllers': "Il n'existe pas de contrôleurs",
|
||||
'There are no models': "Il n'existe pas de modèles",
|
||||
'There are no modules': "Il n'existe pas de modules",
|
||||
'There are no plugins': 'There are no plugins',
|
||||
'There are no static files': "Il n'existe pas de fichiers statiques",
|
||||
'There are no translators, only default language is supported': "Il n'y a pas de traducteurs, est prise en charge uniquement la langue par défaut",
|
||||
'There are no views': "Il n'existe pas de vues",
|
||||
'These files are served without processing, your images go here': 'These files are served without processing, your images go here',
|
||||
'The application logic, each URL path is mapped in one exposed function in the controller': "La logique de l'application, chaque chemin d'URL est mappé avec une fonction exposée dans le contrôleur",
|
||||
'The data representation, define database tables and sets': 'La représentation des données, définir les tables et ensembles de la base de données',
|
||||
'The presentations layer, views are also known as templates': "Les couches de présentation, les vues sont également appelées modples",
|
||||
'There are no controllers': "Il n'y a pas de contrôleurs",
|
||||
'There are no models': "Il n'y a pas de modèles",
|
||||
'There are no modules': "Il n'y a pas de modules",
|
||||
'There are no plugins': "Il n'y a pas de plugins",
|
||||
'There are no static files': "Il n'y a pas de fichiers statiques",
|
||||
'There are no translators, only default language is supported': "Il n'y a pas de traducteurs, seule la langue par défaut est prise en charge",
|
||||
'There are no views': "Il n'y a pas de vues",
|
||||
'These files are served without processing, your images go here': 'Ces fichiers sont renvoyés sans traitement, vos images viennent ici',
|
||||
'This is the %(filename)s template': 'Ceci est le modèle %(filename)s ',
|
||||
'Ticket': 'Ticket',
|
||||
'To create a plugin, name a file/folder plugin_[name]': 'Pour créer un plugin, créer un fichier /dossier plugin_[nom]',
|
||||
'Translation strings for the application': 'Translation strings for the application',
|
||||
'Unable to check for upgrades': 'Impossible de vérifier les mises à niveau',
|
||||
'Translation strings for the application': "Chaînes de traduction pour l'application",
|
||||
'Unable to check for upgrades': 'Impossible de vérifier les mises à jour',
|
||||
'Unable to download': 'Impossible de télécharger',
|
||||
'Unable to download app': 'Impossible de télécharger app',
|
||||
'Unable to download app because:': 'Unable to download app because:',
|
||||
'Unable to download because': 'Unable to download because',
|
||||
'Unable to download app': "Impossible de télécharger l'app",
|
||||
'Unable to download app because:': "Impossible de télécharger l'app car:",
|
||||
'Unable to download because': 'Impossible de télécharger car',
|
||||
'Uninstall': 'désinstaller',
|
||||
'Update:': 'Mise à jour:',
|
||||
'Upload & install packed application': 'Upload & install packed application',
|
||||
'Upload a package:': 'Upload a package:',
|
||||
'Upload existing application': 'charger une application existante',
|
||||
'Use (...)&(...) for AND, (...)|(...) for OR, and ~(...) for NOT to build more complex queries.': 'Utilisez (...)&(...) pour AND, (...)|(...) pour OR, et ~(...) pour NOT et construire des requêtes plus complexes. ',
|
||||
'Use an url:': 'Use an url:',
|
||||
'Upload & install packed application': "Charger & installer l'application empaquetée",
|
||||
'Upload a package:': 'Charger un paquet:',
|
||||
'Upload existing application': 'Charger une application existante',
|
||||
'Use (...)&(...) for AND, (...)|(...) for OR, and ~(...) for NOT to build more complex queries.': 'Utilisez (...)&(...) pour AND, (...)|(...) pour OR, et ~(...) pour NOT afin de construire des requêtes plus complexes. ',
|
||||
'Use an url:': 'Utiliser une url:',
|
||||
'Version': 'Version',
|
||||
'Views': 'Vues',
|
||||
'Web Framework': 'Web Framework',
|
||||
'Web Framework': 'Framework Web',
|
||||
'YES': 'OUI',
|
||||
'additional code for your application': 'code supplémentaire pour votre application',
|
||||
'admin disabled because no admin password': 'admin désactivé car aucun mot de passe admin',
|
||||
'admin disabled because not supported on google app engine': 'admin désactivé car non pris en charge sur Google Apps engine',
|
||||
'admin disabled because unable to access password file': "admin désactivé car incapable d'accéder au fichier mot de passe",
|
||||
'administrative interface': 'administrative interface',
|
||||
'admin disabled because no admin password': 'admin désactivée car aucun mot de passe admin',
|
||||
'admin disabled because not supported on google app engine': 'admin désactivée car non prise en charge sur Google Apps engine',
|
||||
'admin disabled because unable to access password file': "admin désactivée car incapable d'accéder au fichier mot de passe",
|
||||
'administrative interface': "interface d'administration",
|
||||
'and rename it (required):': 'et renommez-la (obligatoire):',
|
||||
'and rename it:': 'et renommez-le:',
|
||||
'appadmin': 'appadmin',
|
||||
'appadmin is disabled because insecure channel': 'appadmin est désactivé parce que canal non sécurisé',
|
||||
'application "%s" uninstalled': 'application "%s" désinstallé',
|
||||
'application %(appname)s installed with md5sum: %(digest)s': 'application %(appname)s installed with md5sum: %(digest)s',
|
||||
'application "%s" uninstalled': 'application "%s" désinstallée',
|
||||
'application %(appname)s installed with md5sum: %(digest)s': 'application %(appname)s installée avec md5sum: %(digest)s',
|
||||
'application compiled': 'application compilée',
|
||||
'application is compiled and cannot be designed': "l'application est compilée et ne peut être désigné",
|
||||
'application is compiled and cannot be designed': "l'application est compilée et ne peut être modifiée",
|
||||
'arguments': 'arguments',
|
||||
'back': 'retour',
|
||||
'cache': 'cache',
|
||||
'cache, errors and sessions cleaned': 'cache, erreurs et sessions nettoyé',
|
||||
'cannot create file': 'ne peu pas créer de fichier',
|
||||
'cannot upload file "%(filename)s"': 'ne peu pas charger le fichier "%(filename)s"',
|
||||
'check all': 'tous vérifier ',
|
||||
'click to check for upgrades': 'Cliquez pour vérifier les mises à niveau',
|
||||
'cache, errors and sessions cleaned': 'cache, erreurs et sessions nettoyés',
|
||||
'cannot create file': 'ne peut pas créer de fichier',
|
||||
'cannot upload file "%(filename)s"': 'ne peut pas charger le fichier "%(filename)s"',
|
||||
'check all': 'tout vérifier ',
|
||||
'click to check for upgrades': 'Cliquez pour vérifier les mises jour',
|
||||
'code': 'code',
|
||||
'collapse/expand all': 'collapse/expand all',
|
||||
'compiled application removed': 'application compilée enlevé',
|
||||
'collapse/expand all': 'tout réduire/agrandir',
|
||||
'compiled application removed': 'application compilée enlevée',
|
||||
'controllers': 'contrôleurs',
|
||||
'create file with filename:': 'créer un fichier avec nom de fichier:',
|
||||
'create new application:': 'créer une nouvelle application:',
|
||||
'created by': 'créé par',
|
||||
'crontab': 'crontab',
|
||||
'currently running': 'currently running',
|
||||
'currently saved or': 'actuellement enregistrés ou',
|
||||
'currently running': 'tourne actuellement',
|
||||
'currently saved or': 'actuellement enregistré ou',
|
||||
'data uploaded': 'données chargées',
|
||||
'database': 'base de données',
|
||||
'database %s select': 'base de données %s sélectionner',
|
||||
'database administration': 'administration base de données',
|
||||
'db': 'db',
|
||||
'db': 'bdd',
|
||||
'defines tables': 'définit les tables',
|
||||
'delete': 'supprimer',
|
||||
'delete all checked': 'supprimer tout ce qui est cocher',
|
||||
'delete plugin': ' supprimer plugin',
|
||||
'delete all checked': 'supprimer tout ce qui est coché',
|
||||
'delete plugin': ' supprimer le plugin',
|
||||
'design': 'conception',
|
||||
'direction: ltr': 'direction: ltr',
|
||||
'docs': 'docs',
|
||||
'done!': 'fait!',
|
||||
'download layouts': 'download layouts',
|
||||
'download plugins': 'download plugins',
|
||||
'download layouts': 'télécharger layouts',
|
||||
'download plugins': 'télécharger plugins',
|
||||
'edit controller': 'modifier contrôleur',
|
||||
'edit views:': 'edit views:',
|
||||
'export as csv file': 'exportation au format CSV',
|
||||
'edit views:': 'modifier vues:',
|
||||
'export as csv file': 'export au format CSV',
|
||||
'exposes': 'expose',
|
||||
'exposes:': 'exposes:',
|
||||
'exposes:': 'expose:',
|
||||
'extends': 'étend',
|
||||
'failed to reload module': 'impossible de recharger le module',
|
||||
'failed to reload module because:': 'failed to reload module because:',
|
||||
'failed to reload module because:': 'impossible de recharger le module car:',
|
||||
'file "%(filename)s" created': 'fichier "%(filename)s" créé',
|
||||
'file "%(filename)s" deleted': 'fichier "%(filename)s" supprimé',
|
||||
'file "%(filename)s" uploaded': 'fichier "%(filename)s" chargé',
|
||||
@@ -200,7 +200,7 @@
|
||||
'file does not exist': "fichier n'existe pas",
|
||||
'file saved on %(time)s': 'fichier enregistré le %(time)s',
|
||||
'file saved on %s': 'fichier enregistré le %s',
|
||||
'filter': 'filter',
|
||||
'filter': 'filtre',
|
||||
'htmledit': 'edition html',
|
||||
'includes': 'inclus',
|
||||
'index': 'index',
|
||||
@@ -219,14 +219,14 @@
|
||||
'modules': 'modules',
|
||||
'new application "%s" created': 'nouvelle application "%s" créée',
|
||||
'new plugin installed': 'nouveau plugin installé',
|
||||
'new record inserted': 'nouvelle entrée inséré',
|
||||
'new record inserted': 'nouvelle entrée insérée',
|
||||
'next 100 rows': '100 lignes suivantes',
|
||||
'no match': 'no match',
|
||||
'no match': 'aucune correspondance',
|
||||
'or import from csv file': 'ou importer depuis un fichier CSV ',
|
||||
'or provide app url:': 'or provide app url:',
|
||||
'or provide app url:': "ou fournir l'URL de l'app:",
|
||||
'or provide application url:': "ou fournir l'URL de l'application:",
|
||||
'pack plugin': 'paquet plugin',
|
||||
'password changed': 'password changed',
|
||||
'password changed': 'mot de passe modifié',
|
||||
'plugin "%(plugin)s" deleted': 'plugin "%(plugin)s" supprimé',
|
||||
'plugins': 'plugins',
|
||||
'previous 100 rows': '100 lignes précédentes',
|
||||
@@ -245,9 +245,9 @@
|
||||
'submit': 'envoyer',
|
||||
'table': 'table',
|
||||
'test': 'tester',
|
||||
'the application logic, each URL path is mapped in one exposed function in the controller': "la logique de l'application, chaque route URL est mappé dans une fonction exposée dans le contrôleur",
|
||||
'the data representation, define database tables and sets': 'la représentation des données, défini les tables de bases de données et sets',
|
||||
'the presentations layer, views are also known as templates': 'la couche des présentations, les vues sont également connus en tant que modèles',
|
||||
'the application logic, each URL path is mapped in one exposed function in the controller': "la logique de l'application, chaque chemin d'URL est mappé dans une fonction exposée dans le contrôleur",
|
||||
'the data representation, define database tables and sets': 'La représentation des données, définir les tables et ensembles de la base de données',
|
||||
'the presentations layer, views are also known as templates': 'la couche de présentation, les vues sont également appelées modèles',
|
||||
'these files are served without processing, your images go here': 'ces fichiers sont servis sans transformation, vos images vont ici',
|
||||
'to previous version.': 'à la version précédente.',
|
||||
'translation strings for the application': "chaînes de traduction de l'application",
|
||||
@@ -258,22 +258,22 @@
|
||||
'unable to delete file plugin "%(plugin)s"': 'impossible de supprimer le plugin "%(plugin)s"',
|
||||
'unable to parse csv file': "impossible d'analyser les fichiers CSV",
|
||||
'unable to uninstall "%s"': 'impossible de désinstaller "%s"',
|
||||
'unable to upgrade because "%s"': 'unable to upgrade because "%s"',
|
||||
'unable to upgrade because "%s"': 'impossible de mettre à jour car "%s"',
|
||||
'uncheck all': 'tout décocher',
|
||||
'update': 'mettre à jour',
|
||||
'update all languages': 'mettre à jour toutes les langues',
|
||||
'upgrade now': 'upgrade now',
|
||||
'upgrade web2py now': 'upgrade web2py now',
|
||||
'upload': 'upload',
|
||||
'upgrade now': 'mettre à jour maintenant',
|
||||
'upgrade web2py now': 'mettre à jour web2py maintenant',
|
||||
'upload': 'charger',
|
||||
'upload application:': "charger l'application:",
|
||||
'upload file:': 'charger le fichier:',
|
||||
'upload plugin file:': 'charger fichier plugin:',
|
||||
'user': 'user',
|
||||
'user': 'utilisateur',
|
||||
'variables': 'variables',
|
||||
'versioning': 'versioning',
|
||||
'view': 'vue',
|
||||
'views': 'vues',
|
||||
'web2py Recent Tweets': 'web2py Tweets récentes',
|
||||
'web2py Recent Tweets': 'Tweets récents sur web2py ',
|
||||
'web2py is up to date': 'web2py est à jour',
|
||||
'web2py upgraded; please restart it': 'web2py upgraded; please restart it',
|
||||
'web2py upgraded; please restart it': 'web2py mis à jour; veuillez le redémarrer',
|
||||
}
|
||||
|
||||
@@ -92,7 +92,7 @@ div.flash {
|
||||
position:fixed;
|
||||
padding:10px;
|
||||
top:48px;
|
||||
right:50px;
|
||||
right:250px;
|
||||
min-width:280px;
|
||||
opacity:0.95;
|
||||
margin:0px 0px 10px 10px;
|
||||
@@ -191,6 +191,7 @@ div.error {
|
||||
.web2py_grid {width:100%}
|
||||
.web2py_grid table {width:100%}
|
||||
.web2py_grid tbody td {padding:2px 5px 2px 5px; vertical-align: middle;}
|
||||
.web2py_grid .web2py_form td {vertical-align: top;}
|
||||
|
||||
.web2py_grid thead th,.web2py_grid tfoot td {
|
||||
background-color:#EAEAEA;
|
||||
|
||||
@@ -102,6 +102,7 @@ td.w2p_fl,td.w2p_fc {padding:0;}
|
||||
==============================================================*/
|
||||
|
||||
/* because web2py handles this via js */
|
||||
textarea { width:90%}
|
||||
.hidden{visibility:visible;}
|
||||
/* right folder for bootstrap black images/icons */
|
||||
[class^="icon-"],[class*=" icon-"]{
|
||||
|
||||
+6
-2
File diff suppressed because one or more lines are too long
@@ -35,6 +35,7 @@ function web2py_ajax_init(target) {
|
||||
jQuery('.hidden', target).hide();
|
||||
jQuery('.error', target).hide().slideDown('slow');
|
||||
web2py_ajax_fields(target);
|
||||
web2py_show_if(target);
|
||||
};
|
||||
|
||||
function web2py_event_handlers() {
|
||||
@@ -216,3 +217,26 @@ function web2py_validate_entropy(myfield, req_entropy) {
|
||||
if(!myfield.hasClass('entropy_check')) myfield.on('keyup', validator).on('keydown', validator).addClass('entropy_check');
|
||||
}
|
||||
|
||||
function web2py_show_if(target) {
|
||||
var triggers = {};
|
||||
var show_if = function () {
|
||||
var t = jQuery(this);
|
||||
var id = t.attr('id');
|
||||
t.attr('value', t.val());
|
||||
for(var k = 0; k < triggers[id].length; k++) {
|
||||
var dep = jQuery('#' + triggers[id][k], target);
|
||||
var tr = jQuery('#' + triggers[id][k] + '__row', target);
|
||||
if(t.is(dep.attr('data-show-if'))) tr.slideDown();
|
||||
else tr.hide();
|
||||
}
|
||||
};
|
||||
jQuery('[data-show-trigger]', target).each(function () {
|
||||
var name = jQuery(this).attr('data-show-trigger');
|
||||
if(!triggers[name]) triggers[name] = [];
|
||||
triggers[name].push(jQuery(this).attr('id'));
|
||||
});
|
||||
for(var name in triggers) {
|
||||
jQuery('#' + name, target).change(show_if).keyup(show_if);
|
||||
show_if.call(jQuery('#' + name, target));
|
||||
};
|
||||
}
|
||||
@@ -8,21 +8,28 @@ jQuery(function(){
|
||||
if(jQuery(this).find('ul').length)
|
||||
jQuery(this).addClass('dropdown-submenu');
|
||||
});
|
||||
function adjust_height_of_collapsed_nav() {
|
||||
var cn = jQuery('div.collapse');
|
||||
if (cn.get(0)) {
|
||||
var cnh = cn.get(0).style.height;
|
||||
if (cnh>'0px'){
|
||||
cn.css('height','auto');
|
||||
}
|
||||
}
|
||||
}
|
||||
function hoverMenu(){
|
||||
var wid = document.documentElement.clientWidth; //faster than $(window).width() and cross browser
|
||||
if (wid>=980){
|
||||
jQuery('ul.nav a.dropdown-toggle').parent().hover(function(){
|
||||
mi = jQuery(this).addClass('open');
|
||||
mi.children('.dropdown-menu').stop(true, true).delay(200).fadeIn(400);
|
||||
}, function(){
|
||||
mi = jQuery(this);
|
||||
mi.children('.dropdown-menu').stop(true, true).delay(200).fadeOut(function(){mi.removeClass('open')});
|
||||
});
|
||||
};
|
||||
jQuery('ul.nav a.dropdown-toggle').parent().hover(function(){
|
||||
adjust_height_of_collapsed_nav();
|
||||
mi = jQuery(this).addClass('open');
|
||||
mi.children('.dropdown-menu').stop(true, true).delay(200).fadeIn(400);
|
||||
}, function(){
|
||||
mi = jQuery(this);
|
||||
mi.children('.dropdown-menu').stop(true, true).delay(200).fadeOut(function(){mi.removeClass('open')});
|
||||
});
|
||||
}
|
||||
hoverMenu(); // first page load
|
||||
jQuery(window).resize(hoverMenu); // on resize event
|
||||
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');
|
||||
});
|
||||
});
|
||||
@@ -247,3 +247,39 @@
|
||||
{{=IMG(_src=URL('appadmin', 'bg_graph_model'))}}
|
||||
{{pass}}
|
||||
{{pass}}
|
||||
|
||||
{{if request.function == 'auth_manage':}}
|
||||
<h2>{{=T('Manage Access Control')}}</h2>
|
||||
<ul class="nav nav-tabs">
|
||||
<li class="active"><a href="#users" data-toggle="tab">Users</a></li>
|
||||
<li><a href="#roles" data-toggle="tab">Roles</a></li>
|
||||
<li><a href="#permissions" data-toggle="tab">Permissions</a></li>
|
||||
</ul>
|
||||
|
||||
<div class="tab-content">
|
||||
<div class="tab-pane active" id="users">
|
||||
{{=LOAD(f='auth_manage.load', args=auth.settings.table_user_name,ajax=True)}}
|
||||
</div>
|
||||
<div class="tab-pane" id="roles">
|
||||
{{=LOAD(f='auth_manage.load', args=auth.settings.table_group_name,ajax=True)}}
|
||||
</div>
|
||||
<div class="tab-pane" id="permissions">
|
||||
{{=LOAD(f='auth_manage.load', args=auth.settings.table_permission_name,ajax=True)}}
|
||||
</div>
|
||||
</div>
|
||||
{{elif request.function == 'manage':}}
|
||||
<h2>{{=T('Manage Access Control')}}</h2>
|
||||
<ul class="nav nav-tabs">
|
||||
{{for k,tablename in enumerate(auth.db.tables):}}
|
||||
<li><a href="#table-{{=tablename}}" data-toggle="tab">{{=tablename}}</a></li>
|
||||
{{pass}}
|
||||
</ul>
|
||||
|
||||
<div class="tab-content">
|
||||
{{for tablename in auth.db.tables:}}
|
||||
<div class="tab-pane" id="table-{{=tablename}}">
|
||||
{{=LOAD(f='manage.load', args=tablename,ajax=True)}}
|
||||
</div>
|
||||
{{pass}}
|
||||
</div>
|
||||
{{pass}}
|
||||
|
||||
@@ -1,69 +1,69 @@
|
||||
{{extend 'layout.html'}}
|
||||
{{
|
||||
def all(items):
|
||||
return reduce(lambda a,b:a and b,items,True)
|
||||
return reduce(lambda a,b:a and b,items,True)
|
||||
def peekfile(path,file,vars={},title=None):
|
||||
args=(path,file) if 'app' in vars else (app,path,file)
|
||||
return A(file.replace('\\\\','/'),_title=title,_href=URL('peek', args=args, vars=vars))
|
||||
args=(path,file) if 'app' in vars else (app,path,file)
|
||||
return A(file.replace('\\\\','/'),_title=title,_href=URL('peek', args=args, vars=vars))
|
||||
def editfile(path,file,vars={}):
|
||||
args=(path,file) if 'app' in vars else (app,path,file)
|
||||
return A(SPAN(T('Edit')),_class='button editbutton btn btn-mini',_href=URL('edit', args=args, vars=vars))
|
||||
args=(path,file) if 'app' in vars else (app,path,file)
|
||||
return A(SPAN(T('Edit')),_class='button editbutton btn btn-mini',_href=URL('edit', args=args, vars=vars))
|
||||
def testfile(path,file):
|
||||
return A(TAG[''](IMG(_src=URL('static', 'images/test_icon.png'), _alt=T('test')),
|
||||
SPAN(T("Run tests in this file (to run all files, you may also use the button labelled 'test')"))),
|
||||
_class='icon test',
|
||||
_href=URL('test', args=(app, file)),
|
||||
_rel="tooltip",
|
||||
**{'_data-placement':'right',
|
||||
'_data-original-title':T("Run tests in this file (to run all files, you may also use the button labelled 'test')")})
|
||||
return A(TAG[''](IMG(_src=URL('static', 'images/test_icon.png'), _alt=T('test')),
|
||||
SPAN(T("Run tests in this file (to run all files, you may also use the button labelled 'test')"))),
|
||||
_class='icon test',
|
||||
_href=URL('test', args=(app, file)),
|
||||
_rel="tooltip",
|
||||
**{'_data-placement':'right',
|
||||
'_data-original-title':T("Run tests in this file (to run all files, you may also use the button labelled 'test')")})
|
||||
def editlanguagefile(path,file,vars={}):
|
||||
return A(SPAN(T('Edit')),_class='button editbutton btn btn-mini',_href=URL('edit_language', args=(app, path, file), vars=vars))
|
||||
return A(SPAN(T('Edit')),_class='button editbutton btn btn-mini',_href=URL('edit_language', args=(app, path, file), vars=vars))
|
||||
def editpluralsfile(path,file,vars={}):
|
||||
return A(SPAN(T('Edit')),_class='button editbutton btn btn-mini',_href=URL('edit_plurals', args=(app, path, file), vars=vars))
|
||||
return A(SPAN(T('Edit')),_class='button editbutton btn btn-mini',_href=URL('edit_plurals', args=(app, path, file), vars=vars))
|
||||
def file_upload_form(location, anchor=None):
|
||||
form=FORM(
|
||||
LABEL(T("upload file:")),
|
||||
INPUT(_type="file",_name="file"),
|
||||
LABEL(T("and rename it:")),
|
||||
INPUT(_type="text",_name="filename",requires=IS_NOT_EMPTY,_class=""),
|
||||
DIV(TAG['BUTTON'](T("Upload"),_type="submit",_class="btn"),_class="controls"),
|
||||
INPUT(_type="hidden",_name="location",_value=location),
|
||||
INPUT(_type="hidden",_name="token",_value=session.token),
|
||||
INPUT(_type="hidden",_name="sender",_value=URL('design',args=app, anchor=anchor)),
|
||||
_action=URL('upload_file'),
|
||||
_class="generatedbyw2p well well-small")
|
||||
return form
|
||||
form=FORM(
|
||||
LABEL(T("upload file:")),
|
||||
INPUT(_type="file",_name="file"),
|
||||
LABEL(T("and rename it:")),
|
||||
INPUT(_type="text",_name="filename",requires=IS_NOT_EMPTY,_class=""),
|
||||
DIV(TAG['BUTTON'](T("Upload"),_type="submit",_class="btn"),_class="controls"),
|
||||
INPUT(_type="hidden",_name="location",_value=location),
|
||||
INPUT(_type="hidden",_name="token",_value=session.token),
|
||||
INPUT(_type="hidden",_name="sender",_value=URL('design',args=app, anchor=anchor)),
|
||||
_action=URL('upload_file'),
|
||||
_class="generatedbyw2p well well-small")
|
||||
return form
|
||||
def file_create_form(location, anchor=None, helptext=""):
|
||||
form=FORM(
|
||||
LABEL(T("create file with filename:")),
|
||||
INPUT(_type="text",_name="filename",requires=IS_NOT_EMPTY,_class=''),
|
||||
TAG['SMALL'](helptext,_class="help-block"),
|
||||
DIV(TAG['BUTTON'](T("Create"),_type="submit",_class="btn"),_class="controls"),
|
||||
INPUT(_type="hidden",_name="location",_value=location),
|
||||
INPUT(_type="hidden",_name="sender",_value=URL('design',args=app)),
|
||||
INPUT(_type="hidden",_name="token",_value=session.token),
|
||||
INPUT(_type="hidden",_name="id",_value=anchor),
|
||||
_action=URL('create_file'),
|
||||
_class="generatedbyw2p well well-small")
|
||||
return form
|
||||
form=FORM(
|
||||
LABEL(T("create file with filename:")),
|
||||
INPUT(_type="text",_name="filename",requires=IS_NOT_EMPTY,_class=''),
|
||||
TAG['SMALL'](helptext,_class="help-block"),
|
||||
DIV(TAG['BUTTON'](T("Create"),_type="submit",_class="btn"),_class="controls"),
|
||||
INPUT(_type="hidden",_name="location",_value=location),
|
||||
INPUT(_type="hidden",_name="sender",_value=URL('design',args=app)),
|
||||
INPUT(_type="hidden",_name="token",_value=session.token),
|
||||
INPUT(_type="hidden",_name="id",_value=anchor),
|
||||
_action=URL('create_file'),
|
||||
_class="generatedbyw2p well well-small")
|
||||
return form
|
||||
def upload_plugin_form(app, anchor=None):
|
||||
form=FORM(
|
||||
LABEL(T("upload plugin file:")),
|
||||
INPUT(_type="file",_name="pluginfile"),
|
||||
INPUT(_type="hidden",_name="id",_value=anchor),
|
||||
INPUT(_type="hidden",_name="token",_value=session.token),
|
||||
DIV(TAG['BUTTON'](T("Upload"),_type="submit",_class="btn"),_class="controls"),
|
||||
_class="generatedbyw2p well well-small")
|
||||
return form
|
||||
form=FORM(
|
||||
LABEL(T("upload plugin file:")),
|
||||
INPUT(_type="file",_name="pluginfile"),
|
||||
INPUT(_type="hidden",_name="id",_value=anchor),
|
||||
INPUT(_type="hidden",_name="token",_value=session.token),
|
||||
DIV(TAG['BUTTON'](T("Upload"),_type="submit",_class="btn"),_class="controls"),
|
||||
_class="generatedbyw2p well well-small")
|
||||
return form
|
||||
def deletefile(arglist, vars={}):
|
||||
vars.update({'sender':request.function+'/'+app})
|
||||
return A(TAG[''](IMG(_src=URL('static', 'images/delete_icon.png')),
|
||||
SPAN(T('Delete this file (you will be asked to confirm deletion)'))),
|
||||
_href=URL('delete',args=arglist,vars=vars),
|
||||
_class='icon delete',
|
||||
_rel="tooltip",
|
||||
**{'_data-placement':'right',
|
||||
'_data-original-title':T('Delete this file (you will be asked to confirm deletion)')})
|
||||
vars.update({'sender':request.function+'/'+app})
|
||||
return A(TAG[''](IMG(_src=URL('static', 'images/delete_icon.png')),
|
||||
SPAN(T('Delete this file (you will be asked to confirm deletion)'))),
|
||||
_href=URL('delete',args=arglist,vars=vars),
|
||||
_class='icon delete',
|
||||
_rel="tooltip",
|
||||
**{'_data-placement':'right',
|
||||
'_data-original-title':T('Delete this file (you will be asked to confirm deletion)')})
|
||||
}}
|
||||
|
||||
{{block sectionclass}}design{{end}}
|
||||
@@ -91,45 +91,45 @@ def deletefile(arglist, vars={}):
|
||||
|
||||
<!-- MODELS -->
|
||||
<h3 id="_models" rel="pagebookmark">
|
||||
<span class="component" onclick="collapse('models_inner');">{{=T("Models")}}</span>
|
||||
<a href="#models" rel="tooltip" data-placement="right" data-original-title="{{=T('The data representation, define database tables and sets')}}">
|
||||
{{=helpicon()}}
|
||||
<span>{{=T("The data representation, define database tables and sets")}}</span>
|
||||
</a><span id="models" class="hashstick"> </span><a href="#" class="tophashlink btn btn-mini btn-warning"><span>top</span></a>
|
||||
<span class="component" onclick="collapse('models_inner');">{{=T("Models")}}</span>
|
||||
<a href="#models" rel="tooltip" data-placement="right" data-original-title="{{=T('The data representation, define database tables and sets')}}">
|
||||
{{=helpicon()}}
|
||||
<span>{{=T("The data representation, define database tables and sets")}}</span>
|
||||
</a><span id="models" class="hashstick"> </span><a href="#" class="tophashlink btn btn-mini btn-warning"><span>top</span></a>
|
||||
</h3>
|
||||
<div id="models_inner" class="component_contents">
|
||||
{{if not models:}}<p><strong>{{=T("There are no models")}}</strong></p>{{else:}}
|
||||
<div class="controls comptools">
|
||||
{{=button(URL(a=app,c='appadmin',f='index'), T('database administration'))}}
|
||||
{{if os.access(os.path.join(request.folder,'..',app,'databases','sql.log'),os.R_OK):}}
|
||||
{{=button(URL('peek/%s/databases/sql.log'%app), 'sql.log')}}
|
||||
{{pass}}
|
||||
{{if not models:}}<p><strong>{{=T("There are no models")}}</strong></p>{{else:}}
|
||||
<div class="controls comptools">
|
||||
{{=button(URL(a=app,c='appadmin',f='index'), T('database administration'))}}
|
||||
{{if os.access(os.path.join(request.folder,'..',app,'databases','sql.log'),os.R_OK):}}
|
||||
{{=button(URL('peek/%s/databases/sql.log'%app), 'sql.log')}}
|
||||
{{pass}}
|
||||
{{=button(URL(a=app, c='appadmin',f='graph_model'), T('graph model'))}}
|
||||
</div>
|
||||
<ul class="unstyled act_edit">
|
||||
{{for m in models:}}
|
||||
{{id="models__"+m.replace('.','__')}}
|
||||
<li id="{{='_'+id}}" rel="pagebookmark"><span id="{{=id}}" class="hashstick"> </span>
|
||||
<span class="filetools controls">
|
||||
{{=editfile('models',m, dict(id=id))}}
|
||||
{{=deletefile([app, 'models', m], dict(id=id, id2='models'))}}
|
||||
</span>
|
||||
<span class="file">
|
||||
{{=peekfile('models',m, dict(id=id))}}
|
||||
</span>
|
||||
<span class="extras">
|
||||
{{if len(defines[m]):}}{{=T("defines tables")}} {{pass}}{{=XML(', '.join([B(table).xml() for table in defines[m]]))}}
|
||||
</span>
|
||||
</li>
|
||||
{{pass}}
|
||||
</ul>
|
||||
{{pass}}
|
||||
<div class="controls formfield">
|
||||
<button onclick="jQuery('#form1').slideToggle()" class="btn btn-mini">Create</button>
|
||||
<div id="form1" class="row-fluid" style="display:none">
|
||||
<div class="span3">{{=file_create_form('%s/models/' % app, 'models')}}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<ul class="unstyled act_edit">
|
||||
{{for m in models:}}
|
||||
{{id="models__"+m.replace('.','__')}}
|
||||
<li id="{{='_'+id}}" rel="pagebookmark"><span id="{{=id}}" class="hashstick"> </span>
|
||||
<span class="filetools controls">
|
||||
{{=editfile('models',m, dict(id=id))}}
|
||||
{{=deletefile([app, 'models', m], dict(id=id, id2='models'))}}
|
||||
</span>
|
||||
<span class="file">
|
||||
{{=peekfile('models',m, dict(id=id))}}
|
||||
</span>
|
||||
<span class="extras">
|
||||
{{if len(defines[m]):}}{{=T("defines tables")}} {{pass}}{{=XML(', '.join([B(table).xml() for table in defines[m]]))}}
|
||||
</span>
|
||||
</li>
|
||||
{{pass}}
|
||||
</ul>
|
||||
{{pass}}
|
||||
<div class="controls formfield">
|
||||
<button onclick="jQuery('#form1').slideToggle()" class="btn btn-mini">Create</button>
|
||||
<div id="form1" class="row-fluid" style="display:none">
|
||||
<div class="span3">{{=file_create_form('%s/models/' % app, 'models')}}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- FIND CONTROLLER FUNCTIONS -->
|
||||
@@ -140,330 +140,330 @@ for c in controllers: controller_functions+=[c[:-3]+'/%s.html'%x for x in functi
|
||||
|
||||
<!-- CONTROLLERS -->
|
||||
<h3 id="_controllers" rel="pagebookmark">
|
||||
<span class="component" onclick="collapse('controllers_inner');">{{=T("Controllers")}}</span>
|
||||
<a href="#controllers" rel="tooltip" data-placement="right" data-original-title="{{=T('The application logic, each URL path is mapped in one exposed function in the controller')}}">
|
||||
{{=helpicon()}}
|
||||
<span>{{=T("The application logic, each URL path is mapped in one exposed function in the controller")}}</span>
|
||||
</a><span id="controllers" class="hashstick"> </span><a href="#" class="tophashlink btn btn-mini btn-warning"><span>top</span></a>
|
||||
<span class="component" onclick="collapse('controllers_inner');">{{=T("Controllers")}}</span>
|
||||
<a href="#controllers" rel="tooltip" data-placement="right" data-original-title="{{=T('The application logic, each URL path is mapped in one exposed function in the controller')}}">
|
||||
{{=helpicon()}}
|
||||
<span>{{=T("The application logic, each URL path is mapped in one exposed function in the controller")}}</span>
|
||||
</a><span id="controllers" class="hashstick"> </span><a href="#" class="tophashlink btn btn-mini btn-warning"><span>top</span></a>
|
||||
</h3>
|
||||
<div id="controllers_inner" class="component_contents">
|
||||
{{if not controllers:}}<p><strong>{{=T("There are no controllers")}}</strong></p>{{else:}}
|
||||
<div class="controls comptools">
|
||||
{{=button(URL(r=request,c='shell',f='index',args=app), T("shell"))}}
|
||||
{{=button(URL('test',args=app), T("test"))}}
|
||||
{{=button(URL('edit',args=[app,'cron','crontab']), T("crontab"))}}
|
||||
</div>
|
||||
<ul class="unstyled act_edit">
|
||||
{{for c in controllers:}}
|
||||
{{id="controllers__"+c.replace('.','__')}}
|
||||
<li id="{{='_'+id}}" rel="pagebookmark"><span id="{{=id}}" class="hashstick"> </span>
|
||||
<span class="filetools controls">
|
||||
{{=editfile('controllers',c, dict(id=id))}}
|
||||
{{=deletefile([app, 'controllers', c], dict(id=id, id2='controllers'))}}
|
||||
{{=testfile('controllers',c)}}
|
||||
</span>
|
||||
<span class="file">
|
||||
{{=peekfile('controllers',c, dict(id=id))}}
|
||||
</span>
|
||||
<span class="extras celled">
|
||||
{{if functions[c]:}}{{=T("exposes")}}{{pass}} {{=XML(', '.join([A(f,_href=URL(a=app,c=c[:-3],f=f)).xml() for f in functions[c]]))}}
|
||||
</span>
|
||||
</li>
|
||||
{{pass}}
|
||||
</ul>
|
||||
{{pass}}
|
||||
<div class="controls formfield">
|
||||
<button onclick="jQuery('#form2').slideToggle()" class="btn btn-mini">Create</button>
|
||||
<div id="form2" class="row-fluid" style="display:none">
|
||||
<div class="span3">{{=file_create_form('%s/controllers/' % app, 'controllers')}}</div>
|
||||
</div>
|
||||
</div>
|
||||
{{if not controllers:}}<p><strong>{{=T("There are no controllers")}}</strong></p>{{else:}}
|
||||
<div class="controls comptools">
|
||||
{{=button(URL(r=request,c='shell',f='index',args=app), T("shell"))}}
|
||||
{{=button(URL('test',args=app), T("test"))}}
|
||||
{{=button(URL('edit',args=[app,'cron','crontab']), T("crontab"))}}
|
||||
</div>
|
||||
<ul class="unstyled act_edit">
|
||||
{{for c in controllers:}}
|
||||
{{id="controllers__"+c.replace('.','__')}}
|
||||
<li id="{{='_'+id}}" rel="pagebookmark"><span id="{{=id}}" class="hashstick"> </span>
|
||||
<span class="filetools controls">
|
||||
{{=editfile('controllers',c, dict(id=id))}}
|
||||
{{=deletefile([app, 'controllers', c], dict(id=id, id2='controllers'))}}
|
||||
{{=testfile('controllers',c)}}
|
||||
</span>
|
||||
<span class="file">
|
||||
{{=peekfile('controllers',c, dict(id=id))}}
|
||||
</span>
|
||||
<span class="extras celled">
|
||||
{{if functions[c]:}}{{=T("exposes")}}{{pass}} {{=XML(', '.join([A(f,_href=URL(a=app,c=c[:-3],f=f)).xml() for f in functions[c]]))}}
|
||||
</span>
|
||||
</li>
|
||||
{{pass}}
|
||||
</ul>
|
||||
{{pass}}
|
||||
<div class="controls formfield">
|
||||
<button onclick="jQuery('#form2').slideToggle()" class="btn btn-mini">Create</button>
|
||||
<div id="form2" class="row-fluid" style="display:none">
|
||||
<div class="span3">{{=file_create_form('%s/controllers/' % app, 'controllers')}}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- VIEWS -->
|
||||
<h3 id="_views" rel="pagebookmark">
|
||||
<span class="component" onclick="collapse('views_inner');">{{=T("Views")}}</span>
|
||||
<a href="#views" rel="tooltip" data-placement="right" data-original-title="{{=T('The presentations layer, views are also known as templates')}}">
|
||||
{{=helpicon()}}
|
||||
<span>{{=T("The presentations layer, views are also known as templates")}}</span>
|
||||
</a><span id="views" class="hashstick"> </span><a href="#" class="tophashlink btn btn-mini btn-warning"><span>top</span></a>
|
||||
<span class="component" onclick="collapse('views_inner');">{{=T("Views")}}</span>
|
||||
<a href="#views" rel="tooltip" data-placement="right" data-original-title="{{=T('The presentations layer, views are also known as templates')}}">
|
||||
{{=helpicon()}}
|
||||
<span>{{=T("The presentations layer, views are also known as templates")}}</span>
|
||||
</a><span id="views" class="hashstick"> </span><a href="#" class="tophashlink btn btn-mini btn-warning"><span>top</span></a>
|
||||
</h3>
|
||||
<div id="views_inner" class="component_contents">
|
||||
{{if not views:}}<p><strong>{{=T("There are no views")}}</strong></p>{{else:}}
|
||||
<div class="controls comptools">
|
||||
{{=button(LAYOUTS_APP, T("download layouts"))}}
|
||||
</div>
|
||||
<ul class="unstyled act_edit">
|
||||
{{for c in views:}}
|
||||
{{id="views__"+c.replace('/','__').replace('.','__')}}
|
||||
<li id="{{='_'+id}}" rel="pagebookmark"><span id="{{=id}}" class="hashstick"> </span>
|
||||
<span class="filetools controls">
|
||||
{{=editfile('views',c, dict(id=id))}}
|
||||
{{=deletefile([app, 'views', c], dict(id=id, id2='views'))}}
|
||||
</span>
|
||||
<span class="file">
|
||||
{{=peekfile('views',c, dict(id=id))}}
|
||||
</span>
|
||||
<span class="extras celled celled-one">
|
||||
{{if extend.has_key(c):}}{{=T("extends")}} <b>{{=extend[c]}}</b> {{pass}}
|
||||
{{if include[c]:}}{{=T("includes")}} {{pass}}{{=XML(', '.join([B(f).xml() for f in include[c]]))}}
|
||||
</span>
|
||||
</li>
|
||||
{{pass}}
|
||||
</ul>
|
||||
{{pass}}
|
||||
<div class="controls formfield">
|
||||
<button onclick="jQuery('#form3').slideToggle()" class="btn btn-mini">Create</button>
|
||||
<div id="form3" class="row-fluid" style="display:none">
|
||||
<div class="span3">{{=file_create_form('%s/views/' % app, 'views')}}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="controls comptools">
|
||||
{{=button(LAYOUTS_APP, T("download layouts"))}}
|
||||
</div>
|
||||
<ul class="unstyled act_edit">
|
||||
{{for c in views:}}
|
||||
{{id="views__"+c.replace('/','__').replace('.','__')}}
|
||||
<li id="{{='_'+id}}" rel="pagebookmark"><span id="{{=id}}" class="hashstick"> </span>
|
||||
<span class="filetools controls">
|
||||
{{=editfile('views',c, dict(id=id))}}
|
||||
{{=deletefile([app, 'views', c], dict(id=id, id2='views'))}}
|
||||
</span>
|
||||
<span class="file">
|
||||
{{=peekfile('views',c, dict(id=id))}}
|
||||
</span>
|
||||
<span class="extras celled celled-one">
|
||||
{{if extend.has_key(c):}}{{=T("extends")}} <b>{{=extend[c]}}</b> {{pass}}
|
||||
{{if include[c]:}}{{=T("includes")}} {{pass}}{{=XML(', '.join([B(f).xml() for f in include[c]]))}}
|
||||
</span>
|
||||
</li>
|
||||
{{pass}}
|
||||
</ul>
|
||||
{{pass}}
|
||||
<div class="controls formfield">
|
||||
<button onclick="jQuery('#form3').slideToggle()" class="btn btn-mini">Create</button>
|
||||
<div id="form3" class="row-fluid" style="display:none">
|
||||
<div class="span3">{{=file_create_form('%s/views/' % app, 'views')}}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- LANGUAGES -->
|
||||
<h3 id="_languages" rel="pagebookmark">
|
||||
<span class="component" onclick="collapse('languages_inner');">{{=T("Languages")}}</span>
|
||||
<a href="#languages" rel="tooltip" data-placement="right" data-original-title="{{=T('Translation strings for the application')}}">
|
||||
{{=helpicon()}}
|
||||
<span>{{=T("Translation strings for the application")}}</span>
|
||||
</a><span id="languages" class="hashstick"> </span><a href="#" class="tophashlink btn btn-mini btn-warning"><span>top</span></a>
|
||||
<span class="component" onclick="collapse('languages_inner');">{{=T("Languages")}}</span>
|
||||
<a href="#languages" rel="tooltip" data-placement="right" data-original-title="{{=T('Translation strings for the application')}}">
|
||||
{{=helpicon()}}
|
||||
<span>{{=T("Translation strings for the application")}}</span>
|
||||
</a><span id="languages" class="hashstick"> </span><a href="#" class="tophashlink btn btn-mini btn-warning"><span>top</span></a>
|
||||
</h3>
|
||||
<div id="languages_inner" class="component_contents">
|
||||
{{if not languages:}}<p><strong>{{=T("There are no translators, only default language is supported")}}</strong></p>{{else:}}
|
||||
<div class="controls comptools">
|
||||
{{=button(URL('update_languages/'+app), T('update all languages'))}}
|
||||
</div>
|
||||
<ul class="unstyled act_edit">
|
||||
{{for lang in sorted(languages):
|
||||
file = lang+'.py'
|
||||
id = "languages__"+file.replace('.','__')}}
|
||||
<li id="{{='_'+id}}" rel="pagebookmark" class="li-row"><span id="{{=id}}" class="hashstick"> </span>
|
||||
<span class="li-controls">
|
||||
<span class="filetools controls">
|
||||
{{=editlanguagefile('languages',file)}}
|
||||
{{=deletefile([app, 'languages', file], dict(id=id, id2='languages'))}}
|
||||
</span>
|
||||
<span class="">
|
||||
{{=peekfile('languages',file, dict(id=id))}}
|
||||
</span>
|
||||
</span> <!-- /li-row -->
|
||||
<span class="extras celled">
|
||||
(
|
||||
{{=T("Plural-Forms:")}}
|
||||
{{p=languages[lang][3:7]}}
|
||||
{{if p[2] == 'default':}}
|
||||
<span class='error text-error'>{{=T("rules are not defined")}}</span> {{=T.M("(file **gluon/contrib/plural_rules/%s.py** is not found)",lang[:2])}}
|
||||
{{else:}}
|
||||
{{if p[3] == 1:}}
|
||||
{{=B(T("are not used"))}}
|
||||
{{else:}}
|
||||
{{pfile=p[0]}}
|
||||
{{if p[1]!=0:}}<span style="display:inline-block;margin-top:-10px;">
|
||||
<span class="filetools controls">
|
||||
{{=editpluralsfile('languages',pfile,dict(nplurals=p[3]))}}
|
||||
</span>
|
||||
<span class="file">
|
||||
{{=peekfile('languages',pfile,dict(id=id))}}
|
||||
</span></span>
|
||||
{{else:}}
|
||||
<b>{{=T("are not used yet")}}</b>
|
||||
{{pass}}
|
||||
{{pass}}
|
||||
{{pass}}
|
||||
)
|
||||
</span>
|
||||
</li>
|
||||
{{pass}}
|
||||
</ul>
|
||||
{{pass}}
|
||||
<div class="controls formfield">
|
||||
<button onclick="jQuery('#form4').slideToggle()" class="btn btn-mini">Create</button>
|
||||
<div id="form4" class="row-fluid" style="display:none">
|
||||
<div class="span3">{{=file_create_form('%s/languages/' % app, 'languages', T('(something like "it-it")'))}}</div>
|
||||
</div>
|
||||
</div>
|
||||
{{if not languages:}}<p><strong>{{=T("There are no translators, only default language is supported")}}</strong></p>{{else:}}
|
||||
<div class="controls comptools">
|
||||
{{=button(URL('update_languages/'+app), T('update all languages'))}}
|
||||
</div>
|
||||
<ul class="unstyled act_edit">
|
||||
{{for lang in sorted(languages):
|
||||
file = lang+'.py'
|
||||
id = "languages__"+file.replace('.','__')}}
|
||||
<li id="{{='_'+id}}" rel="pagebookmark" class="li-row"><span id="{{=id}}" class="hashstick"> </span>
|
||||
<span class="li-controls">
|
||||
<span class="filetools controls">
|
||||
{{=editlanguagefile('languages',file)}}
|
||||
{{=deletefile([app, 'languages', file], dict(id=id, id2='languages'))}}
|
||||
</span>
|
||||
<span class="">
|
||||
{{=peekfile('languages',file, dict(id=id))}}
|
||||
</span>
|
||||
</span> <!-- /li-row -->
|
||||
<span class="extras celled">
|
||||
(
|
||||
{{=T("Plural-Forms:")}}
|
||||
{{p=languages[lang][3:7]}}
|
||||
{{if p[2] == 'default':}}
|
||||
<span class='error text-error'>{{=T("rules are not defined")}}</span> {{=T.M("(file **gluon/contrib/plural_rules/%s.py** is not found)",lang[:2])}}
|
||||
{{else:}}
|
||||
{{if p[3] == 1:}}
|
||||
{{=B(T("are not used"))}}
|
||||
{{else:}}
|
||||
{{pfile=p[0]}}
|
||||
{{if p[1]!=0:}}<span style="display:inline-block;margin-top:-10px;">
|
||||
<span class="filetools controls">
|
||||
{{=editpluralsfile('languages',pfile,dict(nplurals=p[3]))}}
|
||||
</span>
|
||||
<span class="file">
|
||||
{{=peekfile('languages',pfile,dict(id=id))}}
|
||||
</span></span>
|
||||
{{else:}}
|
||||
<b>{{=T("are not used yet")}}</b>
|
||||
{{pass}}
|
||||
{{pass}}
|
||||
{{pass}}
|
||||
)
|
||||
</span>
|
||||
</li>
|
||||
{{pass}}
|
||||
</ul>
|
||||
{{pass}}
|
||||
<div class="controls formfield">
|
||||
<button onclick="jQuery('#form4').slideToggle()" class="btn btn-mini">Create</button>
|
||||
<div id="form4" class="row-fluid" style="display:none">
|
||||
<div class="span3">{{=file_create_form('%s/languages/' % app, 'languages', T('(something like "it-it")'))}}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- STATIC -->
|
||||
<h3 id="_static" rel="pagebookmark">
|
||||
<span class="component" onclick="collapse('static_inner');">{{=T("Static")}}</span>
|
||||
<a href="#static" rel="tooltip" data-placement="right" data-original-title="{{=T('These files are served without processing, your images go here')}}">
|
||||
{{=helpicon()}}
|
||||
<span>{{=T("These files are served without processing, your images go here")}}</span>
|
||||
</a><span id="static" class="hashstick"> </span><a href="#" class="tophashlink btn btn-mini btn-warning"><span>top</span></a>
|
||||
<span class="component" onclick="collapse('static_inner');">{{=T("Static")}}</span>
|
||||
<a href="#static" rel="tooltip" data-placement="right" data-original-title="{{=T('These files are served without processing, your images go here')}}">
|
||||
{{=helpicon()}}
|
||||
<span>{{=T("These files are served without processing, your images go here")}}</span>
|
||||
</a><span id="static" class="hashstick"> </span><a href="#" class="tophashlink btn btn-mini btn-warning"><span>top</span></a>
|
||||
</h3>
|
||||
<div id="static_inner" class="component_contents">
|
||||
{{if not statics:}}<p><strong>{{=T("There are no static files")}}</strong></p>{{else:}}
|
||||
<ul class="unstyled act_edit">
|
||||
{{
|
||||
path=[]
|
||||
for file in statics+['']:
|
||||
items=file.split('/')
|
||||
file_path=items[:-1]
|
||||
filename=items[-1]
|
||||
while path!=file_path:
|
||||
if len(file_path)>=len(path) and all([v==file_path[k] for k,v in enumerate(path)]):
|
||||
path.append(file_path[len(path)])
|
||||
thispath='static__'+'__'.join(path)
|
||||
}}
|
||||
<li class="folder"><i> </i>
|
||||
<a href="javascript:collapse('{{=thispath}}');" class="file">{{=path[-1]}}/</a>
|
||||
<ul id="{{=thispath}}" style="display: none;" class="sublist">{{
|
||||
else:
|
||||
path = path[:-1]
|
||||
}}
|
||||
</ul></li>
|
||||
{{
|
||||
pass
|
||||
pass
|
||||
if filename:
|
||||
}}
|
||||
<li>
|
||||
<span class="filetools controls">
|
||||
{{=editfile('static',file, dict(id="static"))}} {{=deletefile([app,'static',file], dict(id="static",id2="static"))}}
|
||||
</span>
|
||||
<span class="file">
|
||||
<a href="{{=URL(a=app,c='static',f=file)}}">{{=filename}}</a>
|
||||
</span>
|
||||
</li>{{
|
||||
pass
|
||||
pass
|
||||
}}
|
||||
</ul>
|
||||
{{pass}}
|
||||
<div class="controls formfield">
|
||||
<button onclick="jQuery('#form5').slideToggle()" class="btn btn-mini">Create/Upload</button>
|
||||
<div id="form5" class="row-fluid" style="display:none">
|
||||
<div class="span3">{{=file_create_form('%s/static/' % app, 'static')}}<em>{{=T('or alternatively')}}</em></div>
|
||||
<div class="span3">{{=file_upload_form('%s/static/' % app, 'static')}}</div>
|
||||
</div>
|
||||
</div>
|
||||
{{if not statics:}}<p><strong>{{=T("There are no static files")}}</strong></p>{{else:}}
|
||||
<ul class="unstyled act_edit">
|
||||
{{
|
||||
path=[]
|
||||
for file in statics+['']:
|
||||
items=file.split('/')
|
||||
file_path=items[:-1]
|
||||
filename=items[-1]
|
||||
while path!=file_path:
|
||||
if len(file_path)>=len(path) and all([v==file_path[k] for k,v in enumerate(path)]):
|
||||
path.append(file_path[len(path)])
|
||||
thispath='static__'+'__'.join(path)
|
||||
}}
|
||||
<li class="folder"><i> </i>
|
||||
<a href="javascript:collapse('{{=thispath}}');" class="file">{{=path[-1]}}/</a>
|
||||
<ul id="{{=thispath}}" style="display: none;" class="sublist">{{
|
||||
else:
|
||||
path = path[:-1]
|
||||
}}
|
||||
</ul></li>
|
||||
{{
|
||||
pass
|
||||
pass
|
||||
if filename:
|
||||
}}
|
||||
<li>
|
||||
<span class="filetools controls">
|
||||
{{=editfile('static',file, dict(id="static"))}} {{=deletefile([app,'static',file], dict(id="static",id2="static"))}}
|
||||
</span>
|
||||
<span class="file">
|
||||
<a href="{{=URL(a=app,c='static',f=file)}}">{{=filename}}</a>
|
||||
</span>
|
||||
</li>{{
|
||||
pass
|
||||
pass
|
||||
}}
|
||||
</ul>
|
||||
{{pass}}
|
||||
<div class="controls formfield">
|
||||
<button onclick="jQuery('#form5').slideToggle()" class="btn btn-mini">Create/Upload</button>
|
||||
<div id="form5" class="row-fluid" style="display:none">
|
||||
<div class="span3">{{=file_create_form('%s/static/' % app, 'static')}}<em>{{=T('or alternatively')}}</em></div>
|
||||
<div class="span3">{{=file_upload_form('%s/static/' % app, 'static')}}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- MODULES -->
|
||||
<h3 id="_modules" rel="pagebookmark">
|
||||
<span class="component" onclick="collapse('modules_inner');">{{=T("Modules")}}</span>
|
||||
<a href="#modules" rel="tooltip" data-placement="right" data-original-title="{{=T('Additional code for your application')}}">
|
||||
{{=helpicon()}}
|
||||
<span>{{=T("Additional code for your application")}}</span>
|
||||
</a><span id="modules" class="hashstick"> </span><a href="#" class="tophashlink btn btn-mini btn-warning"><span>top</span></a>
|
||||
<span class="component" onclick="collapse('modules_inner');">{{=T("Modules")}}</span>
|
||||
<a href="#modules" rel="tooltip" data-placement="right" data-original-title="{{=T('Additional code for your application')}}">
|
||||
{{=helpicon()}}
|
||||
<span>{{=T("Additional code for your application")}}</span>
|
||||
</a><span id="modules" class="hashstick"> </span><a href="#" class="tophashlink btn btn-mini btn-warning"><span>top</span></a>
|
||||
</h3>
|
||||
<div id="modules_inner" class="component_contents">
|
||||
{{if not modules:}}<p><strong>{{=T("There are no modules")}}</strong></p>{{else:}}
|
||||
<ul class="unstyled act_edit">
|
||||
{{for m in modules:}}
|
||||
{{id="modules__"+m.replace('/','__').replace('.','__')}}
|
||||
<li id="{{='_'+id}}" rel="pagebookmark"><span id="{{=id}}" class="hashstick"> </span>
|
||||
<span class="filetols controls">
|
||||
{{=editfile('modules',m,dict(id=id))}}
|
||||
{{if m!='__init__.py':}}
|
||||
{{=deletefile([app, 'modules', m], dict(id=id, id2='modules'))}}
|
||||
{{pass}}
|
||||
</span>
|
||||
<span class="file">
|
||||
{{=peekfile('modules',m, dict(id=id))}}
|
||||
</span>
|
||||
</li>
|
||||
{{pass}}
|
||||
</ul>
|
||||
{{pass}}
|
||||
<div class="controls formfield">
|
||||
<button onclick="jQuery('#form5').slideToggle()" class="btn btn-mini">Create/Upload</button>
|
||||
<div id="form5" class="row-fluid" style="display:none">
|
||||
<div class="span3">{{=file_create_form('%s/modules/' % app, 'modules')}}<em>{{=T('or alternatively')}}</em></div>
|
||||
<div class="span3">{{=file_upload_form('%s/modules/' % app, 'modules')}}</div>
|
||||
</div>
|
||||
</div>
|
||||
{{if not modules:}}<p><strong>{{=T("There are no modules")}}</strong></p>{{else:}}
|
||||
<ul class="unstyled act_edit">
|
||||
{{for m in modules:}}
|
||||
{{id="modules__"+m.replace('/','__').replace('.','__')}}
|
||||
<li id="{{='_'+id}}" rel="pagebookmark"><span id="{{=id}}" class="hashstick"> </span>
|
||||
<span class="filetols controls">
|
||||
{{=editfile('modules',m,dict(id=id))}}
|
||||
{{if m!='__init__.py':}}
|
||||
{{=deletefile([app, 'modules', m], dict(id=id, id2='modules'))}}
|
||||
{{pass}}
|
||||
</span>
|
||||
<span class="file">
|
||||
{{=peekfile('modules',m, dict(id=id))}}
|
||||
</span>
|
||||
</li>
|
||||
{{pass}}
|
||||
</ul>
|
||||
{{pass}}
|
||||
<div class="controls formfield">
|
||||
<button onclick="jQuery('#form6').slideToggle()" class="btn btn-mini">Create/Upload</button>
|
||||
<div id="form6" class="row-fluid" style="display:none">
|
||||
<div class="span3">{{=file_create_form('%s/modules/' % app, 'modules')}}<em>{{=T('or alternatively')}}</em></div>
|
||||
<div class="span3">{{=file_upload_form('%s/modules/' % app, 'modules')}}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- PRIVATE -->
|
||||
<h3 id="_private" rel="pagebookmark">
|
||||
<span class="component" onclick="collapse('private_inner');">{{=T("Private files")}}</span>
|
||||
<a href="#private" rel="tooltip" data-placement="right" data-original-title="{{=T('These files are not served, they are only available from within your app')}}">
|
||||
{{=helpicon()}}
|
||||
<span>{{=T("These files are not served, they are only available from within your app")}}</span>
|
||||
</a><span id="private" class="hashstick"> </span><a href="#" class="tophashlink btn btn-mini btn-warning"><span>top</span></a>
|
||||
<span class="component" onclick="collapse('private_inner');">{{=T("Private files")}}</span>
|
||||
<a href="#private" rel="tooltip" data-placement="right" data-original-title="{{=T('These files are not served, they are only available from within your app')}}">
|
||||
{{=helpicon()}}
|
||||
<span>{{=T("These files are not served, they are only available from within your app")}}</span>
|
||||
</a><span id="private" class="hashstick"> </span><a href="#" class="tophashlink btn btn-mini btn-warning"><span>top</span></a>
|
||||
</h3>
|
||||
<div id="private_inner" class="component_contents">
|
||||
{{if not privates:}}<p><strong>{{=T("There are no private files")}}</strong></p>{{else:}}
|
||||
<ul class="unstyled act_edit">
|
||||
{{
|
||||
path=[]
|
||||
for file in privates+['']:
|
||||
items=file.split('/')
|
||||
file_path=items[:-1]
|
||||
filename=items[-1]
|
||||
while path!=file_path:
|
||||
if len(file_path)>=len(path) and all([v==file_path[k] for k,v in enumerate(path)]):
|
||||
path.append(file_path[len(path)])
|
||||
thispath='private__'+'__'.join(path)
|
||||
}}
|
||||
<li class="folder">
|
||||
<a href="javascript:collapse('{{=thispath}}');" class="file">{{=path[-1]}}/</a>
|
||||
<ul id="{{=thispath}}" style="display: none;" class="sublist">{{
|
||||
else:
|
||||
path = path[:-1]
|
||||
}}
|
||||
</ul>
|
||||
</li>
|
||||
{{
|
||||
pass
|
||||
pass
|
||||
if filename:
|
||||
}}
|
||||
<li>
|
||||
<span class="filetools controls">
|
||||
{{=editfile('private',file, dict(id="private"))}} {{=deletefile([app,'private',file], dict(id="private",id2="private"))}}
|
||||
</span>
|
||||
<span class="file">
|
||||
{{=peekfile('private',file, dict(id="private"))}}
|
||||
</span>
|
||||
</li>{{
|
||||
pass
|
||||
pass
|
||||
}}
|
||||
{{pass}}
|
||||
</ul>
|
||||
<div class="controls formfield">
|
||||
<button onclick="jQuery('#form6').slideToggle()" class="btn btn-mini">Create/Upload</button>
|
||||
<div id="form6" class="row-fluid" style="display:none">
|
||||
<div class="span3">{{=file_create_form('%s/private/' % app, 'private')}}<em>{{=T('or alternatively')}}</em></div>
|
||||
<div class="span3">{{=file_upload_form('%s/private/' % app, 'private')}}</div>
|
||||
</div>
|
||||
</div>
|
||||
{{if not privates:}}<p><strong>{{=T("There are no private files")}}</strong></p>{{else:}}
|
||||
<ul class="unstyled act_edit">
|
||||
{{
|
||||
path=[]
|
||||
for file in privates+['']:
|
||||
items=file.split('/')
|
||||
file_path=items[:-1]
|
||||
filename=items[-1]
|
||||
while path!=file_path:
|
||||
if len(file_path)>=len(path) and all([v==file_path[k] for k,v in enumerate(path)]):
|
||||
path.append(file_path[len(path)])
|
||||
thispath='private__'+'__'.join(path)
|
||||
}}
|
||||
<li class="folder">
|
||||
<a href="javascript:collapse('{{=thispath}}');" class="file">{{=path[-1]}}/</a>
|
||||
<ul id="{{=thispath}}" style="display: none;" class="sublist">{{
|
||||
else:
|
||||
path = path[:-1]
|
||||
}}
|
||||
</ul>
|
||||
</li>
|
||||
{{
|
||||
pass
|
||||
pass
|
||||
if filename:
|
||||
}}
|
||||
<li>
|
||||
<span class="filetools controls">
|
||||
{{=editfile('private',file, dict(id="private"))}} {{=deletefile([app,'private',file], dict(id="private",id2="private"))}}
|
||||
</span>
|
||||
<span class="file">
|
||||
{{=peekfile('private',file, dict(id="private"))}}
|
||||
</span>
|
||||
</li>{{
|
||||
pass
|
||||
pass
|
||||
}}
|
||||
{{pass}}
|
||||
</ul>
|
||||
<div class="controls formfield">
|
||||
<button onclick="jQuery('#form7').slideToggle()" class="btn btn-mini">Create/Upload</button>
|
||||
<div id="form7" class="row-fluid" style="display:none">
|
||||
<div class="span3">{{=file_create_form('%s/private/' % app, 'private')}}<em>{{=T('or alternatively')}}</em></div>
|
||||
<div class="span3">{{=file_upload_form('%s/private/' % app, 'private')}}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- PLUGINS -->
|
||||
<h3 id="_plugins" rel="pagebookmark">
|
||||
<span class="component" onclick="collapse('plugins_inner');">{{=T("Plugins")}}</span>
|
||||
<a href="#plugins" rel="tooltip" data-placement="right" data-original-title="{{=T('To create a plugin, name a file/folder plugin_[name]')}}">
|
||||
{{=helpicon()}}
|
||||
<span>{{=T("To create a plugin, name a file/folder plugin_[name]")}}</span>
|
||||
</a><span id="plugins" class="hashstick"> </span><a href="#" class="tophashlink btn btn-mini btn-warning"><span>top</span></a>
|
||||
<span class="component" onclick="collapse('plugins_inner');">{{=T("Plugins")}}</span>
|
||||
<a href="#plugins" rel="tooltip" data-placement="right" data-original-title="{{=T('To create a plugin, name a file/folder plugin_[name]')}}">
|
||||
{{=helpicon()}}
|
||||
<span>{{=T("To create a plugin, name a file/folder plugin_[name]")}}</span>
|
||||
</a><span id="plugins" class="hashstick"> </span><a href="#" class="tophashlink btn btn-mini btn-warning"><span>top</span></a>
|
||||
</h3>
|
||||
<div id="plugins_inner" class="component_contents">
|
||||
<div class="controls comptools">
|
||||
{{=button(PLUGINS_APP, T('download plugins'))}}
|
||||
</div>
|
||||
{{if plugins:}}
|
||||
<ul class="unstyled act_edit">
|
||||
{{for plugin in plugins:}}
|
||||
{{id="plugins__"+plugin.replace('/','__').replace('.','__')}}
|
||||
<li id="{{=id}}">
|
||||
{{=A('plugin_%s' % plugin, _class='file', _href=URL('plugin', args=[app, plugin], vars=dict(id=id, id2='plugins')))}}
|
||||
</li>
|
||||
{{pass}}
|
||||
</ul>
|
||||
{{else:}}
|
||||
<p><strong>{{=T('There are no plugins')}}</strong></p>
|
||||
{{pass}}
|
||||
<div class="controls formfield">
|
||||
<button onclick="jQuery('#form7').slideToggle()" class="btn btn-mini">Upload</button>
|
||||
<div id="form7" class="row-fluid" style="display:none">
|
||||
<div class="row-fluid">
|
||||
<div class="span3">{{=upload_plugin_form(app, 'plugins')}}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="controls comptools">
|
||||
{{=button(PLUGINS_APP, T('download plugins'))}}
|
||||
</div>
|
||||
{{if plugins:}}
|
||||
<ul class="unstyled act_edit">
|
||||
{{for plugin in plugins:}}
|
||||
{{id="plugins__"+plugin.replace('/','__').replace('.','__')}}
|
||||
<li id="{{=id}}">
|
||||
{{=A('plugin_%s' % plugin, _class='file', _href=URL('plugin', args=[app, plugin], vars=dict(id=id, id2='plugins')))}}
|
||||
</li>
|
||||
{{pass}}
|
||||
</ul>
|
||||
{{else:}}
|
||||
<p><strong>{{=T('There are no plugins')}}</strong></p>
|
||||
{{pass}}
|
||||
<div class="controls formfield">
|
||||
<button onclick="jQuery('#form8').slideToggle()" class="btn btn-mini">Upload</button>
|
||||
<div id="form8" class="row-fluid" style="display:none">
|
||||
<div class="row-fluid">
|
||||
<div class="span3">{{=upload_plugin_form(app, 'plugins')}}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
|
||||
@@ -3,6 +3,16 @@
|
||||
{{
|
||||
def shortcut(combo, description):
|
||||
return XML('<li><span class="teletype-text">%s</span><span>%s</span></li>' % (combo, description))
|
||||
def listfiles(app, dir, regexp='.*\.py$'):
|
||||
files = sorted(
|
||||
listdir(apath('%(app)s/%(dir)s/' % {'app':app, 'dir':dir}, r=request), regexp))
|
||||
files = [x.replace('\\', '/') for x in files if not x.endswith('.bak')]
|
||||
return files
|
||||
|
||||
def editfile(path,file,vars={}):
|
||||
args=(path,file) if 'app' in vars else (app,path,file)
|
||||
return A(file, _class='', _href=URL('edit', args=args, vars=vars), _style='word-wrap: break-word;')
|
||||
|
||||
}}
|
||||
{{if TEXT_EDITOR == 'amy':}}
|
||||
{{include 'default/amy_ajax.html'}}
|
||||
@@ -128,8 +138,31 @@ jQuery(document).ready(function(){
|
||||
<a class="button btn" href="http://www.web2py.com/examples/static/epydoc/index.html" target="_blank"><span>{{=T('docs')}}</span></a>
|
||||
</p>
|
||||
</div>
|
||||
<div id="editor_area">
|
||||
<form action="{{=URL('edit',args=filename)}}" method="post" name="editform" id="editform">
|
||||
<div id="editor_area" class="row-fluid">
|
||||
|
||||
<ul class="nav nav-list span2 well" rel="pagebookmark">
|
||||
{{dirs=[{'name':'models', 'reg':'.*\.py$'},
|
||||
{'name':'controllers', 'reg':'.*\.py$'},
|
||||
{'name':'views', 'reg':'[\w/\-]+(\.\w+)+$'},
|
||||
{'name':'modules', 'reg':'.*\.py$'},
|
||||
{'name':'private', 'reg': '[^\.#].*'}]}}
|
||||
{{for dir in dirs:}}
|
||||
<li class="nav-header component" onclick="collapse('{{="%s_files" % dir['name']}}');">{{=dir['name']}}</li>
|
||||
<li id="{{="%s_files" % dir['name']}}">
|
||||
<ul class="nav nav-list">
|
||||
{{for f in listfiles(app, dir['name'], regexp=dir['reg'] ):}}
|
||||
{{id="%s__" % dir['name'] + f.replace('.','__')}}
|
||||
{{current_file = request.args(len(request.args) - 1)}}
|
||||
<li class="{{='active' if current_file==f else ''}}">
|
||||
{{=editfile(dir['name'], f, dict(id=id))}}
|
||||
</li>
|
||||
{{pass}}
|
||||
</ul>
|
||||
</li>
|
||||
{{pass}}
|
||||
</ul>
|
||||
|
||||
<form action="{{=URL('edit',args=filename)}}" method="post" name="editform" id="editform" class="span10">
|
||||
<div class="editor-bar-column">
|
||||
<label>{{=T('Save file:')}}</label>
|
||||
<a value="save" name="save" onclick="return doClickSave();" class="icon saveicon" style="background-image: -webkit-linear-gradient(top,white,#E6E6E6);">
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
{{extend 'layout.html'}}
|
||||
{{import os}}
|
||||
|
||||
{{def tree(path):}}
|
||||
<input type="checkbox" onclick="jQuery(this).parent().find(':checkbox').attr('checked',this.checked)" checked="checked"/>
|
||||
<a href="#" onclick="jQuery(this).next().slideToggle();return false;">
|
||||
{{=path[len(base):] or '/%s' % app}}
|
||||
</a>
|
||||
<ul class="collapsible">
|
||||
{{for file in files[path]['files']:}}
|
||||
<li style="list-style-type: none;">
|
||||
{{p = os.path.relpath(os.path.join(path,file),base)}}
|
||||
<input type="checkbox" value="{{=p}}" name="file" checked="checked"/>
|
||||
{{=file}}
|
||||
</li>
|
||||
{{pass}}
|
||||
{{for dir in files[path]['folders']:}}
|
||||
<li style="list-style-type: none;">
|
||||
{{tree(os.path.join(path,dir))}}
|
||||
</li>
|
||||
{{pass}}
|
||||
</ul>
|
||||
{{return}}
|
||||
|
||||
<form action="{{=URL(args=request.args)}}" method="POST">
|
||||
<h2>{{=T('Select Files to Package')}}</h2>
|
||||
<input type="submit" value="{{=T('Download .w2p')}}" class="btn"/>
|
||||
<div style="margin-top:20px">
|
||||
{{tree(base)}}
|
||||
</div>
|
||||
</form>
|
||||
<script>jQuery(function(){jQuery('.collapsible').hide();});</script>
|
||||
@@ -25,6 +25,7 @@
|
||||
{{buttons.append((URL('errors',args=a), T("Errors")))}}
|
||||
{{buttons.append((URL('cleanup',args=a), T("Clean")))}}
|
||||
{{buttons.append((URL('pack',args=a), T("Pack all")))}}
|
||||
{{buttons.append((URL('pack_custom',args=a), T("Pack custom")))}}
|
||||
{{if not os.path.exists('applications/%s/compiled' % a):}}
|
||||
{{buttons.append((URL('compile_app',args=a), T("Compile")))}}
|
||||
{{else:}}
|
||||
@@ -144,14 +145,8 @@
|
||||
<p>{{=button(URL('wizard','index'), T('Start wizard'))}}<br/>
|
||||
{{=T("(requires internet access, experimental)")}}</p>
|
||||
</div> <!-- /APP WIZARD -->
|
||||
{{if TWITTER_HASH:}}
|
||||
<!-- TWITTER -->
|
||||
<div class="box">
|
||||
<h4>{{=T("%s Recent Tweets"%TWITTER_HASH)}}</h4>
|
||||
<div id="tweets">{{=T('loading...')}}</div>
|
||||
<script>jQuery(document).ready(function(){jQuery('#tweets').load('{{=URL('twitter.load')}}');});</script>
|
||||
</div> <!-- /TWITTER -->
|
||||
{{pass}}
|
||||
<a class="twitter-timeline" href="https://twitter.com/web2py" data-widget-id="340456915207327745">Tweets by @web2py</a>
|
||||
<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+"://platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs");</script>
|
||||
</div>
|
||||
</div> <!-- /sidebar -->
|
||||
</div> <!-- /row-fluid
|
||||
|
||||
@@ -36,7 +36,7 @@ Tweet attributes
|
||||
<td><img src="{{=t['profile_image_url_https']}}"/></td>
|
||||
<td>
|
||||
<a href="http://twitter.com/{{=t['from_user']}}">{{=t["from_user_name"]}}</a>:
|
||||
{{=XML(hashtag.sub('<a href="http://twitter.com/\\g<2>">\\g<1>\\g<2></a>',link.sub('<a href="\\g<0>">\\g<0></a>',t["text"])),sanitize=True)}}
|
||||
{{=XML(hashtag.sub('<a href="http://twitter.com/\\g<2>">\\g<1>\\g<2></a>',link.sub('<a href="\\g<0>">\\g<0></a>',t["text"].encode('utf8'))),sanitize=True)}}
|
||||
</td>
|
||||
</tr>
|
||||
{{ pass }}
|
||||
|
||||
@@ -8,9 +8,7 @@
|
||||
<title>{{=response.title or URL()}}</title>
|
||||
{{
|
||||
response.files.append(URL('static','css/bootstrap.min.css'))
|
||||
#response.files.append(URL('static','css/styles.css'))
|
||||
response.files.append(URL('static','css/bootstrap_essentials.css'))
|
||||
# response.files.append(URL('static','css/bootstrap_adapters.css'))
|
||||
response.files.append(URL('static','css/bootstrap-responsive.min.css'))
|
||||
}}
|
||||
{{include 'web2py_ajax.html'}}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
var w2p_ajax_confirm_message = "{{=T('Are you sure you want to delete this object?')}}";
|
||||
var w2p_ajax_date_format = "{{=T('%Y-%m-%d')}}";
|
||||
var w2p_ajax_datetime_format = "{{=T('%Y-%m-%d %H:%M:%S')}}";
|
||||
var ajax_error_500 = '{{=XML(T('An error occured, please %s the page') % A(T('reload'), _href=URL(args=request.args, vars=request.vars))) }}'
|
||||
var ajax_error_500 = '{{=XML(T('An error occured, please %s the page') % A(T('reload'), _href=URL(args=request.args, vars=request.get_vars))) }}'
|
||||
//--></script>
|
||||
{{
|
||||
response.files.insert(0,URL('static','js/jquery.js'))
|
||||
|
||||
@@ -37,14 +37,20 @@ if request.env.http_x_forwarded_for or request.is_https:
|
||||
elif (remote_addr not in hosts) and (remote_addr != "127.0.0.1"):
|
||||
raise HTTP(200, T('appadmin is disabled because insecure channel'))
|
||||
|
||||
if (request.application == 'admin' and not session.authorized) or \
|
||||
(request.application != 'admin' and not gluon.fileutils.check_credentials(request)):
|
||||
if request.function in ('auth_manage','manage') and 'auth' in globals():
|
||||
auth.requires_membership(auth.settings.manager_group_role)(lambda: None)()
|
||||
menu = False
|
||||
elif (request.application == 'admin' and not session.authorized) or \
|
||||
(request.application != 'admin' and not gluon.fileutils.check_credentials(request)):
|
||||
redirect(URL('admin', 'default', 'index',
|
||||
vars=dict(send=URL(args=request.args, vars=request.vars))))
|
||||
else:
|
||||
menu = True
|
||||
|
||||
ignore_rw = True
|
||||
response.view = 'appadmin.html'
|
||||
response.menu = [[T('design'), False, URL('admin', 'default', 'design',
|
||||
if menu:
|
||||
response.menu = [[T('design'), False, URL('admin', 'default', 'design',
|
||||
args=[request.application])], [T('db'), False,
|
||||
URL('index')], [T('state'), False,
|
||||
URL('state')], [T('cache'), False,
|
||||
@@ -54,6 +60,10 @@ response.menu = [[T('design'), False, URL('admin', 'default', 'design',
|
||||
# ## auxiliary functions
|
||||
# ###########################################################
|
||||
|
||||
if False and request.tickets_db:
|
||||
from gluon.restricted import TicketStorage
|
||||
ts = TicketStorage()
|
||||
ts._get_table(request.tickets_db, ts.tablename, request.application)
|
||||
|
||||
def get_databases(request):
|
||||
dbs = {}
|
||||
@@ -275,14 +285,15 @@ def update():
|
||||
(db, table) = get_table(request)
|
||||
keyed = hasattr(db[table], '_primarykey')
|
||||
record = None
|
||||
db[table]._common_filter = None
|
||||
if keyed:
|
||||
key = [f for f in request.vars if f in db[table]._primarykey]
|
||||
if key:
|
||||
record = db(db[table][key[0]] == request.vars[key[
|
||||
0]], ignore_common_filters=True).select().first()
|
||||
0]]).select().first()
|
||||
else:
|
||||
record = db(db[table].id == request.args(
|
||||
2), ignore_common_filters=True).select().first()
|
||||
2)).select().first()
|
||||
|
||||
if not record:
|
||||
qry = query_by_table_type(table, db)
|
||||
@@ -568,3 +579,35 @@ def bg_graph_model():
|
||||
|
||||
def graph_model():
|
||||
return dict(databases=databases, pgv=pgv)
|
||||
|
||||
def auth_manage():
|
||||
tablename = request.args(0)
|
||||
if not tablename or not tablename in auth.db.tables:
|
||||
return dict()
|
||||
table = auth.db[tablename]
|
||||
formname = '%s_grid' % tablename
|
||||
if tablename == auth.settings.table_user_name:
|
||||
auth.settings.table_user._plural = T('Users')
|
||||
auth.settings.table_membership._plural = T('Roles')
|
||||
auth.settings.table_membership._id.readable = False
|
||||
auth.settings.table_membership.user_id.label = T('User')
|
||||
auth.settings.table_membership.group_id.label = T('Role')
|
||||
grid = SQLFORM.smartgrid(table, args=request.args[:1], user_signature=True,
|
||||
linked_tables=[auth.settings.table_membership_name],
|
||||
maxtextlength=1000, formname=formname)
|
||||
else:
|
||||
table._id.readable = False
|
||||
auth.settings.table_permission.group_id.label = T('Role')
|
||||
auth.settings.table_permission.name.label = T('Permission')
|
||||
orderby = 'role' if table == auth.settings.table_group_name else 'group_id'
|
||||
grid = SQLFORM.grid(table, args=request.args[:1], orderby=table[orderby],
|
||||
user_signature=True, maxtextlength=1000, formname=formname)
|
||||
return grid if request.extension=='load' else dict(grid=grid)
|
||||
|
||||
def manage():
|
||||
tablename = request.args(0)
|
||||
if tablename in auth.db.tables:
|
||||
grid = SQLFORM.smartgrid(auth.db[tablename], args=request.args[:1])
|
||||
else:
|
||||
return dict()
|
||||
return grid if request.extension=='load' else dict(grid=grid)
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
session.connect(request,response,cookie_key='yoursecret')
|
||||
@@ -47,7 +47,7 @@ Here is a more complex complete application that lets the visitor upload images
|
||||
``
|
||||
db=DAL('sqlite://storage.db')
|
||||
db.define_table('image',
|
||||
Field('name'),
|
||||
Field('name', notnull=True),
|
||||
Field('file','upload'))
|
||||
``:code_python
|
||||
|
||||
@@ -55,10 +55,10 @@ db.define_table('image',
|
||||
|
||||
``
|
||||
def index():
|
||||
form = SQLFORM(db.image)
|
||||
if form.process().accepted:
|
||||
form = SQLFORM(db.image).process()
|
||||
if form.accepted:
|
||||
response.flash = 'image uploaded'
|
||||
return dict(form = form)""",counter=None,_class='boxCode')}}
|
||||
return locals()
|
||||
``:code_python
|
||||
|
||||
### In View
|
||||
@@ -66,7 +66,7 @@ def index():
|
||||
``
|
||||
{{extend 'layout.html'}}
|
||||
<h1>Image upload form</h1>
|
||||
{{form}}
|
||||
{{=form}}
|
||||
``:code_python
|
||||
|
||||
Uploaded images are safely renamed to avoid directory traversal vulnerabilities, stored on the filesystem (or database) and a corresponding entry is inserted in the database, linking the file. A built-in mechanism prevents involuntary double form submission. All DB IO is transaction safe by default. Any exception in the code causes the transaction to rollback.
|
||||
|
||||
@@ -92,7 +92,7 @@ div.flash {
|
||||
position:fixed;
|
||||
padding:10px;
|
||||
top:48px;
|
||||
right:50px;
|
||||
right:250px;
|
||||
min-width:280px;
|
||||
opacity:0.95;
|
||||
margin:0px 0px 10px 10px;
|
||||
@@ -191,6 +191,7 @@ div.error {
|
||||
.web2py_grid {width:100%}
|
||||
.web2py_grid table {width:100%}
|
||||
.web2py_grid tbody td {padding:2px 5px 2px 5px; vertical-align: middle;}
|
||||
.web2py_grid .web2py_form td {vertical-align: top;}
|
||||
|
||||
.web2py_grid thead th,.web2py_grid tfoot td {
|
||||
background-color:#EAEAEA;
|
||||
|
||||
@@ -102,6 +102,7 @@ td.w2p_fl,td.w2p_fc {padding:0;}
|
||||
==============================================================*/
|
||||
|
||||
/* because web2py handles this via js */
|
||||
textarea { width:90%}
|
||||
.hidden{visibility:visible;}
|
||||
/* right folder for bootstrap black images/icons */
|
||||
[class^="icon-"],[class*=" icon-"]{
|
||||
|
||||
+6
-2
File diff suppressed because one or more lines are too long
@@ -35,6 +35,7 @@ function web2py_ajax_init(target) {
|
||||
jQuery('.hidden', target).hide();
|
||||
jQuery('.error', target).hide().slideDown('slow');
|
||||
web2py_ajax_fields(target);
|
||||
web2py_show_if(target);
|
||||
};
|
||||
|
||||
function web2py_event_handlers() {
|
||||
@@ -216,3 +217,26 @@ function web2py_validate_entropy(myfield, req_entropy) {
|
||||
if(!myfield.hasClass('entropy_check')) myfield.on('keyup', validator).on('keydown', validator).addClass('entropy_check');
|
||||
}
|
||||
|
||||
function web2py_show_if(target) {
|
||||
var triggers = {};
|
||||
var show_if = function () {
|
||||
var t = jQuery(this);
|
||||
var id = t.attr('id');
|
||||
t.attr('value', t.val());
|
||||
for(var k = 0; k < triggers[id].length; k++) {
|
||||
var dep = jQuery('#' + triggers[id][k], target);
|
||||
var tr = jQuery('#' + triggers[id][k] + '__row', target);
|
||||
if(t.is(dep.attr('data-show-if'))) tr.slideDown();
|
||||
else tr.hide();
|
||||
}
|
||||
};
|
||||
jQuery('[data-show-trigger]', target).each(function () {
|
||||
var name = jQuery(this).attr('data-show-trigger');
|
||||
if(!triggers[name]) triggers[name] = [];
|
||||
triggers[name].push(jQuery(this).attr('id'));
|
||||
});
|
||||
for(var name in triggers) {
|
||||
jQuery('#' + name, target).change(show_if).keyup(show_if);
|
||||
show_if.call(jQuery('#' + name, target));
|
||||
};
|
||||
}
|
||||
@@ -8,21 +8,28 @@ jQuery(function(){
|
||||
if(jQuery(this).find('ul').length)
|
||||
jQuery(this).addClass('dropdown-submenu');
|
||||
});
|
||||
function adjust_height_of_collapsed_nav() {
|
||||
var cn = jQuery('div.collapse');
|
||||
if (cn.get(0)) {
|
||||
var cnh = cn.get(0).style.height;
|
||||
if (cnh>'0px'){
|
||||
cn.css('height','auto');
|
||||
}
|
||||
}
|
||||
}
|
||||
function hoverMenu(){
|
||||
var wid = document.documentElement.clientWidth; //faster than $(window).width() and cross browser
|
||||
if (wid>=980){
|
||||
jQuery('ul.nav a.dropdown-toggle').parent().hover(function(){
|
||||
mi = jQuery(this).addClass('open');
|
||||
mi.children('.dropdown-menu').stop(true, true).delay(200).fadeIn(400);
|
||||
}, function(){
|
||||
mi = jQuery(this);
|
||||
mi.children('.dropdown-menu').stop(true, true).delay(200).fadeOut(function(){mi.removeClass('open')});
|
||||
});
|
||||
};
|
||||
jQuery('ul.nav a.dropdown-toggle').parent().hover(function(){
|
||||
adjust_height_of_collapsed_nav();
|
||||
mi = jQuery(this).addClass('open');
|
||||
mi.children('.dropdown-menu').stop(true, true).delay(200).fadeIn(400);
|
||||
}, function(){
|
||||
mi = jQuery(this);
|
||||
mi.children('.dropdown-menu').stop(true, true).delay(200).fadeOut(function(){mi.removeClass('open')});
|
||||
});
|
||||
}
|
||||
hoverMenu(); // first page load
|
||||
jQuery(window).resize(hoverMenu); // on resize event
|
||||
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');
|
||||
});
|
||||
});
|
||||
@@ -247,3 +247,39 @@
|
||||
{{=IMG(_src=URL('appadmin', 'bg_graph_model'))}}
|
||||
{{pass}}
|
||||
{{pass}}
|
||||
|
||||
{{if request.function == 'auth_manage':}}
|
||||
<h2>{{=T('Manage Access Control')}}</h2>
|
||||
<ul class="nav nav-tabs">
|
||||
<li class="active"><a href="#users" data-toggle="tab">Users</a></li>
|
||||
<li><a href="#roles" data-toggle="tab">Roles</a></li>
|
||||
<li><a href="#permissions" data-toggle="tab">Permissions</a></li>
|
||||
</ul>
|
||||
|
||||
<div class="tab-content">
|
||||
<div class="tab-pane active" id="users">
|
||||
{{=LOAD(f='auth_manage.load', args=auth.settings.table_user_name,ajax=True)}}
|
||||
</div>
|
||||
<div class="tab-pane" id="roles">
|
||||
{{=LOAD(f='auth_manage.load', args=auth.settings.table_group_name,ajax=True)}}
|
||||
</div>
|
||||
<div class="tab-pane" id="permissions">
|
||||
{{=LOAD(f='auth_manage.load', args=auth.settings.table_permission_name,ajax=True)}}
|
||||
</div>
|
||||
</div>
|
||||
{{elif request.function == 'manage':}}
|
||||
<h2>{{=T('Manage Access Control')}}</h2>
|
||||
<ul class="nav nav-tabs">
|
||||
{{for k,tablename in enumerate(auth.db.tables):}}
|
||||
<li><a href="#table-{{=tablename}}" data-toggle="tab">{{=tablename}}</a></li>
|
||||
{{pass}}
|
||||
</ul>
|
||||
|
||||
<div class="tab-content">
|
||||
{{for tablename in auth.db.tables:}}
|
||||
<div class="tab-pane" id="table-{{=tablename}}">
|
||||
{{=LOAD(f='manage.load', args=tablename,ajax=True)}}
|
||||
</div>
|
||||
{{pass}}
|
||||
</div>
|
||||
{{pass}}
|
||||
|
||||
@@ -43,7 +43,7 @@ random.shuffle(quotes)
|
||||
<a href="http://www.infoworld.com/slideshow/24605/infoworlds-2012-technology-of-the-year-award-winners-183313#slide23"><img src="{{=URL('static','images/infoworld2012.jpeg')}}" width="200px"/></a><br/>
|
||||
<a class="btn btn-danger" href="{{=URL('download')}}" style="margin-top:10px; width:180px; color:white">Download Now</a><br/>
|
||||
<a class="btn btn-danger" href="http://web2py.com/demo_admin" style="margin-top:10px; width:180px; color:white">Online Demo</a><br/>
|
||||
<a class="btn btn-danger" href="http://web2py.com/poweredby" style="margin-top:10px; width:180px; color:white">Sites Powereb by web2py</a>
|
||||
<a class="btn btn-danger" href="http://web2py.com/poweredby" style="margin-top:10px; width:180px; color:white">Sites Powered by web2py</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
var w2p_ajax_confirm_message = "{{=T('Are you sure you want to delete this object?')}}";
|
||||
var w2p_ajax_date_format = "{{=T('%Y-%m-%d')}}";
|
||||
var w2p_ajax_datetime_format = "{{=T('%Y-%m-%d %H:%M:%S')}}";
|
||||
var ajax_error_500 = '{{=XML(T('An error occured, please %s the page') % A(T('reload'), _href=URL(args=request.args, vars=request.vars))) }}'
|
||||
var ajax_error_500 = '{{=XML(T('An error occured, please %s the page') % A(T('reload'), _href=URL(args=request.args, vars=request.get_vars))) }}'
|
||||
//--></script>
|
||||
{{
|
||||
response.files.insert(0,URL('static','js/jquery.js'))
|
||||
|
||||
@@ -37,14 +37,20 @@ if request.env.http_x_forwarded_for or request.is_https:
|
||||
elif (remote_addr not in hosts) and (remote_addr != "127.0.0.1"):
|
||||
raise HTTP(200, T('appadmin is disabled because insecure channel'))
|
||||
|
||||
if (request.application == 'admin' and not session.authorized) or \
|
||||
(request.application != 'admin' and not gluon.fileutils.check_credentials(request)):
|
||||
if request.function in ('auth_manage','manage') and 'auth' in globals():
|
||||
auth.requires_membership(auth.settings.manager_group_role)(lambda: None)()
|
||||
menu = False
|
||||
elif (request.application == 'admin' and not session.authorized) or \
|
||||
(request.application != 'admin' and not gluon.fileutils.check_credentials(request)):
|
||||
redirect(URL('admin', 'default', 'index',
|
||||
vars=dict(send=URL(args=request.args, vars=request.vars))))
|
||||
else:
|
||||
menu = True
|
||||
|
||||
ignore_rw = True
|
||||
response.view = 'appadmin.html'
|
||||
response.menu = [[T('design'), False, URL('admin', 'default', 'design',
|
||||
if menu:
|
||||
response.menu = [[T('design'), False, URL('admin', 'default', 'design',
|
||||
args=[request.application])], [T('db'), False,
|
||||
URL('index')], [T('state'), False,
|
||||
URL('state')], [T('cache'), False,
|
||||
@@ -54,6 +60,10 @@ response.menu = [[T('design'), False, URL('admin', 'default', 'design',
|
||||
# ## auxiliary functions
|
||||
# ###########################################################
|
||||
|
||||
if False and request.tickets_db:
|
||||
from gluon.restricted import TicketStorage
|
||||
ts = TicketStorage()
|
||||
ts._get_table(request.tickets_db, ts.tablename, request.application)
|
||||
|
||||
def get_databases(request):
|
||||
dbs = {}
|
||||
@@ -275,14 +285,15 @@ def update():
|
||||
(db, table) = get_table(request)
|
||||
keyed = hasattr(db[table], '_primarykey')
|
||||
record = None
|
||||
db[table]._common_filter = None
|
||||
if keyed:
|
||||
key = [f for f in request.vars if f in db[table]._primarykey]
|
||||
if key:
|
||||
record = db(db[table][key[0]] == request.vars[key[
|
||||
0]], ignore_common_filters=True).select().first()
|
||||
0]]).select().first()
|
||||
else:
|
||||
record = db(db[table].id == request.args(
|
||||
2), ignore_common_filters=True).select().first()
|
||||
2)).select().first()
|
||||
|
||||
if not record:
|
||||
qry = query_by_table_type(table, db)
|
||||
@@ -568,3 +579,35 @@ def bg_graph_model():
|
||||
|
||||
def graph_model():
|
||||
return dict(databases=databases, pgv=pgv)
|
||||
|
||||
def auth_manage():
|
||||
tablename = request.args(0)
|
||||
if not tablename or not tablename in auth.db.tables:
|
||||
return dict()
|
||||
table = auth.db[tablename]
|
||||
formname = '%s_grid' % tablename
|
||||
if tablename == auth.settings.table_user_name:
|
||||
auth.settings.table_user._plural = T('Users')
|
||||
auth.settings.table_membership._plural = T('Roles')
|
||||
auth.settings.table_membership._id.readable = False
|
||||
auth.settings.table_membership.user_id.label = T('User')
|
||||
auth.settings.table_membership.group_id.label = T('Role')
|
||||
grid = SQLFORM.smartgrid(table, args=request.args[:1], user_signature=True,
|
||||
linked_tables=[auth.settings.table_membership_name],
|
||||
maxtextlength=1000, formname=formname)
|
||||
else:
|
||||
table._id.readable = False
|
||||
auth.settings.table_permission.group_id.label = T('Role')
|
||||
auth.settings.table_permission.name.label = T('Permission')
|
||||
orderby = 'role' if table == auth.settings.table_group_name else 'group_id'
|
||||
grid = SQLFORM.grid(table, args=request.args[:1], orderby=table[orderby],
|
||||
user_signature=True, maxtextlength=1000, formname=formname)
|
||||
return grid if request.extension=='load' else dict(grid=grid)
|
||||
|
||||
def manage():
|
||||
tablename = request.args(0)
|
||||
if tablename in auth.db.tables:
|
||||
grid = SQLFORM.smartgrid(auth.db[tablename], args=request.args[:1])
|
||||
else:
|
||||
return dict()
|
||||
return grid if request.extension=='load' else dict(grid=grid)
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
# this file is released under public domain and you can use without limitations
|
||||
|
||||
#########################################################################
|
||||
## This is a samples controller
|
||||
## This is a sample controller
|
||||
## - index is the default action of any application
|
||||
## - user is required for authentication and authorization
|
||||
## - download is for downloading files uploaded in the db (does streaming)
|
||||
@@ -31,6 +31,7 @@ def user():
|
||||
http://..../[app]/default/user/profile
|
||||
http://..../[app]/default/user/retrieve_password
|
||||
http://..../[app]/default/user/change_password
|
||||
http://..../[app]/default/user/manage_users (requires membership in
|
||||
use @auth.requires_login()
|
||||
@auth.requires_membership('group name')
|
||||
@auth.requires_permission('read','table name',record_id)
|
||||
@@ -38,7 +39,7 @@ def user():
|
||||
"""
|
||||
return dict(form=auth())
|
||||
|
||||
|
||||
@cache.action()
|
||||
def download():
|
||||
"""
|
||||
allows downloading of uploaded files
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
'!langcode!': 'cs-cz',
|
||||
'!langname!': 'čeština',
|
||||
'"update" is an optional expression like "field1=\'newvalue\'". You cannot update or delete the results of a JOIN': 'Kolonka "Upravit" je nepovinný výraz, například "pole1=\'nováhodnota\'". Výsledky databázového JOINu nemůžete mazat ani upravovat.',
|
||||
'"User Exception" debug mode. An error ticket could be issued!': '"User Exception" debug mode. An error ticket could be issued!',
|
||||
'%%{Row} in Table': '%%{řádek} v tabulce',
|
||||
'%%{Row} selected': 'označených %%{řádek}',
|
||||
'%s %%{row} deleted': '%s smazaných %%{záznam}',
|
||||
@@ -11,6 +12,7 @@
|
||||
'%Y-%m-%d': '%d.%m.%Y',
|
||||
'%Y-%m-%d %H:%M:%S': '%d.%m.%Y %H:%M:%S',
|
||||
'(requires internet access)': '(vyžaduje připojení k internetu)',
|
||||
'(requires internet access, experimental)': '(requires internet access, experimental)',
|
||||
'(something like "it-it")': '(například "cs-cs")',
|
||||
'@markmin\x01(file **gluon/contrib/plural_rules/%s.py** is not found)': '(soubor **gluon/contrib/plural_rules/%s.py** nenalezen)',
|
||||
'@markmin\x01Searching: **%s** %%{file}': 'Hledání: **%s** %%{soubor}',
|
||||
@@ -19,15 +21,18 @@
|
||||
'Access Control': 'Řízení přístupu',
|
||||
'Add breakpoint': 'Přidat bod přerušení',
|
||||
'Additional code for your application': 'Další kód pro Vaši aplikaci',
|
||||
'Admin design page': 'Admin design page',
|
||||
'Admin language': 'jazyk rozhraní',
|
||||
'Administrative interface': 'pro administrátorské rozhraní klikněte sem',
|
||||
'Administrative Interface': 'Administrátorské rozhraní',
|
||||
'administrative interface': 'rozhraní pro správu',
|
||||
'Administrator Password:': 'Administrátorské heslo:',
|
||||
'Ajax Recipes': 'Recepty s ajaxem',
|
||||
'An error occured, please %s the page': 'An error occured, please %s the page',
|
||||
'and rename it:': 'a přejmenovat na:',
|
||||
'appadmin': 'appadmin',
|
||||
'appadmin is disabled because insecure channel': 'appadmin je zakázaná bez zabezpečeného spojení',
|
||||
'Application': 'Application',
|
||||
'application "%s" uninstalled': 'application "%s" odinstalována',
|
||||
'application compiled': 'aplikace zkompilována',
|
||||
'Application name:': 'Název aplikace:',
|
||||
@@ -36,8 +41,13 @@
|
||||
'Are you sure you want to delete this object?': 'Opravdu chcete odstranit tento objekt?',
|
||||
'Are you sure you want to uninstall application "%s"?': 'Opravdu chcete odinstalovat aplikaci "%s"?',
|
||||
'arguments': 'arguments',
|
||||
'at char %s': 'at char %s',
|
||||
'at line %s': 'at line %s',
|
||||
'ATTENTION:': 'ATTENTION:',
|
||||
'ATTENTION: TESTING IS NOT THREAD SAFE SO DO NOT PERFORM MULTIPLE TESTS CONCURRENTLY.': 'ATTENTION: TESTING IS NOT THREAD SAFE SO DO NOT PERFORM MULTIPLE TESTS CONCURRENTLY.',
|
||||
'Available Databases and Tables': 'Dostupné databáze a tabulky',
|
||||
'back': 'zpět',
|
||||
'Back to wizard': 'Back to wizard',
|
||||
'Basics': 'Basics',
|
||||
'Begin': 'Začít',
|
||||
'breakpoint': 'bod přerušení',
|
||||
@@ -51,7 +61,8 @@
|
||||
'can be a git repo': 'může to být git repo',
|
||||
'Cancel': 'Storno',
|
||||
'Cannot be empty': 'Nemůže být prázdné',
|
||||
'Change admin password': 'Změnit heslo pro strávu aplikací',
|
||||
'Change Admin Password': 'Změnit heslo pro správu',
|
||||
'Change admin password': 'Změnit heslo pro správu aplikací',
|
||||
'Change password': 'Změna hesla',
|
||||
'check all': 'vše označit',
|
||||
'Check for upgrades': 'Zkusit aktualizovat',
|
||||
@@ -94,6 +105,7 @@
|
||||
'data uploaded': 'data nahrána',
|
||||
'Database': 'Rozhraní databáze',
|
||||
'Database %s select': 'databáze %s výběr',
|
||||
'Database administration': 'Database administration',
|
||||
'database administration': 'správa databáze',
|
||||
'Date and Time': 'Datum a čas',
|
||||
'day': 'den',
|
||||
@@ -104,6 +116,7 @@
|
||||
'Delete': 'Smazat',
|
||||
'delete': 'smazat',
|
||||
'delete all checked': 'smazat vše označené',
|
||||
'delete plugin': 'delete plugin',
|
||||
'Delete this file (you will be asked to confirm deletion)': 'Smazat tento soubor (budete požádán o potvrzení mazání)',
|
||||
'Delete:': 'Smazat:',
|
||||
'deleted after first hit': 'smazat po prvním dosažení',
|
||||
@@ -114,9 +127,9 @@
|
||||
'Deployment Recipes': 'Postupy pro deployment',
|
||||
'Description': 'Popis',
|
||||
'design': 'návrh',
|
||||
'Detailed traceback description': 'Detailed traceback description',
|
||||
'details': 'details',
|
||||
'direction: ltr': 'direction: ltr',
|
||||
'Detailed traceback description': 'Podrobný výpis prostředí',
|
||||
'details': 'podrobnosti',
|
||||
'direction: ltr': 'směr: ltr',
|
||||
'Disable': 'Zablokovat',
|
||||
'DISK': 'DISK',
|
||||
'Disk Cache Keys': 'Klíče diskové cache',
|
||||
@@ -132,29 +145,37 @@
|
||||
'Edit': 'Upravit',
|
||||
'edit all': 'edit all',
|
||||
'Edit application': 'Správa aplikace',
|
||||
'edit controller': 'edit controller',
|
||||
'Edit current record': 'Upravit aktuální záznam',
|
||||
'Edit Profile': 'Upravit profil',
|
||||
'edit views:': 'upravit pohled:',
|
||||
'Editing file "%s"': 'Úprava souboru "%s"',
|
||||
'Editing Language file': 'Úprava jazykového souboru',
|
||||
'Editing Plural Forms File': 'Editing Plural Forms File',
|
||||
'Email and SMS': 'Email a SMS',
|
||||
'Enable': 'Odblokovat',
|
||||
'enter a number between %(min)g and %(max)g': 'zadejte číslo mezi %(min)g a %(max)g',
|
||||
'enter an integer between %(min)g and %(max)g': 'zadejte celé číslo mezi %(min)g a %(max)g',
|
||||
'Error': 'Chyba',
|
||||
'Error logs for "%(app)s"': 'Seznam výskytu chyb pro aplikaci "%(app)s"',
|
||||
'Error snapshot': 'Error snapshot',
|
||||
'Error ticket': 'Error ticket',
|
||||
'Error snapshot': 'Snapshot chyby',
|
||||
'Error ticket': 'Ticket chyby',
|
||||
'Errors': 'Chyby',
|
||||
'Exception instance attributes': 'Exception instance attributes',
|
||||
'Exception %(extype)s: %(exvalue)s': 'Exception %(extype)s: %(exvalue)s',
|
||||
'Exception %s': 'Exception %s',
|
||||
'Exception instance attributes': 'Prvky instance výjimky',
|
||||
'Expand Abbreviation': 'Expand Abbreviation',
|
||||
'export as csv file': 'exportovat do .csv souboru',
|
||||
'exposes': 'vystavuje',
|
||||
'exposes:': 'vystavuje funkce:',
|
||||
'extends': 'rozšiřuje',
|
||||
'failed to compile file because:': 'soubor se nepodařilo zkompilovat, protože:',
|
||||
'FAQ': 'Často kladené dotazy',
|
||||
'File': 'Soubor',
|
||||
'file': 'soubor',
|
||||
'file "%(filename)s" created': 'file "%(filename)s" created',
|
||||
'file saved on %(time)s': 'soubor uložen %(time)s',
|
||||
'file saved on %s': 'soubor uložen %s',
|
||||
'Filename': 'Název souboru',
|
||||
'filter': 'filtr',
|
||||
'Find Next': 'Najít další',
|
||||
@@ -165,12 +186,15 @@
|
||||
'Forms and Validators': 'Formuláře a validátory',
|
||||
'Frames': 'Frames',
|
||||
'Free Applications': 'Aplikace zdarma',
|
||||
'Functions with no doctests will result in [passed] tests.': 'Functions with no doctests will result in [passed] tests.',
|
||||
'Generate': 'Vytvořit',
|
||||
'Get from URL:': 'Stáhnout z internetu:',
|
||||
'Git Pull': 'Git Pull',
|
||||
'Git Push': 'Git Push',
|
||||
'Globals##debug': 'Globální proměnné',
|
||||
'go!': 'OK!',
|
||||
'Goto': 'Goto',
|
||||
'graph model': 'graph model',
|
||||
'Group %(group_id)s created': 'Skupina %(group_id)s vytvořena',
|
||||
'Group ID': 'ID skupiny',
|
||||
'Groups': 'Skupiny',
|
||||
@@ -181,6 +205,8 @@
|
||||
'Home': 'Domovská stránka',
|
||||
'honored only if the expression evaluates to true': 'brát v potaz jen když se tato podmínka vyhodnotí kladně',
|
||||
'How did you get here?': 'Jak jste se sem vlastně dostal?',
|
||||
'If start the upgrade, be patient, it may take a while to download': 'If start the upgrade, be patient, it may take a while to download',
|
||||
'If the report above contains a ticket number it indicates a failure in executing the controller, before any attempt to execute the doctests. This is usually due to an indentation error or an error outside function code.\nA green title indicates that all tests (if defined) passed. In this case test results are not shown.': 'If the report above contains a ticket number it indicates a failure in executing the controller, before any attempt to execute the doctests. This is usually due to an indentation error or an error outside function code.\nA green title indicates that all tests (if defined) passed. In this case test results are not shown.',
|
||||
'import': 'import',
|
||||
'Import/Export': 'Import/Export',
|
||||
'includes': 'zahrnuje',
|
||||
@@ -190,8 +216,8 @@
|
||||
'inspect attributes': 'inspect attributes',
|
||||
'Install': 'Instalovat',
|
||||
'Installed applications': 'Nainstalované aplikace',
|
||||
'Interaction at %s line %s': 'Interaction at %s line %s',
|
||||
'Interactive console': 'Interactive console',
|
||||
'Interaction at %s line %s': 'Interakce v %s, na řádce %s',
|
||||
'Interactive console': 'Interaktivní příkazová řádka',
|
||||
'Internal State': 'Vnitřní stav',
|
||||
'Introduction': 'Úvod',
|
||||
'Invalid email': 'Neplatný email',
|
||||
@@ -203,6 +229,7 @@
|
||||
'It is %s %%{day} today.': 'Dnes je to %s %%{den}.',
|
||||
'Key': 'Klíč',
|
||||
'Key bindings': 'Vazby klíčů',
|
||||
'Key bindings for ZenCoding Plugin': 'Key bindings for ZenCoding Plugin',
|
||||
'languages': 'jazyky',
|
||||
'Languages': 'Jazyky',
|
||||
'Last name': 'Příjmení',
|
||||
@@ -227,6 +254,7 @@
|
||||
'Lost Password': 'Zapomněl jste heslo',
|
||||
'Lost password?': 'Zapomněl jste heslo?',
|
||||
'lost password?': 'zapomněl jste heslo?',
|
||||
'Manage': 'Manage',
|
||||
'Manage Cache': 'Manage Cache',
|
||||
'Menu Model': 'Model rozbalovací nabídky',
|
||||
'Models': 'Modely',
|
||||
@@ -237,6 +265,7 @@
|
||||
'modules': 'moduly',
|
||||
'My Sites': 'Správa aplikací',
|
||||
'Name': 'Jméno',
|
||||
'new application "%s" created': 'nová aplikace "%s" vytvořena',
|
||||
'New Application Wizard': 'Nový průvodce aplikací',
|
||||
'New application wizard': 'Nový průvodce aplikací',
|
||||
'New password': 'Nové heslo',
|
||||
@@ -245,13 +274,16 @@
|
||||
'New simple application': 'Vytvořit primitivní aplikaci',
|
||||
'next': 'next',
|
||||
'next 100 rows': 'dalších 100 řádků',
|
||||
'No databases in this application': 'V této aplikáci nejsou žádné databáze',
|
||||
'No databases in this application': 'V této aplikaci nejsou žádné databáze',
|
||||
'No Interaction yet': 'Ještě žádná interakce nenastala',
|
||||
'No ticket_storage.txt found under /private folder': 'Soubor ticket_storage.txt v adresáři /private nenalezen',
|
||||
'Object or table name': 'Objekt či tabulka',
|
||||
'Old password': 'Původní heslo',
|
||||
'online designer': 'online návrhář',
|
||||
'Online examples': 'Příklady online',
|
||||
'Open new app in new window': 'Open new app in new window',
|
||||
'or alternatively': 'or alternatively',
|
||||
'Or Get from URL:': 'Or Get from URL:',
|
||||
'or import from csv file': 'nebo importovat z .csv souboru',
|
||||
'Origin': 'Původ',
|
||||
'Original/Translation': 'Originál/Překlad',
|
||||
@@ -261,12 +293,16 @@
|
||||
'Overwrite installed app': 'Přepsat instalovanou aplikaci',
|
||||
'Pack all': 'Zabalit',
|
||||
'Pack compiled': 'Zabalit zkompilované',
|
||||
'pack plugin': 'pack plugin',
|
||||
'password': 'heslo',
|
||||
'Password': 'Heslo',
|
||||
"Password fields don't match": 'Hesla se neshodují',
|
||||
'Peeking at file': 'Peeking at file',
|
||||
'Please': 'Prosím',
|
||||
'Plugin "%s" in application': 'Plugin "%s" in application',
|
||||
'plugins': 'zásuvné moduly',
|
||||
'Plugins': 'Zásuvné moduly',
|
||||
'Plural Form #%s': 'Plural Form #%s',
|
||||
'Plural-Forms:': 'Množná čísla:',
|
||||
'Powered by': 'Poháněno',
|
||||
'Preface': 'Předmluva',
|
||||
@@ -292,6 +328,7 @@
|
||||
'Register': 'Zaregistrovat se',
|
||||
'Registration identifier': 'Registrační identifikátor',
|
||||
'Registration key': 'Registrační klíč',
|
||||
'reload': 'reload',
|
||||
'Reload routes': 'Znovu nahrát cesty',
|
||||
'Remember me (for 30 days)': 'Zapamatovat na 30 dní',
|
||||
'Remove compiled': 'Odstranit zkompilované',
|
||||
@@ -313,6 +350,7 @@
|
||||
"Run tests in this file (to run all files, you may also use the button labelled 'test')": "Spustí testy v tomto souboru (ke spuštění všech testů, použijte tlačítko 'test')",
|
||||
'Running on %s': 'Běží na %s',
|
||||
'Save': 'Uložit',
|
||||
'Save file:': 'Save file:',
|
||||
'Save via Ajax': 'Uložit pomocí Ajaxu',
|
||||
'Saved file hash:': 'hash uloženého souboru:',
|
||||
'Semantic': 'Modul semantic',
|
||||
@@ -321,6 +359,7 @@
|
||||
'session expired': 'session expired',
|
||||
'Set Breakpoint on %s at line %s: %s': 'Bod přerušení nastaven v souboru %s na řádce %s: %s',
|
||||
'shell': 'příkazová řádka',
|
||||
'Singular Form': 'Singular Form',
|
||||
'Site': 'Správa aplikací',
|
||||
'Size of cache:': 'Velikost cache:',
|
||||
'skip to generate': 'skip to generate',
|
||||
@@ -329,6 +368,7 @@
|
||||
'Start searching': 'Začít hledání',
|
||||
'Start wizard': 'Spustit průvodce',
|
||||
'state': 'stav',
|
||||
'Static': 'Static',
|
||||
'static': 'statické soubory',
|
||||
'Static files': 'Statické soubory',
|
||||
'Statistics': 'Statistika',
|
||||
@@ -345,6 +385,7 @@
|
||||
'Table name': 'Název tabulky',
|
||||
'Temporary': 'Dočasný',
|
||||
'test': 'test',
|
||||
'Testing application': 'Testing application',
|
||||
'The "query" is a condition like "db.table1.field1==\'value\'". Something like "db.table1.field1==db.table2.field2" results in a SQL JOIN.': '"Dotaz" je podmínka, například "db.tabulka1.pole1==\'hodnota\'". Podmínka "db.tabulka1.pole1==db.tabulka2.pole2" pak vytvoří SQL JOIN.',
|
||||
'The application logic, each URL path is mapped in one exposed function in the controller': 'Logika aplikace: každá URL je mapována na funkci vystavovanou kontrolérem.',
|
||||
'The Core': 'Jádro (The Core)',
|
||||
@@ -352,13 +393,19 @@
|
||||
'The output of the file is a dictionary that was rendered by the view %s': 'Výstup ze souboru je slovník, který se zobrazil v pohledu %s.',
|
||||
'The presentations layer, views are also known as templates': 'Prezentační vrstva: pohledy či templaty (šablony)',
|
||||
'The Views': 'Pohledy (The Views)',
|
||||
'There are no controllers': 'There are no controllers',
|
||||
'There are no modules': 'There are no modules',
|
||||
'There are no plugins': 'Žádné moduly nejsou instalovány.',
|
||||
'There are no private files': 'Žádné soukromé soubory neexistují.',
|
||||
'There are no static files': 'There are no static files',
|
||||
'There are no translators, only default language is supported': 'There are no translators, only default language is supported',
|
||||
'There are no views': 'There are no views',
|
||||
'These files are not served, they are only available from within your app': 'Tyto soubory jsou klientům nepřístupné. K dispozici jsou pouze v rámci aplikace.',
|
||||
'These files are served without processing, your images go here': 'Tyto soubory jsou servírovány bez přídavné logiky, sem patří např. obrázky.',
|
||||
'This App': 'Tato aplikace',
|
||||
'This is a copy of the scaffolding application': 'Toto je kopie aplikace skelet.',
|
||||
'This is an experimental feature and it needs more testing. If you decide to upgrade you do it at your own risk': 'This is an experimental feature and it needs more testing. If you decide to upgrade you do it at your own risk',
|
||||
'This is the %(filename)s template': 'This is the %(filename)s template',
|
||||
'this page to see if a breakpoint was hit and debug interaction is required.': 'tuto stránku, abyste uviděli, zda se dosáhlo bodu přerušení.',
|
||||
'Ticket': 'Ticket',
|
||||
'Ticket ID': 'Ticket ID',
|
||||
@@ -373,16 +420,24 @@
|
||||
'too short': 'Příliš krátké',
|
||||
'Traceback': 'Traceback',
|
||||
'Translation strings for the application': 'Překlad textů pro aplikaci',
|
||||
'try something like': 'try something like',
|
||||
'Try the mobile interface': 'Zkuste rozhraní pro mobilní zařízení',
|
||||
'try view': 'try view',
|
||||
'Twitter': 'Twitter',
|
||||
'Type python statement in here and hit Return (Enter) to execute it.': 'Type python statement 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': 'Unable to check for upgrades',
|
||||
'unable to parse csv file': 'csv soubor nedá sa zpracovat',
|
||||
'uncheck all': 'vše odznačit',
|
||||
'Uninstall': 'Odinstalovat',
|
||||
'update': 'aktualizovat',
|
||||
'update all languages': 'aktualizovat všechny jazyky',
|
||||
'Update:': 'Upravit:',
|
||||
'Upgrade': 'Upgrade',
|
||||
'upgrade now': 'upgrade now',
|
||||
'upgrade now to %s': 'upgrade now to %s',
|
||||
'upload': 'nahrát',
|
||||
'Upload': 'Upload',
|
||||
'Upload a package:': 'Nahrát balík:',
|
||||
'Upload and install packed application': 'Nahrát a instalovat zabalenou aplikaci',
|
||||
'upload file:': 'nahrát soubor:',
|
||||
@@ -409,6 +464,8 @@
|
||||
'web2py is up to date': 'Máte aktuální verzi web2py.',
|
||||
'web2py online debugger': 'Ladící online web2py program',
|
||||
'web2py Recent Tweets': 'Štěbetání na Twitteru o web2py',
|
||||
'web2py upgrade': 'web2py upgrade',
|
||||
'web2py upgraded; please restart it': 'web2py upgraded; please restart it',
|
||||
'Welcome': 'Vítejte',
|
||||
'Welcome to web2py': 'Vitejte ve web2py',
|
||||
'Welcome to web2py!': 'Vítejte ve web2py!',
|
||||
|
||||
@@ -8,23 +8,23 @@
|
||||
'%s selected': '%s seleccionado(s)',
|
||||
'%Y-%m-%d': '%Y-%m-%d',
|
||||
'%Y-%m-%d %H:%M:%S': '%Y-%m-%d %H:%M:%S',
|
||||
'(something like "it-it")': '(algo como "it-it")',
|
||||
'(something like "it-it")': '(algo como "eso-eso")',
|
||||
'A new version of web2py is available': 'Hay una nueva versión de web2py disponible',
|
||||
'A new version of web2py is available: %s': 'Hay una nueva versión de web2py disponible: %s',
|
||||
'about': 'acerca de',
|
||||
'About': 'Acerca de',
|
||||
'About application': 'Acerca de la aplicación',
|
||||
'Access Control': 'Access Control',
|
||||
'Access Control': 'Control de Acceso',
|
||||
'additional code for your application': 'código adicional para su aplicación',
|
||||
'admin disabled because no admin password': ' por falta de contraseña',
|
||||
'admin disabled because not supported on google app engine': 'admin deshabilitado, no es soportado en GAE',
|
||||
'admin disabled because unable to access password file': 'admin deshabilitado, imposible acceder al archivo con la contraseña',
|
||||
'Admin is disabled because insecure channel': 'Admin deshabilitado, el canal no es seguro',
|
||||
'Admin is disabled because unsecure channel': 'Admin deshabilitado, el canal no es seguro',
|
||||
'Administrative Interface': 'Administrative Interface',
|
||||
'Administrative Interface': 'Interfaz Administrativa',
|
||||
'Administrative interface': 'Interfaz administrativa',
|
||||
'Administrator Password:': 'Contraseña del Administrador:',
|
||||
'Ajax Recipes': 'Ajax Recipes',
|
||||
'Ajax Recipes': 'Recetas AJAX',
|
||||
'and rename it (required):': 'y renombrela (requerido):',
|
||||
'and rename it:': ' y renombrelo:',
|
||||
'appadmin': 'appadmin',
|
||||
@@ -33,41 +33,41 @@
|
||||
'application compiled': 'aplicación compilada',
|
||||
'application is compiled and cannot be designed': 'la aplicación está compilada y no puede ser modificada',
|
||||
'Are you sure you want to delete file "%s"?': '¿Está seguro que desea eliminar el archivo "%s"?',
|
||||
'Are you sure you want to delete this object?': 'Are you sure you want to delete this object?',
|
||||
'Are you sure you want to delete this object?': '¿Está seguro que desea borrar este objeto?',
|
||||
'Are you sure you want to uninstall application "%s"': '¿Está seguro que desea desinstalar la aplicación "%s"',
|
||||
'Are you sure you want to uninstall application "%s"?': '¿Está seguro que desea desinstalar la aplicación "%s"?',
|
||||
'ATTENTION: Login requires a secure (HTTPS) connection or running on localhost.': 'ATENCION: Inicio de sesión requiere una conexión segura (HTTPS) o localhost.',
|
||||
'ATTENTION: TESTING IS NOT THREAD SAFE SO DO NOT PERFORM MULTIPLE TESTS CONCURRENTLY.': 'ATENCION: NO EJECUTE VARIAS PRUEBAS SIMULTANEAMENTE, NO SON THREAD SAFE.',
|
||||
'ATTENTION: 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 está ejecutandose!',
|
||||
'Authentication': 'Autenticación',
|
||||
'Available Databases and Tables': 'Bases de datos y tablas disponibles',
|
||||
'Buy this book': 'Buy this book',
|
||||
'Buy this book': 'Compra este libro',
|
||||
'cache': 'cache',
|
||||
'Cache': 'Cache',
|
||||
'Cache Keys': 'Cache Keys',
|
||||
'Cache Keys': 'Llaves de la Cache',
|
||||
'cache, errors and sessions cleaned': 'cache, errores y sesiones eliminados',
|
||||
'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 create file': 'no es posible crear archivo',
|
||||
'cannot upload file "%(filename)s"': 'no es posible subir archivo "%(filename)s"',
|
||||
'Change Password': 'Cambie Contraseña',
|
||||
'change password': 'cambie contraseña',
|
||||
'Change Password': 'Cambie la contraseña',
|
||||
'change password': 'cambie la contraseña',
|
||||
'check all': 'marcar todos',
|
||||
'Check to delete': 'Marque para eliminar',
|
||||
'clean': 'limpiar',
|
||||
'Clear CACHE?': 'Clear CACHE?',
|
||||
'Clear DISK': 'Clear DISK',
|
||||
'Clear RAM': 'Clear RAM',
|
||||
'Clear CACHE?': '¿Limpiar CACHE?',
|
||||
'Clear DISK': '¿Limpiar DISCO',
|
||||
'Clear RAM': '¿Limpiar RAM',
|
||||
'click to check for upgrades': 'haga clic para buscar actualizaciones',
|
||||
'Client IP': 'IP del Cliente',
|
||||
'Community': 'Community',
|
||||
'Community': 'Comunidad',
|
||||
'compile': 'compilar',
|
||||
'compiled application removed': 'aplicación compilada removida',
|
||||
'Components and Plugins': 'Components and Plugins',
|
||||
'compiled application removed': 'aplicación compilada eliminada',
|
||||
'Components and Plugins': 'Componentes y Plugins',
|
||||
'Controller': 'Controlador',
|
||||
'Controllers': 'Controladores',
|
||||
'controllers': 'controladores',
|
||||
'Copyright': 'Derechos de autor',
|
||||
'Copyright': 'Copyright',
|
||||
'create file with filename:': 'cree archivo con nombre:',
|
||||
'Create new application': 'Cree una nueva aplicación',
|
||||
'create new application:': 'nombre de la nueva aplicación:',
|
||||
@@ -83,24 +83,24 @@
|
||||
'database administration': 'administración base de datos',
|
||||
'Date and Time': 'Fecha y Hora',
|
||||
'db': 'db',
|
||||
'DB Model': 'Modelo "db"',
|
||||
'DB Model': 'Modelo "DB"',
|
||||
'defines tables': 'define tablas',
|
||||
'Delete': 'Elimine',
|
||||
'Delete': 'Eliminar',
|
||||
'delete': 'eliminar',
|
||||
'delete all checked': 'eliminar marcados',
|
||||
'Delete:': 'Elimine:',
|
||||
'Delete:': 'Eliminar:',
|
||||
'Demo': 'Demo',
|
||||
'Deploy on Google App Engine': 'Instale en Google App Engine',
|
||||
'Deployment Recipes': 'Deployment Recipes',
|
||||
'Deploy on Google App Engine': 'Despliegue en Google App Engine',
|
||||
'Deployment Recipes': 'Recetas de despliegue',
|
||||
'Description': 'Descripción',
|
||||
'DESIGN': 'DISEÑO',
|
||||
'design': 'modificar',
|
||||
'Design for': 'Diseño para',
|
||||
'Design for': 'Diseño por',
|
||||
'DISK': 'DISK',
|
||||
'Disk Cache Keys': 'Disk Cache Keys',
|
||||
'Disk Cleared': 'Disk Cleared',
|
||||
'Disk Cache Keys': 'Llaves de Cache en Disco',
|
||||
'Disk Cleared': 'Disco limpiado',
|
||||
'Documentation': 'Documentación',
|
||||
"Don't know what to do?": "Don't know what to do?",
|
||||
"Don't know what to do?": "¿No sabe que hacer?",
|
||||
'done!': 'listo!',
|
||||
'Download': 'Download',
|
||||
'E-mail': 'Correo electrónico',
|
||||
@@ -115,14 +115,14 @@
|
||||
'Edit This App': 'Edite esta App',
|
||||
'Editing file': 'Editando archivo',
|
||||
'Editing file "%s"': 'Editando archivo "%s"',
|
||||
'Email and SMS': 'Email and SMS',
|
||||
'Email and SMS': 'Correo electrónico y SMS',
|
||||
'Error logs for "%(app)s"': 'Bitácora de errores en "%(app)s"',
|
||||
'Errors': 'Errors',
|
||||
'Errors': 'Errores',
|
||||
'errors': 'errores',
|
||||
'export as csv file': 'exportar como archivo CSV',
|
||||
'exposes': 'expone',
|
||||
'extends': 'extiende',
|
||||
'failed to reload module': 'recarga del módulo ha fallado',
|
||||
'failed to reload module': 'la recarga del módulo ha fallado',
|
||||
'FAQ': 'FAQ',
|
||||
'file "%(filename)s" created': 'archivo "%(filename)s" creado',
|
||||
'file "%(filename)s" deleted': 'archivo "%(filename)s" eliminado',
|
||||
@@ -134,17 +134,17 @@
|
||||
'file saved on %(time)s': 'archivo guardado %(time)s',
|
||||
'file saved on %s': 'archivo guardado %s',
|
||||
'First name': 'Nombre',
|
||||
'Forms and Validators': 'Forms and Validators',
|
||||
'Free Applications': 'Free Applications',
|
||||
'Forms and Validators': 'Formularios y validadores',
|
||||
'Free Applications': 'Aplicaciones Libres',
|
||||
'Functions with no doctests will result in [passed] tests.': 'Funciones sin doctests equivalen a pruebas [aceptadas].',
|
||||
'Group ID': 'ID de Grupo',
|
||||
'Groups': 'Groups',
|
||||
'Groups': 'Groupos',
|
||||
'Hello World': 'Hola Mundo',
|
||||
'help': 'ayuda',
|
||||
'Home': 'Home',
|
||||
'How did you get here?': 'How did you get here?',
|
||||
'How did you get here?': '¿Cómo llegaste aquí?',
|
||||
'htmledit': 'htmledit',
|
||||
'import': 'import',
|
||||
'import': 'importar',
|
||||
'Import/Export': 'Importar/Exportar',
|
||||
'includes': 'incluye',
|
||||
'Index': 'Indice',
|
||||
@@ -153,14 +153,14 @@
|
||||
'Installed applications': 'Aplicaciones instaladas',
|
||||
'internal error': 'error interno',
|
||||
'Internal State': 'Estado Interno',
|
||||
'Introduction': 'Introduction',
|
||||
'Introduction': 'Introducción',
|
||||
'Invalid action': 'Acción inválida',
|
||||
'Invalid email': 'Correo inválido',
|
||||
'Invalid email': 'Correo electrónico inválido',
|
||||
'invalid password': 'contraseña inválida',
|
||||
'Invalid Query': 'Consulta inválida',
|
||||
'invalid request': 'solicitud inválida',
|
||||
'invalid ticket': 'tiquete inválido',
|
||||
'Key': 'Key',
|
||||
'Key': 'Llave',
|
||||
'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',
|
||||
'languages': 'lenguajes',
|
||||
@@ -169,10 +169,10 @@
|
||||
'Last name': 'Apellido',
|
||||
'Last saved on:': 'Guardado en:',
|
||||
'Layout': 'Diseño de página',
|
||||
'Layout Plugins': 'Layout Plugins',
|
||||
'Layouts': 'Layouts',
|
||||
'Layout Plugins': 'Plugins de diseño',
|
||||
'Layouts': 'Diseños de páginas',
|
||||
'License for': 'Licencia para',
|
||||
'Live Chat': 'Live Chat',
|
||||
'Live Chat': 'Chat en vivo',
|
||||
'loading...': 'cargando...',
|
||||
'login': 'inicio de sesión',
|
||||
'Login': 'Inicio de sesión',
|
||||
@@ -180,16 +180,16 @@
|
||||
'logout': 'fin de sesión',
|
||||
'Logout': 'Fin de sesión',
|
||||
'Lost Password': 'Contraseña perdida',
|
||||
'lost password?': '¿olvido la contraseña?',
|
||||
'lost password?': '¿Olvido la contraseña?',
|
||||
'Main Menu': 'Menú principal',
|
||||
'Manage Cache': 'Manage Cache',
|
||||
'Manage Cache': 'Manejar la Cache',
|
||||
'Menu Model': 'Modelo "menu"',
|
||||
'merge': 'combinar',
|
||||
'Models': 'Modelos',
|
||||
'models': 'modelos',
|
||||
'Modules': 'Módulos',
|
||||
'modules': 'módulos',
|
||||
'My Sites': 'My Sites',
|
||||
'My Sites': 'Mis Sitios',
|
||||
'Name': 'Nombre',
|
||||
'new application "%s" created': 'nueva aplicación "%s" creada',
|
||||
'New Record': 'Registro nuevo',
|
||||
@@ -202,9 +202,9 @@
|
||||
'or provide application url:': 'o provea URL de la aplicación:',
|
||||
'Origin': 'Origen',
|
||||
'Original/Translation': 'Original/Traducción',
|
||||
'Other Plugins': 'Other Plugins',
|
||||
'Other Recipes': 'Other Recipes',
|
||||
'Overview': 'Overview',
|
||||
'Other Plugins': 'Otros Plugins',
|
||||
'Other Recipes': 'Otas Recetas',
|
||||
'Overview': 'Resumen',
|
||||
'pack all': 'empaquetar todo',
|
||||
'pack compiled': 'empaquete compiladas',
|
||||
'Password': 'Contraseña',
|
||||
@@ -215,20 +215,20 @@
|
||||
'previous 100 rows': '100 filas anteriores',
|
||||
'Python': 'Python',
|
||||
'Query:': 'Consulta:',
|
||||
'Quick Examples': 'Quick Examples',
|
||||
'Quick Examples': 'Ejemplos Rápidos',
|
||||
'RAM': 'RAM',
|
||||
'RAM Cache Keys': 'RAM Cache Keys',
|
||||
'Ram Cleared': 'Ram Cleared',
|
||||
'Recipes': 'Recipes',
|
||||
'RAM Cache Keys':'Llaves de la RAM Cache',
|
||||
'Ram Cleared': 'Ram Limpiada',
|
||||
'Recipes': 'Recetas',
|
||||
'Record': 'registro',
|
||||
'record does not exist': 'el registro no existe',
|
||||
'Record ID': 'ID de Registro',
|
||||
'Record id': 'id de registro',
|
||||
'Register': 'Registrese',
|
||||
'register': 'registrese',
|
||||
'Registration key': 'Contraseña de Registro',
|
||||
'Registration key': 'Llave de Registro',
|
||||
'remove compiled': 'eliminar compiladas',
|
||||
'Reset Password key': 'Reset Password key',
|
||||
'Reset Password key': 'Restaurar Llave de la Contraseña',
|
||||
'Resolve Conflict file': 'archivo Resolución de Conflicto',
|
||||
'restore': 'restaurar',
|
||||
'revert': 'revertir',
|
||||
@@ -237,20 +237,20 @@
|
||||
'Rows selected': 'Filas seleccionadas',
|
||||
'save': 'guardar',
|
||||
'Saved file hash:': 'Hash del archivo guardado:',
|
||||
'Semantic': 'Semantic',
|
||||
'Services': 'Services',
|
||||
'Semantic': 'Semantica',
|
||||
'Services': 'Servicios',
|
||||
'session expired': 'sesión expirada',
|
||||
'shell': 'shell',
|
||||
'shell': 'terminal',
|
||||
'site': 'sitio',
|
||||
'Size of cache:': 'Size of cache:',
|
||||
'Size of cache:': 'Tamaño del Cache:',
|
||||
'some files could not be removed': 'algunos archivos no pudieron ser removidos',
|
||||
'state': 'estado',
|
||||
'static': 'estáticos',
|
||||
'Static files': 'Archivos estáticos',
|
||||
'Statistics': 'Statistics',
|
||||
'Statistics': 'Estadísticas',
|
||||
'Stylesheet': 'Hoja de estilo',
|
||||
'submit': 'submit',
|
||||
'Support': 'Support',
|
||||
'submit': 'enviar',
|
||||
'Support': 'Soporte',
|
||||
'Sure you want to delete this object?': '¿Está seguro que desea eliminar este objeto?',
|
||||
'Table': 'tabla',
|
||||
'Table name': 'Nombre de la tabla',
|
||||
@@ -258,11 +258,11 @@
|
||||
'Testing application': 'Probando aplicación',
|
||||
'The "query" is a condition like "db.table1.field1==\'value\'". Something like "db.table1.field1==db.table2.field2" results in a SQL JOIN.': 'La "consulta" es una condición como "db.tabla1.campo1==\'valor\'". Algo como "db.tabla1.campo1==db.tabla2.campo2" resulta en un JOIN SQL.',
|
||||
'the application logic, each URL path is mapped in one exposed function in the controller': 'la lógica de la aplicación, cada ruta URL se mapea en una función expuesta en el controlador',
|
||||
'The Core': 'The Core',
|
||||
'The Core': 'El Núcleo',
|
||||
'the data representation, define database tables and sets': 'la representación de datos, define tablas y conjuntos de base de datos',
|
||||
'The output of the file is a dictionary that was rendered by the view %s': 'La salida del archivo es un diccionario escenificado por la vista %s',
|
||||
'The output of the file is a dictionary that was rendered by the view %s': 'La salida de dicha función es un diccionario que es desplegado por la vista %s',
|
||||
'the presentations layer, views are also known as templates': 'la capa de presentación, las vistas también son llamadas plantillas',
|
||||
'The Views': 'The Views',
|
||||
'The Views': 'Las Vistas',
|
||||
'There are no controllers': 'No hay controladores',
|
||||
'There are no models': 'No hay modelos',
|
||||
'There are no modules': 'No hay módulos',
|
||||
@@ -270,14 +270,14 @@
|
||||
'There are no translators, only default language is supported': 'No hay traductores, sólo el lenguaje por defecto es soportado',
|
||||
'There are no views': 'No hay vistas',
|
||||
'these files are served without processing, your images go here': 'estos archivos son servidos sin procesar, sus imágenes van aquí',
|
||||
'This App': 'This App',
|
||||
'This App': 'Esta Aplicación',
|
||||
'This is a copy of the scaffolding application': 'Esta es una copia de la aplicación de andamiaje',
|
||||
'This is the %(filename)s template': 'Esta es la plantilla %(filename)s',
|
||||
'Ticket': 'Tiquete',
|
||||
'Time in Cache (h:m:s)': 'Time in Cache (h:m:s)',
|
||||
'Timestamp': 'Timestamp',
|
||||
'Time in Cache (h:m:s)': 'Tiempo en Cache (h:m:s)',
|
||||
'Timestamp': 'Marca de tiempo',
|
||||
'to previous version.': 'a la versión previa.',
|
||||
'translation strings for the application': 'cadenas de caracteres de traducción para la aplicación',
|
||||
'translation strings for the application': 'cadenas de carácteres de traducción para la aplicación',
|
||||
'try': 'intente',
|
||||
'try something like': 'intente algo como',
|
||||
'Twitter': 'Twitter',
|
||||
@@ -306,12 +306,12 @@
|
||||
'views': 'vistas',
|
||||
'web2py is up to date': 'web2py está actualizado',
|
||||
'web2py Recent Tweets': 'Tweets Recientes de web2py',
|
||||
'Welcome': 'Welcome',
|
||||
'Welcome': 'Bienvenido',
|
||||
'Welcome %s': 'Bienvenido %s',
|
||||
'Welcome to web2py': 'Bienvenido a web2py',
|
||||
'Welcome to web2py!': 'Welcome to web2py!',
|
||||
'Welcome to web2py!': '¡Bienvenido to web2py!',
|
||||
'Which called the function %s located in the file %s': 'La cual llamó la función %s localizada en el archivo %s',
|
||||
'YES': 'SI',
|
||||
'YES': 'SÍ',
|
||||
'You are successfully running web2py': 'Usted está ejecutando web2py exitosamente',
|
||||
'You can modify this application and adapt it to your needs': 'Usted puede modificar esta aplicación y adaptarla a sus necesidades',
|
||||
'You visited the url %s': 'Usted visitó la url %s',
|
||||
|
||||
@@ -3,14 +3,14 @@
|
||||
'!langcode!': 'fr',
|
||||
'!langname!': 'Français',
|
||||
'"update" is an optional expression like "field1=\'newvalue\'". You cannot update or delete the results of a JOIN': '"update" est une expression optionnelle comme "champ1=\'nouvellevaleur\'". Vous ne pouvez mettre à jour ou supprimer les résultats d\'un JOIN',
|
||||
'%s %%{row} deleted': '%s rangées supprimées',
|
||||
'%s %%{row} updated': '%s rangées mises à jour',
|
||||
'%s %%{row} deleted': '%s lignes supprimées',
|
||||
'%s %%{row} updated': '%s lignes mises à jour',
|
||||
'%s selected': '%s sélectionné',
|
||||
'%Y-%m-%d': '%Y-%m-%d',
|
||||
'%Y-%m-%d %H:%M:%S': '%Y-%m-%d %H:%M:%S',
|
||||
'About': 'À propos',
|
||||
'Access Control': "Contrôle d'accès",
|
||||
'Administrative Interface': 'Administrative Interface',
|
||||
'Administrative Interface': "Interface d'administration",
|
||||
'Administrative interface': "Interface d'administration",
|
||||
'Ajax Recipes': 'Recettes Ajax',
|
||||
'appadmin is disabled because insecure channel': "appadmin est désactivée parce que le canal n'est pas sécurisé",
|
||||
@@ -20,38 +20,40 @@
|
||||
'Buy this book': 'Acheter ce livre',
|
||||
'cache': 'cache',
|
||||
'Cache': 'Cache',
|
||||
'Cache Keys': 'Cache Keys',
|
||||
'Cache Keys': 'Clés de cache',
|
||||
'Cannot be empty': 'Ne peut pas être vide',
|
||||
'change password': 'changer le mot de passe',
|
||||
'Check to delete': 'Cliquez pour supprimer',
|
||||
'Check to delete:': 'Cliquez pour supprimer:',
|
||||
'Clear CACHE?': 'Clear CACHE?',
|
||||
'Clear DISK': 'Clear DISK',
|
||||
'Clear RAM': 'Clear RAM',
|
||||
'Clear CACHE?': 'Vider le CACHE?',
|
||||
'Clear DISK': 'Vider le DISQUE',
|
||||
'Clear RAM': 'Vider la RAM',
|
||||
'Client IP': 'IP client',
|
||||
'Community': 'Communauté',
|
||||
'Components and Plugins': 'Components and Plugins',
|
||||
'Components and Plugins': 'Composants et Plugins',
|
||||
'Controller': 'Contrôleur',
|
||||
'Copyright': 'Copyright',
|
||||
'Created By': 'Créé par',
|
||||
'Created On': 'Créé le',
|
||||
'Current request': 'Demande actuelle',
|
||||
'Current response': 'Réponse actuelle',
|
||||
'Current session': 'Session en cours',
|
||||
'customize me!': 'personnalisez-moi!',
|
||||
'data uploaded': 'données téléchargées',
|
||||
'Database': 'base de données',
|
||||
'Database %s select': 'base de données %s select',
|
||||
'db': 'db',
|
||||
'DB Model': 'Modèle DB',
|
||||
'Database %s select': 'base de données %s selectionnée',
|
||||
'db': 'bdd',
|
||||
'DB Model': 'Modèle BDD',
|
||||
'Delete:': 'Supprimer:',
|
||||
'Demo': 'Démo',
|
||||
'Deployment Recipes': 'Recettes de déploiement',
|
||||
'Description': 'Description',
|
||||
'design': 'design',
|
||||
'DISK': 'DISK',
|
||||
'Disk Cache Keys': 'Disk Cache Keys',
|
||||
'Disk Cleared': 'Disk Cleared',
|
||||
'DISK': 'DISQUE',
|
||||
'Disk Cache Keys': 'Clés de cache du disque',
|
||||
'Disk Cleared': 'Disque vidé',
|
||||
'Documentation': 'Documentation',
|
||||
"Don't know what to do?": "Don't know what to do?",
|
||||
"Don't know what to do?": 'Vous ne savez pas quoi faire?',
|
||||
'done!': 'fait!',
|
||||
'Download': 'Téléchargement',
|
||||
'E-mail': 'E-mail',
|
||||
@@ -59,8 +61,8 @@
|
||||
'Edit current record': "Modifier l'enregistrement courant",
|
||||
'edit profile': 'modifier le profil',
|
||||
'Edit This App': 'Modifier cette application',
|
||||
'Email and SMS': 'Email and SMS',
|
||||
'enter an integer between %(min)g and %(max)g': 'enter an integer between %(min)g and %(max)g',
|
||||
'Email and SMS': 'Email et SMS',
|
||||
'enter an integer between %(min)g and %(max)g': 'entrez un entier entre %(min)g et %(max)g',
|
||||
'Errors': 'Erreurs',
|
||||
'export as csv file': 'exporter sous forme de fichier csv',
|
||||
'FAQ': 'FAQ',
|
||||
@@ -69,10 +71,10 @@
|
||||
'Free Applications': 'Applications gratuites',
|
||||
'Function disabled': 'Fonction désactivée',
|
||||
'Group ID': 'Groupe ID',
|
||||
'Groups': 'Groups',
|
||||
'Groups': 'Groupes',
|
||||
'Hello World': 'Bonjour le monde',
|
||||
'Home': 'Accueil',
|
||||
'How did you get here?': 'How did you get here?',
|
||||
'How did you get here?': 'Comment êtes-vous arrivé ici?',
|
||||
'import': 'import',
|
||||
'Import/Export': 'Importer/Exporter',
|
||||
'Index': 'Index',
|
||||
@@ -83,48 +85,51 @@
|
||||
'Invalid email': 'E-mail invalide',
|
||||
'Invalid Query': 'Requête Invalide',
|
||||
'invalid request': 'requête invalide',
|
||||
'Key': 'Key',
|
||||
'Is Active': 'Est actif',
|
||||
'Key': 'Clé',
|
||||
'Last name': 'Nom',
|
||||
'Layout': 'Mise en page',
|
||||
'Layout Plugins': 'Layout Plugins',
|
||||
'Layouts': 'Layouts',
|
||||
'Live chat': 'Chat live',
|
||||
'Live Chat': 'Live Chat',
|
||||
'Layout Plugins': 'Plugins de mise en page',
|
||||
'Layouts': 'Mises en page',
|
||||
'Live chat': 'Chat en direct',
|
||||
'Live Chat': 'Chat en direct',
|
||||
'login': 'connectez-vous',
|
||||
'Login': 'Connectez-vous',
|
||||
'logout': 'déconnectez-vous',
|
||||
'lost password': 'mot de passe perdu',
|
||||
'Lost Password': 'Mot de passe perdu',
|
||||
'Lost password?': 'Lost password?',
|
||||
'Lost password?': 'Mot de passe perdu?',
|
||||
'lost password?': 'mot de passe perdu?',
|
||||
'Main Menu': 'Menu principal',
|
||||
'Manage Cache': 'Manage Cache',
|
||||
'Manage Cache': 'Gérer le Cache',
|
||||
'Menu Model': 'Menu modèle',
|
||||
'My Sites': 'My Sites',
|
||||
'Modified By': 'Modifié par',
|
||||
'Modified On': 'Modifié le',
|
||||
'My Sites': 'Mes sites',
|
||||
'Name': 'Nom',
|
||||
'New Record': 'Nouvel enregistrement',
|
||||
'new record inserted': 'nouvel enregistrement inséré',
|
||||
'next 100 rows': '100 prochaines lignes',
|
||||
'No databases in this application': "Cette application n'a pas de bases de données",
|
||||
'Object or table name': 'Object or table name',
|
||||
'Object or table name': 'Objet ou nom de table',
|
||||
'Online examples': 'Exemples en ligne',
|
||||
'or import from csv file': "ou importer d'un fichier CSV",
|
||||
'Origin': 'Origine',
|
||||
'Other Plugins': 'Other Plugins',
|
||||
'Other Plugins': 'Autres Plugins',
|
||||
'Other Recipes': 'Autres recettes',
|
||||
'Overview': 'Présentation',
|
||||
'Password': 'Mot de passe',
|
||||
"Password fields don't match": 'Les mots de passe ne correspondent pas',
|
||||
'Plugins': 'Plugiciels',
|
||||
'Plugins': 'Plugins',
|
||||
'Powered by': 'Alimenté par',
|
||||
'Preface': 'Préface',
|
||||
'previous 100 rows': '100 lignes précédentes',
|
||||
'Python': 'Python',
|
||||
'Query:': 'Requête:',
|
||||
'Quick Examples': 'Examples Rapides',
|
||||
'Quick Examples': 'Exemples Rapides',
|
||||
'RAM': 'RAM',
|
||||
'RAM Cache Keys': 'RAM Cache Keys',
|
||||
'Ram Cleared': 'Ram Cleared',
|
||||
'RAM Cache Keys': 'Clés de cache de la RAM',
|
||||
'Ram Cleared': 'Ram vidée',
|
||||
'Readme': 'Lisez-moi',
|
||||
'Recipes': 'Recettes',
|
||||
'Record': 'enregistrement',
|
||||
@@ -133,7 +138,7 @@
|
||||
'Record id': "id d'enregistrement",
|
||||
'Register': "S'inscrire",
|
||||
'register': "s'inscrire",
|
||||
'Registration identifier': 'Registration identifier',
|
||||
'Registration identifier': "Identifiant d'enregistrement",
|
||||
'Registration key': "Clé d'enregistrement",
|
||||
'Remember me (for 30 days)': 'Se souvenir de moi (pendant 30 jours)',
|
||||
'Request reset password': 'Demande de réinitialiser le mot clé',
|
||||
@@ -144,42 +149,42 @@
|
||||
'Rows selected': 'Lignes sélectionnées',
|
||||
'Semantic': 'Sémantique',
|
||||
'Services': 'Services',
|
||||
'Size of cache:': 'Size of cache:',
|
||||
'Size of cache:': 'Taille du cache:',
|
||||
'state': 'état',
|
||||
'Statistics': 'Statistics',
|
||||
'Statistics': 'Statistiques',
|
||||
'Stylesheet': 'Feuille de style',
|
||||
'submit': 'submit',
|
||||
'submit': 'soumettre',
|
||||
'Submit': 'Soumettre',
|
||||
'Support': 'Support',
|
||||
'Sure you want to delete this object?': 'Êtes-vous sûr de vouloir supprimer cet objet?',
|
||||
'Table': 'tableau',
|
||||
'Table name': 'Nom du tableau',
|
||||
'The "query" is a condition like "db.table1.field1==\'value\'". Something like "db.table1.field1==db.table2.field2" results in a SQL JOIN.': 'La "query" est une condition comme "db.table1.champ1==\'valeur\'". Quelque chose comme "db.table1.champ1==db.table2.champ2" résulte en un JOIN SQL.',
|
||||
'The "query" is a condition like "db.table1.field1==\'value\'". Something like "db.table1.field1==db.table2.field2" results in a SQL JOIN.': 'La "requête" est une condition comme "db.table1.champ1==\'valeur\'". Quelque chose comme "db.table1.champ1==db.table2.champ2" résulte en un JOIN SQL.',
|
||||
'The Core': 'Le noyau',
|
||||
'The output of the file is a dictionary that was rendered by the view %s': 'La sortie de ce fichier est un dictionnaire qui été restitué par la vue %s',
|
||||
'The Views': 'Les Vues',
|
||||
'This App': 'Cette Appli',
|
||||
'This is a copy of the scaffolding application': "Ceci est une copie de l'application échafaudage",
|
||||
'Time in Cache (h:m:s)': 'Time in Cache (h:m:s)',
|
||||
'Time in Cache (h:m:s)': 'Temps en Cache (h:m:s)',
|
||||
'Timestamp': 'Horodatage',
|
||||
'Twitter': 'Twitter',
|
||||
'unable to parse csv file': "incapable d'analyser le fichier cvs",
|
||||
'Update:': 'Mise à jour:',
|
||||
'Use (...)&(...) for AND, (...)|(...) for OR, and ~(...) for NOT to build more complex queries.': 'Employez (...)&(...) pour AND, (...)|(...) pour OR, and ~(...) pour NOT pour construire des requêtes plus complexes.',
|
||||
'Use (...)&(...) for AND, (...)|(...) for OR, and ~(...) for NOT to build more complex queries.': 'Employez (...)&(...) pour AND, (...)|(...) pour OR, and ~(...) pour NOT afin de construire des requêtes plus complexes.',
|
||||
'User %(id)s Logged-in': 'Utilisateur %(id)s connecté',
|
||||
'User %(id)s Registered': 'Utilisateur %(id)s enregistré',
|
||||
'User ID': 'ID utilisateur',
|
||||
'User Voice': 'User Voice',
|
||||
'User Voice': "Voix de l'utilisateur",
|
||||
'Verify Password': 'Vérifiez le mot de passe',
|
||||
'Videos': 'Vidéos',
|
||||
'View': 'Présentation',
|
||||
'Web2py': 'Web2py',
|
||||
'Welcome': 'Bienvenu',
|
||||
'Welcome': 'Bienvenue',
|
||||
'Welcome %s': 'Bienvenue %s',
|
||||
'Welcome to web2py': 'Bienvenue à web2py',
|
||||
'Welcome to web2py!': 'Welcome to web2py!',
|
||||
'Welcome to web2py!': 'Bienvenue à web2py!',
|
||||
'Which called the function %s located in the file %s': 'Qui a appelé la fonction %s se trouvant dans le fichier %s',
|
||||
'You are successfully running web2py': 'Vous roulez avec succès web2py',
|
||||
'You are successfully running web2py': 'Vous exécutez avec succès web2py',
|
||||
'You can modify this application and adapt it to your needs': "Vous pouvez modifier cette application et l'adapter à vos besoins",
|
||||
'You visited the url %s': "Vous avez visité l'URL %s",
|
||||
}
|
||||
|
||||
Executable
+272
@@ -0,0 +1,272 @@
|
||||
# coding: utf8
|
||||
{
|
||||
'!langcode!': 'id',
|
||||
'!langname!': 'Indonesian',
|
||||
'%d days ago': '%d hari yang lalu',
|
||||
'%d hours ago': '%d jam yang lalu',
|
||||
'%d minutes ago': '%d menit yang lalu',
|
||||
'%d months ago': '%d bulan yang lalu',
|
||||
'%d seconds ago': '%d detik yang lalu',
|
||||
'%d seconds from now': '%d detik dari sekarang',
|
||||
'%d weeks ago': '%d minggu yang lalu',
|
||||
'%d years ago': '%d tahun yang lalu',
|
||||
'%s %%{row} deleted': '%s %%{row} dihapus',
|
||||
'%s %%{row} updated': '%s %%{row} diperbarui',
|
||||
'%s selected': '%s dipilih',
|
||||
'%Y-%m-%d': '%d-%m-%Y',
|
||||
'%Y-%m-%d %H:%M:%S': '%d-%m-%Y %H:%M:%S',
|
||||
'(requires internet access, experimental)': '(membutuhkan akses internet, eksperimental)',
|
||||
'(something like "it-it")': '(sesuatu seperti "it-it")',
|
||||
'1 day ago': '1 hari yang lalu',
|
||||
'1 hour ago': '1 jam yang lalu',
|
||||
'1 minute ago': '1 menit yang lalu',
|
||||
'1 month ago': '1 bulan yang lalu',
|
||||
'1 second ago': '1 detik yang lalu',
|
||||
'1 week ago': '1 minggu yang lalu',
|
||||
'1 year ago': '1 tahun yang lalu',
|
||||
'< Previous': '< Sebelumnya',
|
||||
'About': 'Tentang',
|
||||
'About application': 'Tentang Aplikasi',
|
||||
'Add': 'Tambah',
|
||||
'Additional code for your application': 'Tambahan kode untuk aplikasi Anda',
|
||||
'Address': 'Alamat',
|
||||
'Admin language': 'Bahasa Admin',
|
||||
'administrative interface': 'antarmuka administrative',
|
||||
'Administrator Password:': 'Administrator Kata Sandi:',
|
||||
'Ajax Recipes': 'Resep Ajax',
|
||||
'An error occured, please %s the page': 'Terjadi kesalahan, silakan %s halaman',
|
||||
'And': 'Dan',
|
||||
'and rename it:': 'dan memberi nama baru itu:',
|
||||
'Answer': 'Jawaban',
|
||||
'appadmin is disabled because insecure channel': 'AppAdmin dinonaktifkan karena kanal tidak aman',
|
||||
'application "%s" uninstalled': 'applikasi "%s" dihapus',
|
||||
'application compiled': 'aplikasi dikompilasi',
|
||||
'Application name:': 'Nama Applikasi:',
|
||||
'are not used yet': 'tidak digunakan lagi',
|
||||
'Are you sure you want to delete this object?': 'Apakah Anda yakin ingin menghapus ini?',
|
||||
'Are you sure you want to uninstall application "%s"?': 'Apakah Anda yakin ingin menghapus aplikasi "%s"?',
|
||||
'Available Databases and Tables': 'Database dan Tabel yang tersedia',
|
||||
'Back': 'Kembali',
|
||||
'Buy this book': 'Beli buku ini',
|
||||
'cache, errors and sessions cleaned': 'cache, kesalahan dan sesi dibersihkan',
|
||||
'can be a git repo': 'bisa menjadi repo git',
|
||||
'Cancel': 'Batalkan',
|
||||
'Cannot be empty': 'Tidak boleh kosong',
|
||||
'Change admin password': 'Ubah kata sandi admin',
|
||||
'Change password': 'Ubah kata sandi',
|
||||
'Check for upgrades': 'Periksa upgrade',
|
||||
'Check to delete': 'Centang untuk menghapus',
|
||||
'Checking for upgrades...': 'Memeriksa untuk upgrade...',
|
||||
'Clean': 'Bersih',
|
||||
'Clear': 'Hapus',
|
||||
'Clear CACHE?': 'Hapus CACHE?',
|
||||
'Clear DISK': 'Hapus DISK',
|
||||
'Clear RAM': 'Hapus RAM',
|
||||
'Click row to expand traceback': 'Klik baris untuk memperluas traceback',
|
||||
'Close': 'Tutup',
|
||||
'collapse/expand all': 'kempis / memperluas semua',
|
||||
'Community': 'Komunitas',
|
||||
'Compile': 'Kompilasi',
|
||||
'compiled application removed': 'aplikasi yang dikompilasi dihapus',
|
||||
'Components and Plugins': 'Komponen dan Plugin',
|
||||
'contains': 'mengandung',
|
||||
'Controllers': 'Kontrolir',
|
||||
'controllers': 'kontrolir',
|
||||
'Copyright': 'Hak Cipta',
|
||||
'Count': 'Hitung',
|
||||
'Create': 'Buat',
|
||||
'create file with filename:': 'buat file dengan nama:',
|
||||
'created by': 'dibuat oleh',
|
||||
'CSV (hidden cols)': 'CSV (kolom tersembunyi)',
|
||||
'currently running': 'sedang berjalan',
|
||||
'data uploaded': 'data diunggah',
|
||||
'Database %s select': 'Memilih Database %s',
|
||||
'database administration': 'administrasi database',
|
||||
'defines tables': 'mendefinisikan tabel',
|
||||
'Delete': 'Hapus',
|
||||
'delete all checked': 'menghapus semua yang di centang',
|
||||
'Delete this file (you will be asked to confirm deletion)': 'Hapus file ini (Anda akan diminta untuk mengkonfirmasi penghapusan)',
|
||||
'Delete:': 'Hapus:',
|
||||
'Description': 'Keterangan',
|
||||
'design': 'disain',
|
||||
'direction: ltr': 'petunjuk: ltr',
|
||||
'Disk Cleared': 'Disk Dihapus',
|
||||
'Documentation': 'Dokumentasi',
|
||||
"Don't know what to do?": 'Tidak tahu apa yang harus dilakukan?',
|
||||
'done!': 'selesai!',
|
||||
'Download': 'Unduh',
|
||||
'Download .w2p': 'Unduh .w2p',
|
||||
'download layouts': 'unduh layouts',
|
||||
'download plugins': 'unduh plugins',
|
||||
'Duration': 'Durasi',
|
||||
'Edit': 'Mengedit',
|
||||
'Edit application': 'Mengedit Aplikasi',
|
||||
'Email sent': 'Email dikirim',
|
||||
'enter a valid email address': 'masukkan alamat email yang benar',
|
||||
'enter a valid URL': 'masukkan URL yang benar',
|
||||
'enter a value': 'masukkan data',
|
||||
'Error': 'Kesalahan',
|
||||
'Error logs for "%(app)s"': 'Catatan kesalahan untuk "%(app)s"',
|
||||
'Errors': 'Kesalahan',
|
||||
'export as csv file': 'ekspor sebagai file csv',
|
||||
'Export:': 'Ekspor:',
|
||||
'exposes': 'menghadapkan',
|
||||
'extends': 'meluaskan',
|
||||
'filter': 'menyaring',
|
||||
'First Name': 'Nama Depan',
|
||||
'Forgot username?': 'Lupa nama pengguna?',
|
||||
'Free Applications': 'Aplikasi Gratis',
|
||||
'Gender': 'Jenis Kelamin',
|
||||
'Group %(group_id)s created': 'Grup %(group_id)s dibuat',
|
||||
'Group uniquely assigned to user %(id)s': 'Grup unik yang diberikan kepada pengguna %(id)s',
|
||||
'Groups': 'Grup',
|
||||
'Guest': 'Tamu',
|
||||
'Hello World': 'Halo Dunia',
|
||||
'Help': 'Bantuan',
|
||||
'Home': 'Halaman Utama',
|
||||
'How did you get here?': 'Bagaimana kamu bisa di sini?',
|
||||
'Image': 'Gambar',
|
||||
'import': 'impor',
|
||||
'Import/Export': 'Impor/Ekspor',
|
||||
'includes': 'termasuk',
|
||||
'Install': 'Memasang',
|
||||
'Installation': 'Instalasi',
|
||||
'Installed applications': 'Aplikasi yang diinstal',
|
||||
'Introduction': 'Pengenalan',
|
||||
'Invalid email': 'Email tidak benar',
|
||||
'Language': 'Bahasa',
|
||||
'languages': 'bahasa',
|
||||
'Languages': 'Bahasa',
|
||||
'Last Name': 'Nama Belakang',
|
||||
'License for': 'Lisensi untuk',
|
||||
'loading...': 'sedang memuat...',
|
||||
'Logged in': 'Masuk',
|
||||
'Logged out': 'Keluar',
|
||||
'Login': 'Masuk',
|
||||
'Login to the Administrative Interface': 'Masuk ke antarmuka Administrasi',
|
||||
'Logout': 'Keluar',
|
||||
'Lost Password': 'Lupa Kata Sandi',
|
||||
'Lost password?': 'Lupa kata sandi?',
|
||||
'Maintenance': 'Pemeliharaan',
|
||||
'Manage': 'Mengelola',
|
||||
'Manage Cache': 'Mengelola Cache',
|
||||
'models': 'model',
|
||||
'Models': 'Model',
|
||||
'Modules': 'Modul',
|
||||
'modules': 'modul',
|
||||
'My Sites': 'Situs Saya',
|
||||
'New': 'Baru',
|
||||
'new application "%s" created': 'aplikasi baru "%s" dibuat',
|
||||
'New password': 'Kata sandi baru',
|
||||
'New simple application': 'Aplikasi baru sederhana',
|
||||
'News': 'Berita',
|
||||
'next 100 rows': '100 baris berikutnya',
|
||||
'Next >': 'Berikutnya >',
|
||||
'Next Page': 'Halaman Berikutnya',
|
||||
'No databases in this application': 'Tidak ada database dalam aplikasi ini',
|
||||
'No ticket_storage.txt found under /private folder': 'Tidak ditemukan ticket_storage.txt dalam folder /private',
|
||||
'not a Zip Code': 'bukan Kode Pos',
|
||||
'Note': 'Catatan',
|
||||
'Old password': 'Kata sandi lama',
|
||||
'Online examples': 'Contoh Online',
|
||||
'Or': 'Atau',
|
||||
'or alternatively': 'atau alternatif',
|
||||
'Or Get from URL:': 'Atau Dapatkan dari URL:',
|
||||
'or import from csv file': 'atau impor dari file csv',
|
||||
'Other Plugins': 'Plugin Lainnya',
|
||||
'Other Recipes': 'Resep Lainnya',
|
||||
'Overview': 'Ikhtisar',
|
||||
'Overwrite installed app': 'Ikhtisar app yang terinstall',
|
||||
'Pack all': 'Pak semua',
|
||||
'Pack compiled': 'Pak yang telah dikompilasi',
|
||||
'Pack custom': 'Pak secara kustomisasi',
|
||||
'Password': 'Kata sandi',
|
||||
'Password changed': 'Kata sandi berubah',
|
||||
"Password fields don't match": 'Kata sandi tidak sama',
|
||||
'please input your password again': 'silahkan masukan kata sandi anda lagi',
|
||||
'plugins': 'plugin',
|
||||
'Plugins': 'Plugin',
|
||||
'Plural-Forms:': 'Bentuk-Jamak:',
|
||||
'Powered by': 'Didukung oleh',
|
||||
'Preface': 'Pendahuluan',
|
||||
'previous 100 rows': '100 baris sebelumnya',
|
||||
'Previous Page': 'Halaman Sebelumnya',
|
||||
'private files': 'file pribadi',
|
||||
'Private files': 'File pribadi',
|
||||
'Profile': 'Profil',
|
||||
'Profile updated': 'Profil diperbarui',
|
||||
'Project Progress': 'Perkembangan Proyek',
|
||||
'Quick Examples': 'Contoh Cepat',
|
||||
'Ram Cleared': 'Ram Dihapus',
|
||||
'Recipes': 'Resep',
|
||||
'Register': 'Daftar',
|
||||
'Registration successful': 'Pendaftaran berhasil',
|
||||
'reload': 'memuat kembali',
|
||||
'Reload routes': 'Memuat rute kembali',
|
||||
'Remember me (for 30 days)': 'Ingat saya (selama 30 hari)',
|
||||
'Remove compiled': 'Hapus Kompilasi',
|
||||
'Request reset password': 'Meminta reset kata sandi',
|
||||
'Rows in Table': 'Baris dalam Tabel',
|
||||
'Rows selected': 'Baris dipilih',
|
||||
"Run tests in this file (to run all files, you may also use the button labelled 'test')": "Jalankan tes di file ini (untuk menjalankan semua file, Anda juga dapat menggunakan tombol berlabel 'test')",
|
||||
'Running on %s': 'Berjalan di %s',
|
||||
'Save model as...': 'Simpan model sebagai ...',
|
||||
'Save profile': 'Simpan profil',
|
||||
'Search': 'Cari',
|
||||
'Select Files to Package': 'Pilih Berkas untuk Paket',
|
||||
'Send Email': 'Kirim Email',
|
||||
'Service': 'Layanan',
|
||||
'Site': 'Situs',
|
||||
'Size of cache:': 'Ukuran cache:',
|
||||
'starts with': 'dimulai dengan',
|
||||
'static': 'statis',
|
||||
'Static': 'Statis',
|
||||
'Statistics': 'Statistik',
|
||||
'Support': 'Mendukung',
|
||||
'Table': 'Tabel',
|
||||
'test': 'tes',
|
||||
'The application logic, each URL path is mapped in one exposed function in the controller': 'Logika aplikasi, setiap jalur URL dipetakan dalam satu fungsi terpapar di kontrolir',
|
||||
'The data representation, define database tables and sets': 'Representasi data, mendefinisikan tabel database dan set',
|
||||
'There are no plugins': 'Tidak ada plugin',
|
||||
'There are no private files': 'Tidak ada file pribadi',
|
||||
'These files are not served, they are only available from within your app': 'File-file ini tidak dilayani, mereka hanya tersedia dari dalam aplikasi Anda',
|
||||
'These files are served without processing, your images go here': 'File-file ini disajikan tanpa pengolahan, gambar Anda di sini',
|
||||
'This App': 'App Ini',
|
||||
'Time in Cache (h:m:s)': 'Waktu di Cache (h: m: s)',
|
||||
'To create a plugin, name a file/folder plugin_[name]': 'Untuk membuat sebuah plugin, nama file / folder plugin_ [nama]',
|
||||
'too short': 'terlalu pendek',
|
||||
'Translation strings for the application': 'Terjemahan string untuk aplikasi',
|
||||
'Try the mobile interface': 'Coba antarmuka ponsel',
|
||||
'Unable to download because:': 'Tidak dapat mengunduh karena:',
|
||||
'unable to parse csv file': 'tidak mampu mengurai file csv',
|
||||
'update all languages': 'memperbarui semua bahasa',
|
||||
'Update:': 'Perbarui:',
|
||||
'Upload': 'Unggah',
|
||||
'Upload a package:': 'Unggah sebuah paket:',
|
||||
'Upload and install packed application': 'Upload dan pasang aplikasi yang dikemas',
|
||||
'upload file:': 'unggah file:',
|
||||
'upload plugin file:': 'unggah file plugin:',
|
||||
'User %(id)s Logged-in': 'Pengguna %(id)s Masuk',
|
||||
'User %(id)s Logged-out': 'Pengguna %(id)s Keluar',
|
||||
'User %(id)s Password changed': 'Pengguna %(id)s Kata Sandi berubah',
|
||||
'User %(id)s Password reset': 'Pengguna %(id)s Kata Sandi telah direset',
|
||||
'User %(id)s Profile updated': 'Pengguna %(id)s Profil diperbarui',
|
||||
'User %(id)s Registered': 'Pengguna %(id)s Terdaftar',
|
||||
'value already in database or empty': 'data sudah ada dalam database atau kosong',
|
||||
'value not allowed': 'data tidak benar',
|
||||
'value not in database': 'data tidak ada dalam database',
|
||||
'Verify Password': 'Verifikasi Kata Sandi',
|
||||
'Version': 'Versi',
|
||||
'View': 'Lihat',
|
||||
'Views': 'Lihat',
|
||||
'views': 'lihat',
|
||||
'Web Framework': 'Kerangka Web',
|
||||
'web2py is up to date': 'web2py terbaru',
|
||||
'web2py Recent Tweets': 'Tweet web2py terbaru',
|
||||
'Website': 'Situs Web',
|
||||
'Welcome': 'Selamat Datang',
|
||||
'Welcome to web2py!': 'Selamat Datang di web2py!',
|
||||
'You are successfully running web2py': 'Anda berhasil menjalankan web2py',
|
||||
'You can modify this application and adapt it to your needs': 'Anda dapat memodifikasi aplikasi ini dan menyesuaikan dengan kebutuhan Anda',
|
||||
'You visited the url %s': 'Anda mengunjungi url %s',
|
||||
}
|
||||
@@ -4,8 +4,8 @@
|
||||
'!langcode!': 'it',
|
||||
'!langname!': 'Italiano',
|
||||
'"update" is an optional expression like "field1=\'newvalue\'". You cannot update or delete the results of a JOIN': '"update" è un\'espressione opzionale come "campo1=\'nuovo valore\'". Non si può fare "update" o "delete" dei risultati di un JOIN ',
|
||||
'%(nrows)s records found': '%(nrows)s records found',
|
||||
'%d seconds ago': '%d seconds ago',
|
||||
'%(nrows)s records found': '%(nrows)s record trovati',
|
||||
'%d seconds ago': '%d secondi fa',
|
||||
'%s %%{row} deleted': '%s righe ("record") cancellate',
|
||||
'%s %%{row} updated': '%s righe ("record") modificate',
|
||||
'%s selected': '%s selezionato',
|
||||
@@ -16,40 +16,41 @@
|
||||
'=': '=',
|
||||
'>': '>',
|
||||
'>=': '>=',
|
||||
'@markmin\x01Number of entries: **%s**': 'Number of entries: **%s**',
|
||||
'@markmin\x01Number of entries: **%s**': 'Numero di entità: **%s**',
|
||||
'About': 'About',
|
||||
'Access Control': 'Access Control',
|
||||
'Add': 'Add',
|
||||
'Administrative Interface': 'Administrative Interface',
|
||||
'Access Control': 'Controllo Accessi',
|
||||
'Add': 'Aggiungi',
|
||||
'Administrative Interface': 'Interfaccia Amministrativa',
|
||||
'Administrative interface': 'Interfaccia amministrativa',
|
||||
'Ajax Recipes': 'Ajax Recipes',
|
||||
'And': 'And',
|
||||
'An error occured, please %s the page': "È stato rilevato un errore, prego %s la pagina",
|
||||
'And': 'E',
|
||||
'appadmin is disabled because insecure channel': 'Amministrazione (appadmin) disabilitata: comunicazione non sicura',
|
||||
'Are you sure you want to delete this object?': 'Are you sure you want to delete this object?',
|
||||
'Are you sure you want to delete this object?': 'Sicuro di voler cancellare questo oggetto ?',
|
||||
'Available Databases and Tables': 'Database e tabelle disponibili',
|
||||
'Back': 'Back',
|
||||
'Buy this book': 'Buy this book',
|
||||
'Back': 'Indietro',
|
||||
'Buy this book': 'Compra questo libro',
|
||||
'cache': 'cache',
|
||||
'Cache': 'Cache',
|
||||
'Cache Keys': 'Cache Keys',
|
||||
'Cannot be empty': 'Non può essere vuoto',
|
||||
'Change password': 'Change password',
|
||||
'Change password': 'Cambia Password',
|
||||
'change password': 'Cambia password',
|
||||
'Check to delete': 'Seleziona per cancellare',
|
||||
'Clear': 'Clear',
|
||||
'Clear CACHE?': 'Clear CACHE?',
|
||||
'Clear DISK': 'Clear DISK',
|
||||
'Clear RAM': 'Clear RAM',
|
||||
'Clear': 'Resetta',
|
||||
'Clear CACHE?': 'Resetta CACHE?',
|
||||
'Clear DISK': 'Resetta DISK',
|
||||
'Clear RAM': 'Resetta RAM',
|
||||
'Client IP': 'Client IP',
|
||||
'Close': 'Close',
|
||||
'Close': 'Chiudi',
|
||||
'Cognome': 'Cognome',
|
||||
'Community': 'Community',
|
||||
'Components and Plugins': 'Components and Plugins',
|
||||
'contains': 'contains',
|
||||
'Components and Plugins': 'Componenti and Plugin',
|
||||
'contains': 'contiene',
|
||||
'Controller': 'Controller',
|
||||
'Copyright': 'Copyright',
|
||||
'Created By': 'Created By',
|
||||
'Created On': 'Created On',
|
||||
'Created By': 'Creato Da',
|
||||
'Created On': 'Creato Il',
|
||||
'CSV': 'CSV',
|
||||
'CSV (hidden cols)': 'CSV (hidden cols)',
|
||||
'Current request': 'Richiesta (request) corrente',
|
||||
@@ -61,7 +62,7 @@
|
||||
'Database %s select': 'Database %s select',
|
||||
'db': 'db',
|
||||
'DB Model': 'Modello di DB',
|
||||
'Delete': 'Delete',
|
||||
'Delete': 'Cancella',
|
||||
'Delete:': 'Cancella:',
|
||||
'Demo': 'Demo',
|
||||
'Deployment Recipes': 'Deployment Recipes',
|
||||
@@ -71,7 +72,7 @@
|
||||
'Disk Cache Keys': 'Disk Cache Keys',
|
||||
'Disk Cleared': 'Disk Cleared',
|
||||
'Documentation': 'Documentazione',
|
||||
"Don't know what to do?": "Don't know what to do?",
|
||||
"Don't know what to do?": 'Non sai cosa fare?',
|
||||
'done!': 'fatto!',
|
||||
'Download': 'Download',
|
||||
'E-mail': 'E-mail',
|
||||
@@ -79,18 +80,19 @@
|
||||
'Edit current record': 'Modifica record corrente',
|
||||
'edit profile': 'modifica profilo',
|
||||
'Edit This App': 'Modifica questa applicazione',
|
||||
'Email and SMS': 'Email and SMS',
|
||||
'Email and SMS': 'Email e SMS',
|
||||
'Email non valida': 'Email non valida',
|
||||
'enter an integer between %(min)g and %(max)g': 'enter an integer between %(min)g and %(max)g',
|
||||
'Errors': 'Errors',
|
||||
'Errors in form, please check it out.': 'Errors in form, please check it out.',
|
||||
'enter an integer between %(min)g and %(max)g': 'inserisci un intero tra %(min)g e %(max)g',
|
||||
'Errors': 'Errori',
|
||||
'Errors in form, please check it out.': 'Errori nel form, ricontrollalo',
|
||||
'export as csv file': 'esporta come file CSV',
|
||||
'Export:': 'Export:',
|
||||
'Export:': 'Esporta:',
|
||||
'FAQ': 'FAQ',
|
||||
'First name': 'Nome',
|
||||
'Forgot username?': 'Forgot username?',
|
||||
'Forgot username?': 'Dimenticato lo username?',
|
||||
'Forms and Validators': 'Forms and Validators',
|
||||
'Free Applications': 'Free Applications',
|
||||
'Graph Model': 'Graph Model',
|
||||
'Group %(group_id)s created': 'Group %(group_id)s created',
|
||||
'Group ID': 'ID Gruppo',
|
||||
'Group uniquely assigned to user %(id)s': 'Group uniquely assigned to user %(id)s',
|
||||
@@ -100,69 +102,70 @@
|
||||
'Hello World': 'Salve Mondo',
|
||||
'Hello World in a flash!': 'Salve Mondo in un flash!',
|
||||
'Home': 'Home',
|
||||
'How did you get here?': 'How did you get here?',
|
||||
'How did you get here?': 'Come sei arrivato qui?',
|
||||
'HTML': 'HTML',
|
||||
'import': 'import',
|
||||
'import': 'importa',
|
||||
'Import/Export': 'Importa/Esporta',
|
||||
'Index': 'Indice',
|
||||
'insert new': 'inserisci nuovo',
|
||||
'insert new %s': 'inserisci nuovo %s',
|
||||
'Internal State': 'Stato interno',
|
||||
'Introduction': 'Introduction',
|
||||
'Introduction': 'Introduzione',
|
||||
'Invalid email': 'Email non valida',
|
||||
'Invalid login': 'Invalid login',
|
||||
'Invalid login': 'Login non valido',
|
||||
'Invalid Query': 'Richiesta (query) non valida',
|
||||
'invalid request': 'richiesta non valida',
|
||||
'Is Active': 'Is Active',
|
||||
'Key': 'Key',
|
||||
'Is Active': "E' attivo",
|
||||
'Key': 'Chiave',
|
||||
'Last name': 'Cognome',
|
||||
'Layout': 'Layout',
|
||||
'Layout Plugins': 'Layout Plugins',
|
||||
'Layouts': 'Layouts',
|
||||
'Live Chat': 'Live Chat',
|
||||
'Logged in': 'Logged in',
|
||||
'Logged out': 'Logged out',
|
||||
'Logged in': 'Loggato',
|
||||
'Logged out': 'Disconnesso',
|
||||
'login': 'accesso',
|
||||
'Login': 'Login',
|
||||
'logout': 'uscita',
|
||||
'Logout': 'Logout',
|
||||
'Lost Password': 'Lost Password',
|
||||
'Lost password?': 'Lost password?',
|
||||
'Lost Password': 'Password Smarrita',
|
||||
'Lost password?': 'Password smarrita?',
|
||||
'lost password?': 'dimenticato la password?',
|
||||
'Main Menu': 'Menu principale',
|
||||
'Manage Cache': 'Manage Cache',
|
||||
'Menu Model': 'Menu Modelli',
|
||||
'Modified By': 'Modified By',
|
||||
'Modified On': 'Modified On',
|
||||
'Modified By': 'Modificato da',
|
||||
'Modified On': 'Modificato il',
|
||||
'My Sites': 'My Sites',
|
||||
'Name': 'Nome',
|
||||
'New': 'New',
|
||||
'New password': 'New password',
|
||||
'New': 'Nuovo',
|
||||
'New password': 'Nuova password',
|
||||
'New Record': 'Nuovo elemento (record)',
|
||||
'new record inserted': 'nuovo record inserito',
|
||||
'next 100 rows': 'prossime 100 righe',
|
||||
'No databases in this application': 'Nessun database presente in questa applicazione',
|
||||
'No records found': 'No records found',
|
||||
'No records found': 'Nessun record trovato',
|
||||
'Nome': 'Nome',
|
||||
'Non può essere vuoto': 'Non può essere vuoto',
|
||||
'not authorized': 'non autorizzato',
|
||||
'Object or table name': 'Object or table name',
|
||||
'Old password': 'Old password',
|
||||
'Object or table name': 'Oggeto o nome tabella',
|
||||
'Old password': 'Vecchia password',
|
||||
'Online examples': 'Vedere gli esempi',
|
||||
'Or': 'Or',
|
||||
'Or': 'O',
|
||||
'or import from csv file': 'oppure importa da file CSV',
|
||||
'Origin': 'Origine',
|
||||
'Other Plugins': 'Other Plugins',
|
||||
'Other Recipes': 'Other Recipes',
|
||||
'Overview': 'Overview',
|
||||
'Password': 'Password',
|
||||
"Password fields don't match": "Password fields don't match",
|
||||
'please input your password again': 'please input your password again',
|
||||
"Password fields don't match": 'I campi password non sono uguali',
|
||||
'please input your password again': 'perfavore reimmeti la tua password',
|
||||
'Plugins': 'Plugins',
|
||||
'Powered by': 'Powered by',
|
||||
'Preface': 'Preface',
|
||||
'previous 100 rows': '100 righe precedenti',
|
||||
'Profile': 'Profile',
|
||||
'Profile': 'Profilo',
|
||||
'pygraphviz library not found': 'pygraphviz library not found',
|
||||
'Python': 'Python',
|
||||
'Query:': 'Richiesta (query):',
|
||||
'Quick Examples': 'Quick Examples',
|
||||
@@ -174,28 +177,30 @@
|
||||
'record does not exist': 'il record non esiste',
|
||||
'Record ID': 'Record ID',
|
||||
'Record id': 'Record id',
|
||||
'Register': 'Register',
|
||||
'Register': 'Registrati',
|
||||
'register': 'registrazione',
|
||||
'Registration identifier': 'Registration identifier',
|
||||
'Registration key': 'Chiave di Registazione',
|
||||
'Registration successful': 'Registration successful',
|
||||
'Remember me (for 30 days)': 'Remember me (for 30 days)',
|
||||
'Request reset password': 'Request reset password',
|
||||
'Registration successful': 'Registrazione avvenuta',
|
||||
'reload': 'reload',
|
||||
'Remember me (for 30 days)': 'Ricordami (per 30 giorni)',
|
||||
'Request reset password': 'Richiedi il reset della password',
|
||||
'Reset Password key': 'Resetta chiave Password ',
|
||||
'Role': 'Ruolo',
|
||||
'Rows in Table': 'Righe nella tabella',
|
||||
'Rows selected': 'Righe selezionate',
|
||||
'Save profile': 'Save profile',
|
||||
'Search': 'Search',
|
||||
'Save model as...': 'Salva modello come...',
|
||||
'Save profile': 'Salva profilo',
|
||||
'Search': 'Ricerca',
|
||||
'Semantic': 'Semantic',
|
||||
'Services': 'Services',
|
||||
'Services': 'Servizi',
|
||||
'Size of cache:': 'Size of cache:',
|
||||
'starts with': 'starts with',
|
||||
'starts with': 'comincia con',
|
||||
'state': 'stato',
|
||||
'Statistics': 'Statistics',
|
||||
'Stylesheet': 'Foglio di stile (stylesheet)',
|
||||
'submit': 'submit',
|
||||
'Submit': 'Submit',
|
||||
'submit': 'Inviai',
|
||||
'Submit': 'Invia',
|
||||
'Support': 'Support',
|
||||
'Sure you want to delete this object?': 'Vuoi veramente cancellare questo oggetto?',
|
||||
'Table': 'tabella',
|
||||
@@ -208,12 +213,13 @@
|
||||
'This is a copy of the scaffolding application': "Questa è una copia dell'applicazione di base (scaffold)",
|
||||
'Time in Cache (h:m:s)': 'Time in Cache (h:m:s)',
|
||||
'Timestamp': 'Ora (timestamp)',
|
||||
'too short': 'too short',
|
||||
'TSV (Excel compatible)': 'TSV (Excel compatible)',
|
||||
'TSV (Excel compatible, hidden cols)': 'TSV (Excel compatible, hidden cols)',
|
||||
'too short': 'troppo corto',
|
||||
'Traceback': 'Traceback',
|
||||
'TSV (Excel compatible)': 'TSV (Excel compatibile)',
|
||||
'TSV (Excel compatible, hidden cols)': 'TSV (Excel compatibile, hidden cols)',
|
||||
'Twitter': 'Twitter',
|
||||
'unable to parse csv file': 'non riesco a decodificare questo file CSV',
|
||||
'Update': 'Update',
|
||||
'Update': 'Aggiorna',
|
||||
'Update:': 'Aggiorna:',
|
||||
'Use (...)&(...) for AND, (...)|(...) for OR, and ~(...) for NOT to build more complex queries.': 'Per costruire richieste (query) più complesse si usano (...)&(...) come "e" (AND), (...)|(...) come "o" (OR), e ~(...) come negazione (NOT).',
|
||||
'User %(id)s Logged-in': 'User %(id)s Logged-in',
|
||||
@@ -223,14 +229,14 @@
|
||||
'User %(id)s Profile updated': 'User %(id)s Profile updated',
|
||||
'User %(id)s Registered': 'User %(id)s Registered',
|
||||
'User ID': 'ID Utente',
|
||||
'value already in database or empty': 'value already in database or empty',
|
||||
'Verify Password': 'Verify Password',
|
||||
'value already in database or empty': 'valore già presente nel database o vuoto',
|
||||
'Verify Password': 'Verifica Password',
|
||||
'Videos': 'Videos',
|
||||
'View': 'Vista',
|
||||
'Welcome': 'Welcome',
|
||||
'Welcome %s': 'Benvenuto %s',
|
||||
'Welcome to web2py': 'Benvenuto su web2py',
|
||||
'Welcome to web2py!': 'Welcome to web2py!',
|
||||
'Welcome to web2py!': 'Benvenuto in web2py!',
|
||||
'Which called the function %s located in the file %s': 'che ha chiamato la funzione %s presente nel file %s',
|
||||
'XML': 'XML',
|
||||
'You are successfully running web2py': 'Stai eseguendo web2py con successo',
|
||||
|
||||
Executable
+217
@@ -0,0 +1,217 @@
|
||||
# coding: utf8
|
||||
{
|
||||
'!langcode!': 'my',
|
||||
'!langname!': 'Malay',
|
||||
'%d days ago': '%d hari yang lalu',
|
||||
'%d hours ago': '%d jam yang lalu',
|
||||
'%d minutes ago': '%d minit yang lalu',
|
||||
'%d months ago': '%d bulan yang lalu',
|
||||
'%d seconds ago': '%d saat yang lalu',
|
||||
'%d seconds from now': '%d saat dari sekarang',
|
||||
'%d weeks ago': '%d minggu yang lalu',
|
||||
'%d years ago': '%d tahun yang lalu',
|
||||
'%s %%{row} deleted': '%s %%{row} dihapuskan',
|
||||
'%s %%{row} updated': '%s %%{row} dikemas kini',
|
||||
'%s selected': '%s dipilih',
|
||||
'%Y-%m-%d': '%d-%m-%Y',
|
||||
'%Y-%m-%d %H:%M:%S': '%d-%m-%Y %H:%M:%S',
|
||||
'(requires internet access, experimental)': '(memerlukan akses internet, percubaan)',
|
||||
'(something like "it-it")': '(sesuatu seperti "it-it")',
|
||||
'1 day ago': '1 hari yang lalu',
|
||||
'1 hour ago': '1 jam yang lalu',
|
||||
'1 minute ago': '1 minit yang lalu',
|
||||
'1 month ago': '1 bulan yang lalu',
|
||||
'1 second ago': '1 saat yang lalu',
|
||||
'1 week ago': '1 minggu yang lalu',
|
||||
'1 year ago': '1 tahun yang lalu',
|
||||
'< Previous': '< Sebelumnya',
|
||||
'About': 'Mengenai',
|
||||
'Add': 'Tambah',
|
||||
'Admin language': 'Bahasa admin',
|
||||
'Administrator Password:': 'Kata laluan Administrator:',
|
||||
'Ajax Recipes': 'Resipi Ajax',
|
||||
'An error occured, please %s the page': 'Kesilapan telah berlaku, sila %s laman',
|
||||
'And': 'Dan',
|
||||
'and rename it:': 'dan menamakan itu:',
|
||||
'are not used yet': 'tidak digunakan lagi',
|
||||
'Are you sure you want to delete this object?': 'Apakah anda yakin anda mahu memadam ini?',
|
||||
'Back': 'Kembali',
|
||||
'Buy this book': 'Beli buku ini',
|
||||
'cache, errors and sessions cleaned': 'cache, kesilapan dan sesi dibersihkan',
|
||||
'Cancel': 'Batal',
|
||||
'Cannot be empty': 'Tidak boleh kosong',
|
||||
'Change admin password': 'Tukar kata laluan admin',
|
||||
'Change password': 'Tukar kata laluan',
|
||||
'Clean': 'Bersihkan',
|
||||
'Clear': 'Hapus',
|
||||
'Clear CACHE?': 'Hapus CACHE?',
|
||||
'Clear DISK': 'Hapus DISK',
|
||||
'Clear RAM': 'Hapus RAM',
|
||||
'Click row to expand traceback': 'Klik baris untuk mengembangkan traceback',
|
||||
'Close': 'Tutup',
|
||||
'Community': 'Komuniti',
|
||||
'Components and Plugins': 'Komponen dan Plugin',
|
||||
'contains': 'mengandung',
|
||||
'Copyright': 'Hak Cipta',
|
||||
'Create': 'Buat',
|
||||
'create file with filename:': 'mencipta fail dengan nama:',
|
||||
'created by': 'dicipta oleh',
|
||||
'currently running': 'sedang berjalan',
|
||||
'data uploaded': 'data diunggah',
|
||||
'Delete': 'Hapus',
|
||||
'Delete this file (you will be asked to confirm deletion)': 'Padam fail ini (anda akan diminta untuk mengesahkan pemadaman)',
|
||||
'Delete:': 'Hapus:',
|
||||
'design': 'disain',
|
||||
'direction: ltr': 'arah: ltr',
|
||||
'Disk Cleared': 'Disk Dihapuskan',
|
||||
'Documentation': 'Dokumentasi',
|
||||
"Don't know what to do?": 'Tidak tahu apa yang perlu dilakukan?',
|
||||
'done!': 'selesai!',
|
||||
'Download': 'Unduh',
|
||||
'Duration': 'Tempoh',
|
||||
'Email : ': 'Emel : ',
|
||||
'Email sent': 'Emel dihantar',
|
||||
'enter a valid email address': 'masukkan alamat emel yang benar',
|
||||
'enter a valid URL': 'masukkan URL yang benar',
|
||||
'enter a value': 'masukkan data',
|
||||
'Error': 'Kesalahan',
|
||||
'Errors': 'Kesalahan',
|
||||
'export as csv file': 'eksport sebagai file csv',
|
||||
'Export:': 'Eksport:',
|
||||
'File': 'Fail',
|
||||
'filter': 'menapis',
|
||||
'First Name': 'Nama Depan',
|
||||
'Forgot username?': 'Lupa nama pengguna?',
|
||||
'Free Applications': 'Aplikasi Percuma',
|
||||
'Gender': 'Jenis Kelamin',
|
||||
'Group %(group_id)s created': 'Kumpulan %(group_id)s dicipta',
|
||||
'Group uniquely assigned to user %(id)s': 'Kumpulan unik yang diberikan kepada pengguna %(id)s',
|
||||
'Groups': 'Kumpulan',
|
||||
'Hello World': 'Halo Dunia',
|
||||
'Help': 'Bantuan',
|
||||
'Home': 'Laman Utama',
|
||||
'How did you get here?': 'Bagaimana kamu boleh di sini?',
|
||||
'Image': 'Gambar',
|
||||
'import': 'import',
|
||||
'Import/Export': 'Import/Eksport',
|
||||
'includes': 'termasuk',
|
||||
'Install': 'Pasang',
|
||||
'Installation': 'Pemasangan',
|
||||
'Introduction': 'Pengenalan',
|
||||
'Invalid email': 'Emel tidak benar',
|
||||
'Language': 'Bahasa',
|
||||
'languages': 'bahasa',
|
||||
'Languages': 'Bahasa',
|
||||
'Last Name': 'Nama Belakang',
|
||||
'License for': 'lesen untuk',
|
||||
'loading...': 'sedang memuat...',
|
||||
'Logged in': 'Masuk',
|
||||
'Logged out': 'Keluar',
|
||||
'Login': 'Masuk',
|
||||
'Logout': 'Keluar',
|
||||
'Lost Password': 'Lupa Kata Laluan',
|
||||
'Lost password?': 'Lupa kata laluan?',
|
||||
'Maintenance': 'Penyelenggaraan',
|
||||
'Manage': 'Menguruskan',
|
||||
'Manage Cache': 'Menguruskan Cache',
|
||||
'models': 'model',
|
||||
'Models': 'Model',
|
||||
'Modules': 'Modul',
|
||||
'modules': 'modul',
|
||||
'My Sites': 'Laman Saya',
|
||||
'New': 'Baru',
|
||||
'New password': 'Kata laluan baru',
|
||||
'next 100 rows': '100 baris seterusnya',
|
||||
'Next >': 'Seterusnya >',
|
||||
'Next Page': 'Laman Seterusnya',
|
||||
'No ticket_storage.txt found under /private folder': 'Ticket_storage.txt tidak dijumpai di bawah folder /private',
|
||||
'not a Zip Code': 'bukan Pos',
|
||||
'Old password': 'Kata laluan lama',
|
||||
'Online examples': 'Contoh Online',
|
||||
'Or': 'Atau',
|
||||
'or alternatively': 'atau sebagai alternatif',
|
||||
'Or Get from URL:': 'Atau Dapatkan dari URL:',
|
||||
'or import from csv file': 'atau import dari file csv',
|
||||
'Other Plugins': 'Plugin Lain',
|
||||
'Other Recipes': 'Resipi Lain',
|
||||
'Overview': 'Tinjauan',
|
||||
'Pack all': 'Mengemaskan semua',
|
||||
'Password': 'Kata laluan',
|
||||
'Password changed': 'Kata laluan berubah',
|
||||
"Password fields don't match": 'Kata laluan tidak sama',
|
||||
'please input your password again': 'sila masukan kata laluan anda lagi',
|
||||
'plugins': 'plugin',
|
||||
'Plugins': 'Plugin',
|
||||
'Powered by': 'Disokong oleh',
|
||||
'Preface': 'Pendahuluan',
|
||||
'previous 100 rows': '100 baris sebelumnya',
|
||||
'Previous Page': 'Laman Sebelumnya',
|
||||
'private files': 'fail peribadi',
|
||||
'Private files': 'Fail peribadi',
|
||||
'Profile': 'Profil',
|
||||
'Profile updated': 'Profil dikemaskini',
|
||||
'Project Progress': 'Kemajuan Projek',
|
||||
'Quick Examples': 'Contoh Cepat',
|
||||
'Ram Cleared': 'Ram Dihapuskan',
|
||||
'Recipes': 'Resipi',
|
||||
'Register': 'Daftar',
|
||||
'Registration successful': 'Pendaftaran berjaya',
|
||||
'reload': 'memuat kembali',
|
||||
'Reload routes': 'Memuat laluan kembali',
|
||||
'Remember me (for 30 days)': 'Ingat saya (selama 30 hari)',
|
||||
'Request reset password': 'Meminta reset kata laluan',
|
||||
'Rows selected': 'Baris dipilih',
|
||||
'Running on %s': 'Berjalan pada %s',
|
||||
'Save model as...': 'Simpan model sebagai ...',
|
||||
'Save profile': 'Simpan profil',
|
||||
'Search': 'Cari',
|
||||
'Select Files to Package': 'Pilih Fail untuk Pakej',
|
||||
'Send Email': 'Kirim Emel',
|
||||
'Size of cache:': 'Saiz cache:',
|
||||
'Solution': 'Penyelesaian',
|
||||
'starts with': 'bermula dengan',
|
||||
'static': 'statik',
|
||||
'Static': 'Statik',
|
||||
'Statistics': 'Statistik',
|
||||
'Support': 'Menyokong',
|
||||
'test': 'ujian',
|
||||
'There are no plugins': 'Tiada plugin',
|
||||
'There are no private files': 'Tiada fail peribadi',
|
||||
'These files are not served, they are only available from within your app': 'Fail-fail ini tidak disampaikan, mereka hanya boleh didapati dari dalam aplikasi anda',
|
||||
'These files are served without processing, your images go here': 'Ini fail disampaikan tanpa pemprosesan, imej anda di sini',
|
||||
'This App': 'App Ini',
|
||||
'Time in Cache (h:m:s)': 'Waktu di Cache (h: m: s)',
|
||||
'Title': 'Judul',
|
||||
'To create a plugin, name a file/folder plugin_[name]': 'Untuk mencipta plugin, nama fail/folder plugin_ [nama]',
|
||||
'too short': 'terlalu pendek',
|
||||
'Unable to download because:': 'Tidak dapat memuat turun kerana:',
|
||||
'unable to parse csv file': 'tidak mampu mengurai file csv',
|
||||
'update all languages': 'mengemaskini semua bahasa',
|
||||
'Update:': 'Kemas kini:',
|
||||
'Upgrade': 'Menaik taraf',
|
||||
'Upload': 'Unggah',
|
||||
'Upload a package:': 'Unggah pakej:',
|
||||
'upload file:': 'unggah fail:',
|
||||
'upload plugin file:': 'unggah fail plugin:',
|
||||
'User %(id)s Logged-in': 'Pengguna %(id)s Masuk',
|
||||
'User %(id)s Logged-out': 'Pengguna %(id)s Keluar',
|
||||
'User %(id)s Password changed': 'Pengguna %(id)s Kata Laluan berubah',
|
||||
'User %(id)s Password reset': 'Pengguna %(id)s Kata Laluan telah direset',
|
||||
'User %(id)s Profile updated': 'Pengguna %(id)s Profil dikemaskini',
|
||||
'User %(id)s Registered': 'Pengguna %(id)s Didaftarkan',
|
||||
'value not allowed': 'data tidak benar',
|
||||
'Verify Password': 'Pengesahan Kata Laluan',
|
||||
'Version': 'Versi',
|
||||
'Versioning': 'Pembuatan Sejarah',
|
||||
'View': 'Lihat',
|
||||
'Views': 'Lihat',
|
||||
'views': 'Lihat',
|
||||
'Web Framework': 'Rangka Kerja Web',
|
||||
'web2py Recent Tweets': 'Tweet terbaru web2py',
|
||||
'Website': 'Laman Web',
|
||||
'Welcome': 'Selamat Datang',
|
||||
'Welcome to web2py!': 'Selamat Datang di web2py!',
|
||||
'You are successfully running web2py': 'Anda berjaya menjalankan web2py',
|
||||
'You can modify this application and adapt it to your needs': 'Anda boleh mengubah suai aplikasi ini dan menyesuaikan dengan keperluan anda',
|
||||
'You visited the url %s': 'Anda melawat url %s',
|
||||
}
|
||||
@@ -0,0 +1,129 @@
|
||||
# coding: utf8
|
||||
{
|
||||
'!langcode!': 'tr',
|
||||
'!langname!': 'Türkçe',
|
||||
'%s %%(shop)': '%s %%(shop)',
|
||||
'%s %%(shop[0])': '%s %%(shop[0])',
|
||||
'%s %%{quark[0]}': '%s %%{quark[0]}',
|
||||
'%s %%{shop[0]}': '%s %%{shop[0]}',
|
||||
'%s %%{shop}': '%s %%{shop}',
|
||||
'%Y-%m-%d': '%Y-%m-%d',
|
||||
'%Y-%m-%d %H:%M:%S': '%Y-%m-%d %H:%M:%S',
|
||||
'@markmin\x01**Hello World**': '**Merhaba Dünya**',
|
||||
'About': 'Hakkında',
|
||||
'Access Control': 'Erişim Denetimi',
|
||||
'Administrative Interface': 'Yönetim Arayüzü',
|
||||
'Ajax Recipes': 'Ajax Tarifleri',
|
||||
'An error occured, please %s the page': 'Bir hata meydana geldi, lütfen sayfayı %s',
|
||||
'Are you sure you want to delete this object?': 'Bu nesneyi silmek istediğinden emin misin?',
|
||||
'Buy this book': 'Bu kitabı satın alın',
|
||||
'Cannot be empty': 'Boş bırakılamaz',
|
||||
'Check to delete': 'Silmek için denetle',
|
||||
'Client IP': ' IP',
|
||||
'Community': 'Topluluk',
|
||||
'Components and Plugins': 'Bileşenler ve Eklentiler',
|
||||
'Controller': 'Denetçi',
|
||||
'Copyright': 'Telif',
|
||||
'Created By': 'Tasarlayan',
|
||||
'Created On': 'Oluşturma tarihi',
|
||||
'customize me!': 'burayı değiştir!',
|
||||
'Database': 'Veritabanı',
|
||||
'DB Model': 'DB Model',
|
||||
'Demo': 'Demo',
|
||||
'Deployment Recipes': 'Yayınlama tarifleri',
|
||||
'Description': 'Açıklama',
|
||||
'Documentation': 'Kitap',
|
||||
"Don't know what to do?": 'Neleri nasıl yapacağını bilmiyor musun?',
|
||||
'Download': 'İndir',
|
||||
'E-mail': 'E-posta',
|
||||
'Email and SMS': 'E-posta ve kısa mesaj (SMS)',
|
||||
'enter an integer between %(min)g and %(max)g': '%(min)g ve %(max)g arasında bir sayı girin',
|
||||
'enter date and time as %(format)s': 'tarih ve saati %(format)s biçiminde girin',
|
||||
'Errors': 'Hatalar',
|
||||
'FAQ': 'SSS',
|
||||
'First name': 'Ad',
|
||||
'Forgot username?': 'Kullanıcı adını mı unuttun?',
|
||||
'Forms and Validators': 'Biçimler ve Doğrulayıcılar',
|
||||
'Free Applications': 'Ücretsiz uygulamalar',
|
||||
'Giriş': 'Giriş',
|
||||
'Group %(group_id)s created': '%(group_id)s takımı oluşturuldu',
|
||||
'Group ID': 'Takım ID',
|
||||
'Group uniquely assigned to user %(id)s': 'Group uniquely assigned to user %(id)s',
|
||||
'Groups': 'Topluluklar',
|
||||
'Hello World': 'Merhaba Dünyalı',
|
||||
'Hello World ## comment': 'Merhaba Dünyalı ',
|
||||
'Hello World## comment': 'Merhaba Dünyalı',
|
||||
'Home': 'Anasayfa',
|
||||
'How did you get here?': 'Bu sayfayı görüntüleme uğruna neler mi oldu?',
|
||||
'Introduction': 'Giriş',
|
||||
'Invalid email': 'Yanlış eposta',
|
||||
'Is Active': 'Etkin',
|
||||
'Kayıt ol': 'Kayıt ol',
|
||||
'Last name': 'Soyad',
|
||||
'Layout': 'Şablon',
|
||||
'Layout Plugins': 'Şablon Eklentileri',
|
||||
'Layouts': 'Şablonlar',
|
||||
'Live Chat': 'Canlı Sohbet',
|
||||
'Logged in': 'Giriş yapıldı',
|
||||
'Logged out': 'Çıkış yapıldı',
|
||||
'Login': 'Giriş',
|
||||
'Logout': 'Terket',
|
||||
'Lost Password': 'Şifremi unuttum',
|
||||
'Lost password?': 'Şifrenizimi unuttunuz?',
|
||||
'Menu Model': 'Menu Model',
|
||||
'Modified By': 'Değiştiren',
|
||||
'Modified On': 'Değiştirilme tarihi',
|
||||
'My Sites': 'Sitelerim',
|
||||
'Name': 'İsim',
|
||||
'Object or table name': 'Nesne ya da tablo adı',
|
||||
'Online examples': 'Canlı örnekler',
|
||||
'Origin': 'Origin',
|
||||
'Other Plugins': 'Diğer eklentiler',
|
||||
'Other Recipes': 'Diğer Tarifler',
|
||||
'Overview': 'Göz gezdir',
|
||||
'Password': 'Şifre',
|
||||
"Password fields don't match": 'Şifreler uyuşmuyor',
|
||||
'please input your password again': 'lütfen şifrenizi tekrar girin',
|
||||
'Plugins': 'Eklentiler',
|
||||
'Powered by': 'Yazılım Temeli',
|
||||
'Preface': 'Preface',
|
||||
'Profile': 'Hakkımda',
|
||||
'Python': 'Python',
|
||||
'Quick Examples': 'Hızlı Örnekler',
|
||||
'Recipes': 'Recipes',
|
||||
'Record ID': 'Kayıt ID',
|
||||
'Register': 'Kayıt ol',
|
||||
'Registration identifier': 'Registration identifier',
|
||||
'Registration key': 'Kayıt anahtarı',
|
||||
'Registration successful': 'Kayıt başarılı',
|
||||
'reload': 'reload',
|
||||
'Remember me (for 30 days)': 'Beni hatırla (30 gün)',
|
||||
'Request reset password': 'Şifre sıfırla',
|
||||
'Reset Password key': 'Şifre anahtarını sıfırla',
|
||||
'Role': 'Role',
|
||||
'Semantic': 'Semantik',
|
||||
'Services': 'Hizmetler',
|
||||
'Stylesheet': 'Stil Şablonu',
|
||||
'Support': 'Destek',
|
||||
'The Core': 'Çekirdek',
|
||||
'The output of the file is a dictionary that was rendered by the view %s': 'Son olarak fonksiyonların vs. işlenip %s dosyasıyla tasarıma yedirilmesiyle sayfayı görüntüledin',
|
||||
'The Views': 'The Views',
|
||||
'This App': 'Bu Uygulama',
|
||||
'Timestamp': 'Zaman damgası',
|
||||
'Twitter': 'Twitter',
|
||||
'User %(id)s Logged-in': '%(id)s Giriş yaptı',
|
||||
'User %(id)s Logged-out': '%(id)s çıkış yaptı',
|
||||
'User %(id)s Password reset': 'User %(id)s Password reset',
|
||||
'User %(id)s Registered': '%(id)s Kayıt oldu',
|
||||
'User ID': 'Kullanıcı ID',
|
||||
'value already in database or empty': 'değer boş ya da veritabanında zaten mevcut',
|
||||
'Verify Password': 'Şifreni Onayla',
|
||||
'Videos': 'Videolar',
|
||||
'View': 'View',
|
||||
'Welcome': 'Hoşgeldin',
|
||||
'Welcome to web2py!': 'Welcome to web2py!',
|
||||
'Which called the function %s located in the file %s': 'Bu ziyaretle %s fonksiyonunu %s dosyasından çağırmış oldun ',
|
||||
'You are successfully running web2py': 'web2py çatısını çalıştırmayı başardın',
|
||||
'You can modify this application and adapt it to your needs': 'Artık uygulamayı kafana göre düzenleyebilirsin!',
|
||||
'You visited the url %s': '%s adresini ziyaret ettin',
|
||||
}
|
||||
@@ -0,0 +1,244 @@
|
||||
# coding: utf8
|
||||
{
|
||||
'!langcode!': 'zh-cn',
|
||||
'!langname!': '中文',
|
||||
'"update" is an optional expression like "field1=\'newvalue\'". You cannot update or delete the results of a JOIN': '"update" 应为选择表达式, 格式如 "field1=\'value\'". 但是对 JOIN 的结果不可以使用 update 或者 delete"',
|
||||
'%s %%{row} deleted': '已删除 %s 笔',
|
||||
'%s %%{row} updated': '已更新 %s 笔',
|
||||
'%s selected': '%s 已选择',
|
||||
'%Y-%m-%d': '%Y-%m-%d',
|
||||
'%Y-%m-%d %H:%M:%S': '%Y-%m-%d %H:%M:%S',
|
||||
'(something like "it-it")': '(格式类似 "zh-tw")',
|
||||
'A new version of web2py is available': '新版 web2py 已推出',
|
||||
'A new version of web2py is available: %s': '新版 web2py 已推出: %s',
|
||||
'about': '关于',
|
||||
'About': '关于',
|
||||
'About application': '关于本应用程序',
|
||||
'Access Control': 'Access Control',
|
||||
'Admin is disabled because insecure channel': '管理功能(Admin)在非安全连接环境下自动关闭',
|
||||
'Admin is disabled because unsecure channel': '管理功能(Admin)在非安全连接环境下自动关闭',
|
||||
'Administrative Interface': 'Administrative Interface',
|
||||
'Administrative interface': '点击进入管理界面',
|
||||
'Administrator Password:': '管理员密码:',
|
||||
'Ajax Recipes': 'Ajax Recipes',
|
||||
'An error occured, please %s the page': 'An error occured, please %s the page',
|
||||
'appadmin is disabled because insecure channel': '管理界面在非安全通道下被禁用',
|
||||
'Are you sure you want to delete file "%s"?': '确定要删除文件"%s"?',
|
||||
'Are you sure you want to delete this object?': '确定要删除该对象么?',
|
||||
'Are you sure you want to uninstall application "%s"': '确定要删除应用程序 "%s"',
|
||||
'Are you sure you want to uninstall application "%s"?': '确定要删除应用程序 "%s"',
|
||||
'ATTENTION: Login requires a secure (HTTPS) connection or running on localhost.': '注意: 登录管理账号需要安全连接(HTTPS)或是在本地连接(localhost).',
|
||||
'ATTENTION: TESTING IS NOT THREAD SAFE SO DO NOT PERFORM MULTIPLE TESTS CONCURRENTLY.': '注意: 因为在测试模式不保证多线程安全性,所以不可同时执行多个测试案例',
|
||||
'ATTENTION: you cannot edit the running application!': '注意:不可编辑正在执行的应用程序!',
|
||||
'Authentication': '验证',
|
||||
'Available Databases and Tables': '可提供的数据库和数据表',
|
||||
'Buy this book': '购买本书',
|
||||
'cache': '高速缓存',
|
||||
'Cache': 'Cache',
|
||||
'Cache Keys': 'Cache Keys',
|
||||
'Cannot be empty': '不可空白',
|
||||
'Cannot compile: there are errors in your app. Debug it, correct errors and try again.': '编译失败:应用程序有错误,请排除错误后再尝试编译.',
|
||||
'Change Password': '修改密码',
|
||||
'change password': '修改密码',
|
||||
'Check to delete': '打勾以示删除',
|
||||
'Check to delete:': '打勾以示删除:',
|
||||
'Clear CACHE?': 'Clear CACHE?',
|
||||
'Clear DISK': 'Clear DISK',
|
||||
'Clear RAM': 'Clear RAM',
|
||||
'Client IP': '客户端网址(IP)',
|
||||
'Community': 'Community',
|
||||
'Components and Plugins': 'Components and Plugins',
|
||||
'Controller': '控件',
|
||||
'Controllers': '控件',
|
||||
'Copyright': '版权所有',
|
||||
'Create new application': '创建应用程序',
|
||||
'Created By': 'Created By',
|
||||
'Created On': 'Created On',
|
||||
'Current request': '当前网络要求(request)',
|
||||
'Current response': '当前网络响应(response)',
|
||||
'Current session': '当前网络连接信息(session)',
|
||||
'customize me!': '请调整我!',
|
||||
'data uploaded': '数据已上传',
|
||||
'Database': '数据库',
|
||||
'Database %s select': '已选择 %s 数据库',
|
||||
'Date and Time': '日期和时间',
|
||||
'db': 'db',
|
||||
'DB Model': '数据库模型',
|
||||
'Delete': '删除',
|
||||
'Delete:': '删除:',
|
||||
'Demo': 'Demo',
|
||||
'Deploy on Google App Engine': '发布到 Google App Engine',
|
||||
'Deployment Recipes': 'Deployment Recipes',
|
||||
'Description': '描述',
|
||||
'DESIGN': '设计',
|
||||
'design': '设计',
|
||||
'Design for': '设计用于',
|
||||
'DISK': 'DISK',
|
||||
'Disk Cache Keys': 'Disk Cache Keys',
|
||||
'Disk Cleared': 'Disk Cleared',
|
||||
'Documentation': 'Documentation',
|
||||
"Don't know what to do?": "Don't know what to do?",
|
||||
'done!': '完成!',
|
||||
'Download': '下载',
|
||||
'E-mail': '电子邮件',
|
||||
'EDIT': '编辑',
|
||||
'Edit': '编辑',
|
||||
'Edit application': '编辑应用程序',
|
||||
'Edit current record': '编辑当前记录',
|
||||
'edit profile': '编辑配置文件',
|
||||
'Edit Profile': '编辑配置文件',
|
||||
'Edit This App': '编辑本应用程序',
|
||||
'Editing file': '编辑文件',
|
||||
'Editing file "%s"': '编辑文件"%s"',
|
||||
'Email and SMS': 'Email and SMS',
|
||||
'enter an integer between %(min)g and %(max)g': 'enter an integer between %(min)g and %(max)g',
|
||||
'Error logs for "%(app)s"': '"%(app)s"的错误记录',
|
||||
'Errors': 'Errors',
|
||||
'export as csv file': '以CSV格式导出',
|
||||
'FAQ': 'FAQ',
|
||||
'First name': '名',
|
||||
'Forgot username?': '忘记用户名?',
|
||||
'Forms and Validators': 'Forms and Validators',
|
||||
'Free Applications': 'Free Applications',
|
||||
'Functions with no doctests will result in [passed] tests.': '沒有 doctests 的函数会显示 [passed].',
|
||||
'Group ID': '群组编号',
|
||||
'Groups': 'Groups',
|
||||
'Hello World': 'Hello World',
|
||||
'Home': 'Home',
|
||||
'How did you get here?': 'How did you get here?',
|
||||
'import': 'import',
|
||||
'Import/Export': '导入/导出',
|
||||
'Index': '索引',
|
||||
'insert new': '插入新纪录',
|
||||
'insert new %s': '插入新纪录 %s',
|
||||
'Installed applications': '已安裝应用程序',
|
||||
'Internal State': '內部状态',
|
||||
'Introduction': 'Introduction',
|
||||
'Invalid action': '非法操作(action)',
|
||||
'Invalid email': '不符合电子邮件格式',
|
||||
'Invalid Query': '无效的查询请求',
|
||||
'invalid request': '网络要求无效',
|
||||
'Is Active': 'Is Active',
|
||||
'Key': 'Key',
|
||||
'Language files (static strings) updated': '语言文件已更新',
|
||||
'Languages': '各国语言',
|
||||
'Last name': '姓',
|
||||
'Last saved on:': '最后保存时间:',
|
||||
'Layout': '网页布局',
|
||||
'Layout Plugins': 'Layout Plugins',
|
||||
'Layouts': 'Layouts',
|
||||
'License for': '软件授权',
|
||||
'Live Chat': 'Live Chat',
|
||||
'login': '登录',
|
||||
'Login': '登录',
|
||||
'Login to the Administrative Interface': '登录到管理员界面',
|
||||
'logout': '登出',
|
||||
'Logout': '登出',
|
||||
'Lost Password': '忘记密码',
|
||||
'Lost password?': '忘记密码?',
|
||||
'Main Menu': '主菜单',
|
||||
'Manage Cache': 'Manage Cache',
|
||||
'Menu Model': '菜单模型(menu)',
|
||||
'Models': '数据模型',
|
||||
'Modified By': '修改者',
|
||||
'Modified On': '修改时间',
|
||||
'Modules': '程序模块',
|
||||
'My Sites': 'My Sites',
|
||||
'Name': '名字',
|
||||
'New Record': '新记录',
|
||||
'new record inserted': '已插入新记录',
|
||||
'next 100 rows': '往后 100 笔',
|
||||
'NO': '否',
|
||||
'No databases in this application': '该应用程序不含数据库',
|
||||
'Object or table name': 'Object or table name',
|
||||
'Online examples': '点击进入在线例子',
|
||||
'or import from csv file': '或导入CSV文件',
|
||||
'Origin': '原文',
|
||||
'Original/Translation': '原文/翻译',
|
||||
'Other Plugins': 'Other Plugins',
|
||||
'Other Recipes': 'Other Recipes',
|
||||
'Overview': '概览',
|
||||
'Password': '密码',
|
||||
"Password fields don't match": '密码不匹配',
|
||||
'Peeking at file': '选择文件',
|
||||
'Plugins': 'Plugins',
|
||||
'Powered by': '基于下列技术构建:',
|
||||
'Preface': 'Preface',
|
||||
'previous 100 rows': '往前 100 笔',
|
||||
'Python': 'Python',
|
||||
'Query:': '查询:',
|
||||
'Quick Examples': 'Quick Examples',
|
||||
'RAM': 'RAM',
|
||||
'RAM Cache Keys': 'RAM Cache Keys',
|
||||
'Ram Cleared': 'Ram Cleared',
|
||||
'Recipes': 'Recipes',
|
||||
'Record': '记录',
|
||||
'record does not exist': '记录不存在',
|
||||
'Record ID': '记录编号',
|
||||
'Record id': '记录编号',
|
||||
'Register': '注册',
|
||||
'register': '注册',
|
||||
'Registration identifier': 'Registration identifier',
|
||||
'Registration key': '注册密钥',
|
||||
'reload': 'reload',
|
||||
'Remember me (for 30 days)': '记住我(30 天)',
|
||||
'Reset Password key': '重置密码',
|
||||
'Resolve Conflict file': '解决冲突文件',
|
||||
'Role': '角色',
|
||||
'Rows in Table': '在数据表里的记录',
|
||||
'Rows selected': '笔记录被选择',
|
||||
'Saved file hash:': '已保存文件的哈希值:',
|
||||
'Semantic': 'Semantic',
|
||||
'Services': 'Services',
|
||||
'Size of cache:': 'Size of cache:',
|
||||
'state': '状态',
|
||||
'Static files': '静态文件',
|
||||
'Statistics': '统计数据',
|
||||
'Stylesheet': '网页样式表',
|
||||
'submit': '提交',
|
||||
'Submit': '提交',
|
||||
'Support': 'Support',
|
||||
'Sure you want to delete this object?': '确定要删除此对象?',
|
||||
'Table': '数据表',
|
||||
'Table name': '数据表名称',
|
||||
'Testing application': '测试中的应用程序',
|
||||
'The "query" is a condition like "db.table1.field1==\'value\'". Something like "db.table1.field1==db.table2.field2" results in a SQL JOIN.': '"query"应是类似 "db.table1.field1==\'value\'" 的条件表达式. "db.table1.field1==db.table2.field2"的形式则代表执行 JOIN SQL.',
|
||||
'The Core': 'The Core',
|
||||
'The output of the file is a dictionary that was rendered by the view %s': 'The output of the file is a dictionary that was rendered by the view %s',
|
||||
'The Views': '视图',
|
||||
'There are no controllers': '沒有控件(controllers)',
|
||||
'There are no models': '沒有数据库模型(models)',
|
||||
'There are no modules': '沒有程序模块(modules)',
|
||||
'There are no static files': '沒有静态文件',
|
||||
'There are no translators, only default language is supported': '沒有对应的语言文件,仅支持原始语言',
|
||||
'There are no views': '沒有视图',
|
||||
'This App': '该应用',
|
||||
'This is the %(filename)s template': '这是%(filename)s文件的模板(template)',
|
||||
'Ticket': '问题清单',
|
||||
'Time in Cache (h:m:s)': 'Time in Cache (h:m:s)',
|
||||
'Timestamp': '时间戳',
|
||||
'Twitter': 'Twitter',
|
||||
'Unable to check for upgrades': '查询新版本失败',
|
||||
'Unable to download': '无法下载',
|
||||
'Unable to download app': '无法下载应用程序',
|
||||
'unable to parse csv file': '无法解析CSV文件',
|
||||
'Update:': '更新:',
|
||||
'Upload existing application': '上传已有应用程序',
|
||||
'Use (...)&(...) for AND, (...)|(...) for OR, and ~(...) for NOT to build more complex queries.': '使用下列方式可得到更复杂的条件表达式, (...)&(...) 代表必须都满足, (...)|(...) 代表其一, ~(...)则代表否.',
|
||||
'User %(id)s Logged-in': '用户 %(id)s 已登录',
|
||||
'User %(id)s Registered': '用户 %(id)s 已注册',
|
||||
'User ID': '用户编号',
|
||||
'Verify Password': '验证密码',
|
||||
'Videos': '视频',
|
||||
'View': '查看',
|
||||
'Views': '视图',
|
||||
'Welcome': '欢迎',
|
||||
'Welcome %s': '欢迎 %s',
|
||||
'Welcome to web2py': '欢迎使用 web2py',
|
||||
'Welcome to web2py!': '欢迎使用 web2py!',
|
||||
'Which called the function %s located in the file %s': 'Which called the function %s located in the file %s',
|
||||
'YES': '是',
|
||||
'You are successfully running web2py': '您已成功运行 web2py',
|
||||
'You can modify this application and adapt it to your needs': '请根据您的需要修改本程序',
|
||||
'You visited the url %s': 'You visited the url %s',
|
||||
}
|
||||
@@ -0,0 +1,244 @@
|
||||
# coding: utf8
|
||||
{
|
||||
'!langcode!': 'zh-cn',
|
||||
'!langname!': '中文',
|
||||
'"update" is an optional expression like "field1=\'newvalue\'". You cannot update or delete the results of a JOIN': '"更新" 是選擇性的條件式, 格式就像 "欄位1=\'值\'". 但是 JOIN 的資料不可以使用 update 或是 delete"',
|
||||
'%s %%{row} deleted': '已刪除 %s 筆',
|
||||
'%s %%{row} updated': '已更新 %s 筆',
|
||||
'%s selected': '%s 已選擇',
|
||||
'%Y-%m-%d': '%Y-%m-%d',
|
||||
'%Y-%m-%d %H:%M:%S': '%Y-%m-%d %H:%M:%S',
|
||||
'(something like "it-it")': '(格式類似 "zh-tw")',
|
||||
'A new version of web2py is available': '新版的 web2py 已發行',
|
||||
'A new version of web2py is available: %s': '新版的 web2py 已發行: %s',
|
||||
'about': '關於',
|
||||
'About': '關於',
|
||||
'About application': '關於本應用程式',
|
||||
'Access Control': 'Access Control',
|
||||
'Admin is disabled because insecure channel': '管理功能(Admin)在不安全連線環境下自動關閉',
|
||||
'Admin is disabled because unsecure channel': '管理功能(Admin)在不安全連線環境下自動關閉',
|
||||
'Administrative Interface': 'Administrative Interface',
|
||||
'Administrative interface': '點此處進入管理介面',
|
||||
'Administrator Password:': '管理員密碼:',
|
||||
'Ajax Recipes': 'Ajax Recipes',
|
||||
'An error occured, please %s the page': 'An error occured, please %s the page',
|
||||
'appadmin is disabled because insecure channel': '因為來自非安全通道,管理介面關閉',
|
||||
'Are you sure you want to delete file "%s"?': '確定要刪除檔案"%s"?',
|
||||
'Are you sure you want to delete this object?': 'Are you sure you want to delete this object?',
|
||||
'Are you sure you want to uninstall application "%s"': '確定要移除應用程式 "%s"',
|
||||
'Are you sure you want to uninstall application "%s"?': '確定要移除應用程式 "%s"',
|
||||
'ATTENTION: Login requires a secure (HTTPS) connection or running on localhost.': '注意: 登入管理帳號需要安全連線(HTTPS)或是在本機連線(localhost).',
|
||||
'ATTENTION: TESTING IS NOT THREAD SAFE SO DO NOT PERFORM MULTIPLE TESTS CONCURRENTLY.': '注意: 因為在測試模式不保證多執行緒安全性,也就是說不可以同時執行多個測試案例',
|
||||
'ATTENTION: you cannot edit the running application!': '注意:不可編輯正在執行的應用程式!',
|
||||
'Authentication': '驗證',
|
||||
'Available Databases and Tables': '可提供的資料庫和資料表',
|
||||
'Buy this book': 'Buy this book',
|
||||
'cache': '快取記憶體',
|
||||
'Cache': 'Cache',
|
||||
'Cache Keys': 'Cache Keys',
|
||||
'Cannot be empty': '不可空白',
|
||||
'Cannot compile: there are errors in your app. Debug it, correct errors and try again.': '無法編譯:應用程式中含有錯誤,請除錯後再試一次.',
|
||||
'Change Password': '變更密碼',
|
||||
'change password': '變更密碼',
|
||||
'Check to delete': '打勾代表刪除',
|
||||
'Check to delete:': '點選以示刪除:',
|
||||
'Clear CACHE?': 'Clear CACHE?',
|
||||
'Clear DISK': 'Clear DISK',
|
||||
'Clear RAM': 'Clear RAM',
|
||||
'Client IP': '客戶端網址(IP)',
|
||||
'Community': 'Community',
|
||||
'Components and Plugins': 'Components and Plugins',
|
||||
'Controller': '控件',
|
||||
'Controllers': '控件',
|
||||
'Copyright': '版權所有',
|
||||
'Create new application': '創建應用程式',
|
||||
'Created By': 'Created By',
|
||||
'Created On': 'Created On',
|
||||
'Current request': '目前網路資料要求(request)',
|
||||
'Current response': '目前網路資料回應(response)',
|
||||
'Current session': '目前網路連線資訊(session)',
|
||||
'customize me!': '請調整我!',
|
||||
'data uploaded': '資料已上傳',
|
||||
'Database': '資料庫',
|
||||
'Database %s select': '已選擇 %s 資料庫',
|
||||
'Date and Time': '日期和時間',
|
||||
'db': 'db',
|
||||
'DB Model': '資料庫模組',
|
||||
'Delete': '刪除',
|
||||
'Delete:': '刪除:',
|
||||
'Demo': 'Demo',
|
||||
'Deploy on Google App Engine': '配置到 Google App Engine',
|
||||
'Deployment Recipes': 'Deployment Recipes',
|
||||
'Description': '描述',
|
||||
'DESIGN': '設計',
|
||||
'design': '設計',
|
||||
'Design for': '設計為了',
|
||||
'DISK': 'DISK',
|
||||
'Disk Cache Keys': 'Disk Cache Keys',
|
||||
'Disk Cleared': 'Disk Cleared',
|
||||
'Documentation': 'Documentation',
|
||||
"Don't know what to do?": "Don't know what to do?",
|
||||
'done!': '完成!',
|
||||
'Download': 'Download',
|
||||
'E-mail': '電子郵件',
|
||||
'EDIT': '編輯',
|
||||
'Edit': '編輯',
|
||||
'Edit application': '編輯應用程式',
|
||||
'Edit current record': '編輯當前紀錄',
|
||||
'edit profile': '編輯設定檔',
|
||||
'Edit Profile': '編輯設定檔',
|
||||
'Edit This App': '編輯本應用程式',
|
||||
'Editing file': '編輯檔案',
|
||||
'Editing file "%s"': '編輯檔案"%s"',
|
||||
'Email and SMS': 'Email and SMS',
|
||||
'enter an integer between %(min)g and %(max)g': 'enter an integer between %(min)g and %(max)g',
|
||||
'Error logs for "%(app)s"': '"%(app)s"的錯誤紀錄',
|
||||
'Errors': 'Errors',
|
||||
'export as csv file': '以逗號分隔檔(csv)格式匯出',
|
||||
'FAQ': 'FAQ',
|
||||
'First name': '名',
|
||||
'Forgot username?': 'Forgot username?',
|
||||
'Forms and Validators': 'Forms and Validators',
|
||||
'Free Applications': 'Free Applications',
|
||||
'Functions with no doctests will result in [passed] tests.': '沒有 doctests 的函式會顯示 [passed].',
|
||||
'Group ID': '群組編號',
|
||||
'Groups': 'Groups',
|
||||
'Hello World': '嗨! 世界',
|
||||
'Home': 'Home',
|
||||
'How did you get here?': 'How did you get here?',
|
||||
'import': 'import',
|
||||
'Import/Export': '匯入/匯出',
|
||||
'Index': '索引',
|
||||
'insert new': '插入新資料',
|
||||
'insert new %s': '插入新資料 %s',
|
||||
'Installed applications': '已安裝應用程式',
|
||||
'Internal State': '內部狀態',
|
||||
'Introduction': 'Introduction',
|
||||
'Invalid action': '不合法的動作(action)',
|
||||
'Invalid email': '不合法的電子郵件',
|
||||
'Invalid Query': '不合法的查詢',
|
||||
'invalid request': '不合法的網路要求(request)',
|
||||
'Is Active': 'Is Active',
|
||||
'Key': 'Key',
|
||||
'Language files (static strings) updated': '語言檔已更新',
|
||||
'Languages': '各國語言',
|
||||
'Last name': '姓',
|
||||
'Last saved on:': '最後儲存時間:',
|
||||
'Layout': '網頁配置',
|
||||
'Layout Plugins': 'Layout Plugins',
|
||||
'Layouts': 'Layouts',
|
||||
'License for': '軟體版權為',
|
||||
'Live Chat': 'Live Chat',
|
||||
'login': '登入',
|
||||
'Login': '登入',
|
||||
'Login to the Administrative Interface': '登入到管理員介面',
|
||||
'logout': '登出',
|
||||
'Logout': '登出',
|
||||
'Lost Password': '密碼遺忘',
|
||||
'Lost password?': 'Lost password?',
|
||||
'Main Menu': '主選單',
|
||||
'Manage Cache': 'Manage Cache',
|
||||
'Menu Model': '選單模組(menu)',
|
||||
'Models': '資料模組',
|
||||
'Modified By': 'Modified By',
|
||||
'Modified On': 'Modified On',
|
||||
'Modules': '程式模組',
|
||||
'My Sites': 'My Sites',
|
||||
'Name': '名字',
|
||||
'New Record': '新紀錄',
|
||||
'new record inserted': '已插入新紀錄',
|
||||
'next 100 rows': '往後 100 筆',
|
||||
'NO': '否',
|
||||
'No databases in this application': '這應用程式不含資料庫',
|
||||
'Object or table name': 'Object or table name',
|
||||
'Online examples': '點此處進入線上範例',
|
||||
'or import from csv file': '或是從逗號分隔檔(CSV)匯入',
|
||||
'Origin': '原文',
|
||||
'Original/Translation': '原文/翻譯',
|
||||
'Other Plugins': 'Other Plugins',
|
||||
'Other Recipes': 'Other Recipes',
|
||||
'Overview': 'Overview',
|
||||
'Password': '密碼',
|
||||
"Password fields don't match": '密碼欄不匹配',
|
||||
'Peeking at file': '選擇檔案',
|
||||
'Plugins': 'Plugins',
|
||||
'Powered by': '基於以下技術構建:',
|
||||
'Preface': 'Preface',
|
||||
'previous 100 rows': '往前 100 筆',
|
||||
'Python': 'Python',
|
||||
'Query:': '查詢:',
|
||||
'Quick Examples': 'Quick Examples',
|
||||
'RAM': 'RAM',
|
||||
'RAM Cache Keys': 'RAM Cache Keys',
|
||||
'Ram Cleared': 'Ram Cleared',
|
||||
'Recipes': 'Recipes',
|
||||
'Record': '紀錄',
|
||||
'record does not exist': '紀錄不存在',
|
||||
'Record ID': '紀錄編號',
|
||||
'Record id': '紀錄編號',
|
||||
'Register': '註冊',
|
||||
'register': '註冊',
|
||||
'Registration identifier': 'Registration identifier',
|
||||
'Registration key': '註冊金鑰',
|
||||
'reload': 'reload',
|
||||
'Remember me (for 30 days)': '記住我(30 天)',
|
||||
'Reset Password key': '重設密碼',
|
||||
'Resolve Conflict file': '解決衝突檔案',
|
||||
'Role': '角色',
|
||||
'Rows in Table': '在資料表裏的資料',
|
||||
'Rows selected': '筆資料被選擇',
|
||||
'Saved file hash:': '檔案雜湊值已紀錄:',
|
||||
'Semantic': 'Semantic',
|
||||
'Services': 'Services',
|
||||
'Size of cache:': 'Size of cache:',
|
||||
'state': '狀態',
|
||||
'Static files': '靜態檔案',
|
||||
'Statistics': 'Statistics',
|
||||
'Stylesheet': '網頁風格檔',
|
||||
'submit': 'submit',
|
||||
'Submit': '傳送',
|
||||
'Support': 'Support',
|
||||
'Sure you want to delete this object?': '確定要刪除此物件?',
|
||||
'Table': '資料表',
|
||||
'Table name': '資料表名稱',
|
||||
'Testing application': '測試中的應用程式',
|
||||
'The "query" is a condition like "db.table1.field1==\'value\'". Something like "db.table1.field1==db.table2.field2" results in a SQL JOIN.': '"查詢"是一個像 "db.表1.欄位1==\'值\'" 的條件式. 以"db.表1.欄位1==db.表2.欄位2"方式則相當於執行 JOIN SQL.',
|
||||
'The Core': 'The Core',
|
||||
'The output of the file is a dictionary that was rendered by the view %s': 'The output of the file is a dictionary that was rendered by the view %s',
|
||||
'The Views': 'The Views',
|
||||
'There are no controllers': '沒有控件(controllers)',
|
||||
'There are no models': '沒有資料庫模組(models)',
|
||||
'There are no modules': '沒有程式模組(modules)',
|
||||
'There are no static files': '沒有靜態檔案',
|
||||
'There are no translators, only default language is supported': '沒有翻譯檔,只支援原始語言',
|
||||
'There are no views': '沒有視圖',
|
||||
'This App': 'This App',
|
||||
'This is the %(filename)s template': '這是%(filename)s檔案的樣板(template)',
|
||||
'Ticket': '問題單',
|
||||
'Time in Cache (h:m:s)': 'Time in Cache (h:m:s)',
|
||||
'Timestamp': '時間標記',
|
||||
'Twitter': 'Twitter',
|
||||
'Unable to check for upgrades': '無法做升級檢查',
|
||||
'Unable to download': '無法下載',
|
||||
'Unable to download app': '無法下載應用程式',
|
||||
'unable to parse csv file': '無法解析逗號分隔檔(csv)',
|
||||
'Update:': '更新:',
|
||||
'Upload existing application': '更新存在的應用程式',
|
||||
'Use (...)&(...) for AND, (...)|(...) for OR, and ~(...) for NOT to build more complex queries.': '使用下列方式來組合更複雜的條件式, (...)&(...) 代表同時存在的條件, (...)|(...) 代表擇一的條件, ~(...)則代表反向條件.',
|
||||
'User %(id)s Logged-in': '使用者 %(id)s 已登入',
|
||||
'User %(id)s Registered': '使用者 %(id)s 已註冊',
|
||||
'User ID': '使用者編號',
|
||||
'Verify Password': '驗證密碼',
|
||||
'Videos': 'Videos',
|
||||
'View': '視圖',
|
||||
'Views': '視圖',
|
||||
'Welcome': 'Welcome',
|
||||
'Welcome %s': '歡迎 %s',
|
||||
'Welcome to web2py': '歡迎使用 web2py',
|
||||
'Welcome to web2py!': 'Welcome to web2py!',
|
||||
'Which called the function %s located in the file %s': 'Which called the function %s located in the file %s',
|
||||
'YES': '是',
|
||||
'You are successfully running web2py': 'You are successfully running web2py',
|
||||
'You can modify this application and adapt it to your needs': 'You can modify this application and adapt it to your needs',
|
||||
'You visited the url %s': 'You visited the url %s',
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
# coding: utf8
|
||||
{
|
||||
'!langcode!': 'zh-cn',
|
||||
'!langcode!': 'zh-tw',
|
||||
'!langname!': '中文',
|
||||
'"update" is an optional expression like "field1=\'newvalue\'". You cannot update or delete the results of a JOIN': '"更新" 是選擇性的條件式, 格式就像 "欄位1=\'值\'". 但是 JOIN 的資料不可以使用 update 或是 delete"',
|
||||
'%s %%{row} deleted': '已刪除 %s 筆',
|
||||
|
||||
@@ -7,8 +7,7 @@
|
||||
|
||||
response.logo = A(B('web',SPAN(2),'py'),XML('™ '),
|
||||
_class="brand",_href="http://www.web2py.com/")
|
||||
response.title = ' '.join(
|
||||
word.capitalize() for word in request.application.split('_'))
|
||||
response.title = request.application.replace('_',' ').title()
|
||||
response.subtitle = T('customize me!')
|
||||
|
||||
## read more at http://dev.w3.org/html5/markup/meta.name.html
|
||||
@@ -137,3 +136,5 @@ def _():
|
||||
]
|
||||
)]
|
||||
if DEVELOPMENT_MENU: _()
|
||||
|
||||
if "auth" in locals(): auth.wikimenu()
|
||||
|
||||
@@ -92,7 +92,7 @@ div.flash {
|
||||
position:fixed;
|
||||
padding:10px;
|
||||
top:48px;
|
||||
right:50px;
|
||||
right:250px;
|
||||
min-width:280px;
|
||||
opacity:0.95;
|
||||
margin:0px 0px 10px 10px;
|
||||
@@ -191,6 +191,7 @@ div.error {
|
||||
.web2py_grid {width:100%}
|
||||
.web2py_grid table {width:100%}
|
||||
.web2py_grid tbody td {padding:2px 5px 2px 5px; vertical-align: middle;}
|
||||
.web2py_grid .web2py_form td {vertical-align: top;}
|
||||
|
||||
.web2py_grid thead th,.web2py_grid tfoot td {
|
||||
background-color:#EAEAEA;
|
||||
|
||||
@@ -102,6 +102,7 @@ td.w2p_fl,td.w2p_fc {padding:0;}
|
||||
==============================================================*/
|
||||
|
||||
/* because web2py handles this via js */
|
||||
textarea { width:90%}
|
||||
.hidden{visibility:visible;}
|
||||
/* right folder for bootstrap black images/icons */
|
||||
[class^="icon-"],[class*=" icon-"]{
|
||||
|
||||
File diff suppressed because one or more lines are too long
+6
-2
File diff suppressed because one or more lines are too long
@@ -35,6 +35,7 @@ function web2py_ajax_init(target) {
|
||||
jQuery('.hidden', target).hide();
|
||||
jQuery('.error', target).hide().slideDown('slow');
|
||||
web2py_ajax_fields(target);
|
||||
web2py_show_if(target);
|
||||
};
|
||||
|
||||
function web2py_event_handlers() {
|
||||
@@ -216,3 +217,26 @@ function web2py_validate_entropy(myfield, req_entropy) {
|
||||
if(!myfield.hasClass('entropy_check')) myfield.on('keyup', validator).on('keydown', validator).addClass('entropy_check');
|
||||
}
|
||||
|
||||
function web2py_show_if(target) {
|
||||
var triggers = {};
|
||||
var show_if = function () {
|
||||
var t = jQuery(this);
|
||||
var id = t.attr('id');
|
||||
t.attr('value', t.val());
|
||||
for(var k = 0; k < triggers[id].length; k++) {
|
||||
var dep = jQuery('#' + triggers[id][k], target);
|
||||
var tr = jQuery('#' + triggers[id][k] + '__row', target);
|
||||
if(t.is(dep.attr('data-show-if'))) tr.slideDown();
|
||||
else tr.hide();
|
||||
}
|
||||
};
|
||||
jQuery('[data-show-trigger]', target).each(function () {
|
||||
var name = jQuery(this).attr('data-show-trigger');
|
||||
if(!triggers[name]) triggers[name] = [];
|
||||
triggers[name].push(jQuery(this).attr('id'));
|
||||
});
|
||||
for(var name in triggers) {
|
||||
jQuery('#' + name, target).change(show_if).keyup(show_if);
|
||||
show_if.call(jQuery('#' + name, target));
|
||||
};
|
||||
}
|
||||
@@ -8,21 +8,28 @@ jQuery(function(){
|
||||
if(jQuery(this).find('ul').length)
|
||||
jQuery(this).addClass('dropdown-submenu');
|
||||
});
|
||||
function adjust_height_of_collapsed_nav() {
|
||||
var cn = jQuery('div.collapse');
|
||||
if (cn.get(0)) {
|
||||
var cnh = cn.get(0).style.height;
|
||||
if (cnh>'0px'){
|
||||
cn.css('height','auto');
|
||||
}
|
||||
}
|
||||
}
|
||||
function hoverMenu(){
|
||||
var wid = document.documentElement.clientWidth; //faster than $(window).width() and cross browser
|
||||
if (wid>=980){
|
||||
jQuery('ul.nav a.dropdown-toggle').parent().hover(function(){
|
||||
mi = jQuery(this).addClass('open');
|
||||
mi.children('.dropdown-menu').stop(true, true).delay(200).fadeIn(400);
|
||||
}, function(){
|
||||
mi = jQuery(this);
|
||||
mi.children('.dropdown-menu').stop(true, true).delay(200).fadeOut(function(){mi.removeClass('open')});
|
||||
});
|
||||
};
|
||||
jQuery('ul.nav a.dropdown-toggle').parent().hover(function(){
|
||||
adjust_height_of_collapsed_nav();
|
||||
mi = jQuery(this).addClass('open');
|
||||
mi.children('.dropdown-menu').stop(true, true).delay(200).fadeIn(400);
|
||||
}, function(){
|
||||
mi = jQuery(this);
|
||||
mi.children('.dropdown-menu').stop(true, true).delay(200).fadeOut(function(){mi.removeClass('open')});
|
||||
});
|
||||
}
|
||||
hoverMenu(); // first page load
|
||||
jQuery(window).resize(hoverMenu); // on resize event
|
||||
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');
|
||||
});
|
||||
});
|
||||
@@ -247,3 +247,39 @@
|
||||
{{=IMG(_src=URL('appadmin', 'bg_graph_model'))}}
|
||||
{{pass}}
|
||||
{{pass}}
|
||||
|
||||
{{if request.function == 'auth_manage':}}
|
||||
<h2>{{=T('Manage Access Control')}}</h2>
|
||||
<ul class="nav nav-tabs">
|
||||
<li class="active"><a href="#users" data-toggle="tab">Users</a></li>
|
||||
<li><a href="#roles" data-toggle="tab">Roles</a></li>
|
||||
<li><a href="#permissions" data-toggle="tab">Permissions</a></li>
|
||||
</ul>
|
||||
|
||||
<div class="tab-content">
|
||||
<div class="tab-pane active" id="users">
|
||||
{{=LOAD(f='auth_manage.load', args=auth.settings.table_user_name,ajax=True)}}
|
||||
</div>
|
||||
<div class="tab-pane" id="roles">
|
||||
{{=LOAD(f='auth_manage.load', args=auth.settings.table_group_name,ajax=True)}}
|
||||
</div>
|
||||
<div class="tab-pane" id="permissions">
|
||||
{{=LOAD(f='auth_manage.load', args=auth.settings.table_permission_name,ajax=True)}}
|
||||
</div>
|
||||
</div>
|
||||
{{elif request.function == 'manage':}}
|
||||
<h2>{{=T('Manage Access Control')}}</h2>
|
||||
<ul class="nav nav-tabs">
|
||||
{{for k,tablename in enumerate(auth.db.tables):}}
|
||||
<li><a href="#table-{{=tablename}}" data-toggle="tab">{{=tablename}}</a></li>
|
||||
{{pass}}
|
||||
</ul>
|
||||
|
||||
<div class="tab-content">
|
||||
{{for tablename in auth.db.tables:}}
|
||||
<div class="tab-pane" id="table-{{=tablename}}">
|
||||
{{=LOAD(f='manage.load', args=tablename,ajax=True)}}
|
||||
</div>
|
||||
{{pass}}
|
||||
</div>
|
||||
{{pass}}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
{{extend 'layout.html'}}
|
||||
|
||||
<h2>{{=T( request.args(0).replace('_',' ').capitalize() )}}</h2>
|
||||
<div id="web2py_user_form">
|
||||
{{
|
||||
@@ -21,3 +22,4 @@ jQuery("#web2py_user_form input:visible:enabled:first").focus();
|
||||
web2py_validate_entropy(jQuery('#no_table_new_password'),100);
|
||||
{{pass}}
|
||||
//--></script>
|
||||
|
||||
|
||||
@@ -92,14 +92,16 @@
|
||||
<div class="container">
|
||||
<!-- Masthead ================================================== -->
|
||||
<header class="mastheader row" id="header">
|
||||
{{if response.title:}}
|
||||
<div class="span12">
|
||||
<div class="page-header">
|
||||
<h1>
|
||||
{{=response.title or request.application}}
|
||||
{{=response.title}}
|
||||
<small>{{=response.subtitle or ''}}</small>
|
||||
</h1>
|
||||
</div>
|
||||
</div>
|
||||
{{pass}}
|
||||
</header>
|
||||
|
||||
<section id="main" class="main row">
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
var w2p_ajax_confirm_message = "{{=T('Are you sure you want to delete this object?')}}";
|
||||
var w2p_ajax_date_format = "{{=T('%Y-%m-%d')}}";
|
||||
var w2p_ajax_datetime_format = "{{=T('%Y-%m-%d %H:%M:%S')}}";
|
||||
var ajax_error_500 = '{{=XML(T('An error occured, please %s the page') % A(T('reload'), _href=URL(args=request.args, vars=request.vars))) }}'
|
||||
var ajax_error_500 = '{{=XML(T('An error occured, please %s the page') % A(T('reload'), _href=URL(args=request.args, vars=request.get_vars))) }}'
|
||||
//--></script>
|
||||
{{
|
||||
response.files.insert(0,URL('static','js/jquery.js'))
|
||||
|
||||
+4
-4
@@ -43,7 +43,7 @@ def apath(path='', r=None):
|
||||
return os.path.join(opath, path).replace('\\', '/')
|
||||
|
||||
|
||||
def app_pack(app, request, raise_ex=False):
|
||||
def app_pack(app, request, raise_ex=False, filenames=None):
|
||||
"""
|
||||
Builds a w2p package for the application
|
||||
|
||||
@@ -60,9 +60,9 @@ def app_pack(app, request, raise_ex=False):
|
||||
filename of the w2p file or None on error
|
||||
"""
|
||||
try:
|
||||
app_cleanup(app, request)
|
||||
if filenames is None: app_cleanup(app, request)
|
||||
filename = apath('../deposit/web2py.app.%s.w2p' % app, request)
|
||||
w2p_pack(filename, apath(app, request))
|
||||
w2p_pack(filename, apath(app, request), filenames=filenames)
|
||||
return filename
|
||||
except Exception, e:
|
||||
if raise_ex:
|
||||
@@ -373,7 +373,7 @@ def check_new_version(myversion, version_URL):
|
||||
the most up-to-version available
|
||||
"""
|
||||
try:
|
||||
from urllib import urlopen
|
||||
from urllib import urlopen
|
||||
version = urlopen(version_URL).read()
|
||||
pversion = parse_version(version)
|
||||
pmyversion = parse_version(myversion)
|
||||
|
||||
+83
-51
@@ -437,7 +437,7 @@ class Cache(object):
|
||||
# been accounted for
|
||||
logger.warning('no cache.disk (AttributeError)')
|
||||
|
||||
def client(self, time_expire=DEFAULT_TIME_EXPIRE, cache_model=None,
|
||||
def action(self, time_expire=DEFAULT_TIME_EXPIRE, cache_model=None,
|
||||
prefix=None, session=False, vars=True, lang=True,
|
||||
user_agent=False, public=True, valid_statuses=None,
|
||||
quick=None):
|
||||
@@ -457,64 +457,96 @@ class Cache(object):
|
||||
public: if False forces the Cache-Control to be 'private'
|
||||
valid_statuses: by default only status codes starting with 1,2,3 will be cached.
|
||||
pass an explicit list of statuses on which turn the cache on
|
||||
quick: Session,Vars,Lang,User-agent,Public,duration:
|
||||
quick: Session,Vars,Lang,User-agent,Public:
|
||||
fast overrides with initial strings, e.g. 'SVLP' or 'VLP', or 'VLP'
|
||||
"""
|
||||
from gluon import current
|
||||
from gluon.http import HTTP
|
||||
def wrap(func):
|
||||
def wrapped_f():
|
||||
if current.request.env.request_method == 'GET':
|
||||
if time_expire:
|
||||
cache_control = 'max-age=%(time_expire)s, s-maxage=%(time_expire)s' % dict(time_expire=time_expire)
|
||||
if quick:
|
||||
session_ = True if 'S' in quick else False
|
||||
vars_ = True if 'V' in quick else False
|
||||
lang_ = True if 'L' in quick else False
|
||||
user_agent_ = True if 'U' in quick else False
|
||||
public_ = True if 'P' in quick else False
|
||||
else:
|
||||
session_, vars_, lang_, user_agent_, public_ = session, vars, lang, user_agent, public
|
||||
if not session_ and public_:
|
||||
cache_control += ', public'
|
||||
expires = (current.request.utcnow + datetime.timedelta(seconds=time_expire)).strftime('%a, %d %b %Y %H:%M:%S GMT')
|
||||
vary = None
|
||||
else:
|
||||
cache_control += ', private'
|
||||
expires = 'Fri, 01 Jan 1990 00:00:00 GMT'
|
||||
if cache_model:
|
||||
cache_key = [current.request.env.path_info, current.response.view]
|
||||
if session_:
|
||||
cache_key.append(current.response.session_id)
|
||||
elif user_agent_:
|
||||
if user_agent_ is True:
|
||||
cache_key.append("%(is_mobile)s_%(is_tablet)s" % current.request.user_agent())
|
||||
else:
|
||||
cache_key.append(str(user_agent_.items()))
|
||||
if vars_:
|
||||
cache_key.append(current.request.env.query_string)
|
||||
if lang_:
|
||||
cache_key.append(current.T.accepted_language)
|
||||
cache_key = hashlib.md5('__'.join(cache_key)).hexdigest()
|
||||
if prefix:
|
||||
cache_key = prefix + cache_key
|
||||
rtn = cache_model(cache_key, lambda : func(), time_expire=time_expire)
|
||||
if current.request.env.request_method != 'GET':
|
||||
return func()
|
||||
if time_expire:
|
||||
cache_control = 'max-age=%(time_expire)s, s-maxage=%(time_expire)s' % dict(time_expire=time_expire)
|
||||
if quick:
|
||||
session_ = True if 'S' in quick else False
|
||||
vars_ = True if 'V' in quick else False
|
||||
lang_ = True if 'L' in quick else False
|
||||
user_agent_ = True if 'U' in quick else False
|
||||
public_ = True if 'P' in quick else False
|
||||
else:
|
||||
session_, vars_, lang_, user_agent_, public_ = session, vars, lang, user_agent, public
|
||||
if not session_ and public_:
|
||||
cache_control += ', public'
|
||||
expires = (current.request.utcnow + datetime.timedelta(seconds=time_expire)).strftime('%a, %d %b %Y %H:%M:%S GMT')
|
||||
vary = None
|
||||
else:
|
||||
cache_control += ', private'
|
||||
expires = 'Fri, 01 Jan 1990 00:00:00 GMT'
|
||||
if cache_model:
|
||||
#figure out the correct cache key
|
||||
cache_key = [current.request.env.path_info, current.response.view]
|
||||
if session_:
|
||||
cache_key.append(current.response.session_id)
|
||||
elif user_agent_:
|
||||
if user_agent_ is True:
|
||||
cache_key.append("%(is_mobile)s_%(is_tablet)s" % current.request.user_agent())
|
||||
else:
|
||||
cache_key.append(str(user_agent_.items()))
|
||||
if vars_:
|
||||
cache_key.append(current.request.env.query_string)
|
||||
if lang_:
|
||||
cache_key.append(current.T.accepted_language)
|
||||
cache_key = hashlib.md5('__'.join(cache_key)).hexdigest()
|
||||
if prefix:
|
||||
cache_key = prefix + cache_key
|
||||
try:
|
||||
#action returns something
|
||||
rtn = cache_model(cache_key, lambda : func(), time_expire=time_expire)
|
||||
http, status = None, current.response.status
|
||||
except HTTP, e:
|
||||
#action raises HTTP (can still be valid)
|
||||
rtn = cache_model(cache_key, lambda : e.body, time_expire=time_expire)
|
||||
http, status = HTTP(e.status, rtn, **e.headers), e.status
|
||||
else:
|
||||
#action raised a generic exception
|
||||
http = None
|
||||
else:
|
||||
#no server-cache side involved
|
||||
try:
|
||||
#action returns something
|
||||
rtn = func()
|
||||
send_headers = False
|
||||
if isinstance(valid_statuses, list):
|
||||
if current.response.status in valid_statuses:
|
||||
send_headers = True
|
||||
elif valid_statuses is None:
|
||||
if str(current.response.status)[0] in '123':
|
||||
send_headers = True
|
||||
http, status = None, current.response.status
|
||||
except HTTP, e:
|
||||
#action raises HTTP (can still be valid)
|
||||
status = e.status
|
||||
http = HTTP(e.status, e.body, **e.headers)
|
||||
else:
|
||||
#action raised a generic exception
|
||||
http = None
|
||||
send_headers = False
|
||||
if http and isinstance(valid_statuses, list):
|
||||
if status in valid_statuses:
|
||||
send_headers = True
|
||||
elif valid_statuses is None:
|
||||
if str(status)[0] in '123':
|
||||
send_headers = True
|
||||
if send_headers:
|
||||
headers = {
|
||||
'Pragma' : None,
|
||||
'Expires' : expires,
|
||||
'Cache-Control' : cache_control
|
||||
}
|
||||
current.response.headers.update(headers)
|
||||
if cache_model and not send_headers:
|
||||
#we cached already the value, but the status is not valid
|
||||
#so we need to delete the cached value
|
||||
cache_model(cache_key, None)
|
||||
if http:
|
||||
if send_headers:
|
||||
current.response.headers['Pragma'] = None
|
||||
current.response.headers['Expires'] = expires
|
||||
current.response.headers['Cache-Control'] = cache_control
|
||||
if cache_model and not send_headers:
|
||||
cache_model.clear(cache_key)
|
||||
return rtn
|
||||
return func()
|
||||
http.headers.update(current.response.headers)
|
||||
raise http
|
||||
return rtn
|
||||
wrapped_f.__name__ = func.__name__
|
||||
wrapped_f.__doc__ = func.__doc__
|
||||
return wrapped_f
|
||||
|
||||
@@ -9,7 +9,7 @@ License: LGPLv3 (http://www.gnu.org/licenses/lgpl.html)
|
||||
CONTENT_TYPE dictionary created against freedesktop.org' shared mime info
|
||||
database version 1.1.
|
||||
|
||||
Deviations from official standards:
|
||||
Deviations from official standards:
|
||||
- '.md': 'application/x-genesis-rom' --> 'text/x-markdown'
|
||||
- '.png': 'image/x-apple-ios-png' --> 'image/png'
|
||||
Additions:
|
||||
@@ -443,10 +443,10 @@ CONTENT_TYPE = {
|
||||
'.odp': 'application/vnd.oasis.opendocument.presentation',
|
||||
'.ods': 'application/vnd.oasis.opendocument.spreadsheet',
|
||||
'.odt': 'application/vnd.oasis.opendocument.text',
|
||||
'.oga': 'audio/x-speex+ogg',
|
||||
'.ogg': 'video/x-theora+ogg',
|
||||
'.oga': 'audio/ogg',
|
||||
'.ogg': 'application/ogg',
|
||||
'.ogm': 'video/x-ogm+ogg',
|
||||
'.ogv': 'video/x-theora+ogg',
|
||||
'.ogv': 'video/ogg',
|
||||
'.ogx': 'application/ogg',
|
||||
'.old': 'application/x-trash',
|
||||
'.oleo': 'application/x-oleo',
|
||||
@@ -518,7 +518,7 @@ CONTENT_TYPE = {
|
||||
'.pln': 'application/x-planperfect',
|
||||
'.pls': 'audio/x-scpls',
|
||||
'.pm': 'application/x-perl',
|
||||
'.png': 'image/x-apple-ios-png',
|
||||
'.png': 'image/png',
|
||||
'.pnm': 'image/x-portable-anymap',
|
||||
'.pntg': 'image/x-macpaint',
|
||||
'.po': 'text/x-gettext-translation',
|
||||
|
||||
+63
-30
@@ -52,7 +52,7 @@ def set_global(var, val):
|
||||
|
||||
class FPDF(object):
|
||||
"PDF Generation class"
|
||||
|
||||
|
||||
def __init__(self, orientation='P',unit='mm',format='A4'):
|
||||
# Some checks
|
||||
self._dochecks()
|
||||
@@ -356,7 +356,7 @@ class FPDF(object):
|
||||
elif (self.current_font['desc']['MissingWidth']) :
|
||||
w += self.current_font['desc']['MissingWidth']
|
||||
#elif (isset($this->CurrentFont['MissingWidth'])) { $w += $this->CurrentFont['MissingWidth']; }
|
||||
else:
|
||||
else:
|
||||
w += 500
|
||||
else:
|
||||
for i in xrange(0, l):
|
||||
@@ -373,6 +373,21 @@ class FPDF(object):
|
||||
"Draw a line"
|
||||
self._out(sprintf('%.2f %.2f m %.2f %.2f l S',x1*self.k,(self.h-y1)*self.k,x2*self.k,(self.h-y2)*self.k))
|
||||
|
||||
def _set_dash(self, dash_length=False, space_length=False):
|
||||
if(dash_length and space_length):
|
||||
s = sprintf('[%.3f %.3f] 0 d', dash_length*self.k, space_length*self.k)
|
||||
else:
|
||||
s = '[] 0 d'
|
||||
self._out(s)
|
||||
|
||||
def dashed_line(self, x1,y1,x2,y2, dash_length=1, space_length=1):
|
||||
"""Draw a dashed line. Same interface as line() except:
|
||||
- dash_length: Length of the dash
|
||||
- space_length: Length of the space between dashes"""
|
||||
self._set_dash(dash_length, space_length)
|
||||
self.line(x1, y1, x2, y2)
|
||||
self._set_dash()
|
||||
|
||||
def rect(self, x,y,w,h,style=''):
|
||||
"Draw a rectangle"
|
||||
if(style=='F'):
|
||||
@@ -401,10 +416,10 @@ class FPDF(object):
|
||||
global SYSTEM_TTFONTS
|
||||
if os.path.exists(fname):
|
||||
ttffilename = fname
|
||||
elif (FPDF_FONT_DIR and
|
||||
elif (FPDF_FONT_DIR and
|
||||
os.path.exists(os.path.join(FPDF_FONT_DIR, fname))):
|
||||
ttffilename = os.path.join(FPDF_FONT_DIR, fname)
|
||||
elif (SYSTEM_TTFONTS and
|
||||
elif (SYSTEM_TTFONTS and
|
||||
os.path.exists(os.path.join(SYSTEM_TTFONTS, fname))):
|
||||
ttffilename = os.path.join(SYSTEM_TTFONTS, fname)
|
||||
else:
|
||||
@@ -450,7 +465,7 @@ class FPDF(object):
|
||||
fh = open(unifilename, "w")
|
||||
pickle.dump(font_dict, fh)
|
||||
fh.close()
|
||||
except IOError as e:
|
||||
except IOError, e:
|
||||
if not e.errno == errno.EACCES:
|
||||
raise # Not a permission error.
|
||||
del ttf
|
||||
@@ -459,11 +474,11 @@ class FPDF(object):
|
||||
else:
|
||||
sbarr = range(0,32)
|
||||
self.fonts[fontkey] = {
|
||||
'i': len(self.fonts)+1, 'type': font_dict['type'],
|
||||
'name': font_dict['name'], 'desc': font_dict['desc'],
|
||||
'up': font_dict['up'], 'ut': font_dict['ut'],
|
||||
'cw': font_dict['cw'],
|
||||
'ttffile': font_dict['ttffile'], 'fontkey': fontkey,
|
||||
'i': len(self.fonts)+1, 'type': font_dict['type'],
|
||||
'name': font_dict['name'], 'desc': font_dict['desc'],
|
||||
'up': font_dict['up'], 'ut': font_dict['ut'],
|
||||
'cw': font_dict['cw'],
|
||||
'ttffile': font_dict['ttffile'], 'fontkey': fontkey,
|
||||
'subset': sbarr, 'unifilename': unifilename,
|
||||
}
|
||||
self.font_files[fontkey] = {'length1': font_dict['originalsize'],
|
||||
@@ -494,7 +509,7 @@ class FPDF(object):
|
||||
if (type == 'TrueType'):
|
||||
self.font_files[filename]={'length1': originalsize}
|
||||
else:
|
||||
self.font_files[filename]={'length1': size1,
|
||||
self.font_files[filename]={'length1': size1,
|
||||
'length2': size2}
|
||||
|
||||
def set_font(self, family,style='',size=0):
|
||||
@@ -660,7 +675,7 @@ class FPDF(object):
|
||||
dx=self.c_margin
|
||||
if(self.color_flag):
|
||||
s+='q '+self.text_color+' '
|
||||
|
||||
|
||||
# If multibyte, Tw has no effect - do word spacing using an adjustment before each space
|
||||
if (self.ws and self.unifontsubset):
|
||||
for uni in UTF8StringToArray(txt):
|
||||
@@ -686,7 +701,7 @@ class FPDF(object):
|
||||
else:
|
||||
txt2 = self._escape(txt)
|
||||
s += sprintf('BT %.2f %.2f Td (%s) Tj ET',(self.x+dx)*k,(self.h-(self.y+.5*h+.3*self.font_size))*k,txt2)
|
||||
|
||||
|
||||
if(self.underline):
|
||||
s+=' '+self._dounderline(self.x+dx,self.y+.5*h+.3*self.font_size,txt)
|
||||
if(self.color_flag):
|
||||
@@ -764,7 +779,7 @@ class FPDF(object):
|
||||
sep=i
|
||||
ls=l
|
||||
ns+=1
|
||||
if self.unifontsubset:
|
||||
if self.unifontsubset:
|
||||
l += self.get_string_width(c) / self.font_size*1000.0
|
||||
else:
|
||||
l += cw.get(c,0)
|
||||
@@ -848,7 +863,7 @@ class FPDF(object):
|
||||
continue
|
||||
if(c==' '):
|
||||
sep=i
|
||||
if self.unifontsubset:
|
||||
if self.unifontsubset:
|
||||
l += self.get_string_width(c) / self.font_size*1000.0
|
||||
else:
|
||||
l += cw.get(c,0)
|
||||
@@ -900,6 +915,24 @@ class FPDF(object):
|
||||
info=self._parsepng(name)
|
||||
else:
|
||||
#Allow for additional formats
|
||||
#maybe the image is not showing the correct extension,
|
||||
#but the header is OK,
|
||||
succeed_parsing = False
|
||||
#try all the parsing functions
|
||||
parsing_functions = [self._parsejpg,self._parsepng,self._parsegif]
|
||||
for pf in parsing_functions:
|
||||
try:
|
||||
info = pf(name)
|
||||
succeed_parsing = True
|
||||
break;
|
||||
except:
|
||||
pass
|
||||
#last resource
|
||||
if not succeed_parsing:
|
||||
mtd='_parse'+type
|
||||
if not hasattr(self,mtd):
|
||||
self.error('Unsupported image type: '+type)
|
||||
info=getattr(self, mtd)(name)
|
||||
mtd='_parse'+type
|
||||
if not hasattr(self,mtd):
|
||||
self.error('Unsupported image type: '+type)
|
||||
@@ -1202,7 +1235,7 @@ class FPDF(object):
|
||||
self._out('<</Type /Font');
|
||||
self._out('/Subtype /Type0');
|
||||
self._out('/BaseFont /' + fontname + '');
|
||||
self._out('/Encoding /Identity-H');
|
||||
self._out('/Encoding /Identity-H');
|
||||
self._out('/DescendantFonts [' + str(self.n + 1) + ' 0 R]')
|
||||
self._out('/ToUnicode ' + str(self.n + 2) + ' 0 R')
|
||||
self._out('>>')
|
||||
@@ -1264,7 +1297,7 @@ class FPDF(object):
|
||||
for kd in ('Ascent', 'Descent', 'CapHeight', 'Flags', 'FontBBox', 'ItalicAngle', 'StemV', 'MissingWidth'):
|
||||
v = font['desc'][kd]
|
||||
if (kd == 'Flags'):
|
||||
v = v | 4;
|
||||
v = v | 4;
|
||||
v = v & ~32; # SYMBOLIC font flag
|
||||
self._out(' /%s %s' % (kd, v))
|
||||
self._out('/FontFile2 ' + str(self.n + 2) + ' 0 R')
|
||||
@@ -1286,7 +1319,7 @@ class FPDF(object):
|
||||
self._putstream(cidtogidmap)
|
||||
self._out('endobj')
|
||||
|
||||
#Font file
|
||||
#Font file
|
||||
self._newobj()
|
||||
self._out('<</Length ' + str(len(fontstream)))
|
||||
self._out('/Filter /FlateDecode')
|
||||
@@ -1341,14 +1374,14 @@ class FPDF(object):
|
||||
font_dict['range'] = range_
|
||||
pickle.dump(font_dict, fh)
|
||||
fh.close()
|
||||
except IOError as e:
|
||||
except IOError, e:
|
||||
if not e.errno == errno.EACCES:
|
||||
raise # Not a permission error.
|
||||
if (font['cw'][cid] == 0):
|
||||
continue
|
||||
width = font['cw'][cid]
|
||||
if (width == 65535): width = 0
|
||||
if (cid > 255 and (cid not in font['subset']) or not cid): #
|
||||
if (cid > 255 and (cid not in font['subset']) or not cid): #
|
||||
continue
|
||||
if ('dw' not in font or (font['dw'] and width != font['dw'])):
|
||||
if (cid == (prevcid + 1)):
|
||||
@@ -1400,7 +1433,7 @@ class FPDF(object):
|
||||
if (len(set(ws)) == 1):
|
||||
w.append(' %s %s %s' % (k, k + len(ws) - 1, ws[0]))
|
||||
else:
|
||||
w.append(' %s [ %s ]\n' % (k, ' '.join([str(int(h)) for h in ws]))) ##
|
||||
w.append(' %s [ %s ]\n' % (k, ' '.join([str(int(h)) for h in ws]))) ##
|
||||
self._out('/W [%s]' % ''.join(w))
|
||||
|
||||
def _putimages(self):
|
||||
@@ -1412,7 +1445,7 @@ class FPDF(object):
|
||||
del info['data']
|
||||
if 'smask' in info:
|
||||
del info['smask']
|
||||
|
||||
|
||||
def _putimage(self, info):
|
||||
if 'data' in info:
|
||||
self._newobj()
|
||||
@@ -1791,20 +1824,20 @@ class FPDF(object):
|
||||
|
||||
def interleaved2of5(self, txt, x, y, w=1.0, h=10.0):
|
||||
"Barcode I2of5 (numeric), adds a 0 if odd lenght"
|
||||
narrow = w / 3.0
|
||||
narrow = w / 3.0
|
||||
wide = w
|
||||
|
||||
|
||||
# wide/narrow codes for the digits
|
||||
bar_char={'0': 'nnwwn', '1': 'wnnnw', '2': 'nwnnw', '3': 'wwnnn',
|
||||
'4': 'nnwnw', '5': 'wnwnn', '6': 'nwwnn', '7': 'nnnww',
|
||||
'8': 'wnnwn', '9': 'nwnwn', 'A': 'nn', 'Z': 'wn'}
|
||||
|
||||
|
||||
self.set_fill_color(0)
|
||||
code = txt
|
||||
# add leading zero if code-length is odd
|
||||
if len(code) % 2 != 0:
|
||||
code = '0' + code
|
||||
|
||||
|
||||
# add start and stop codes
|
||||
code = 'AA' + code.lower() + 'ZA'
|
||||
|
||||
@@ -1843,7 +1876,7 @@ class FPDF(object):
|
||||
narrow = w / 3.0
|
||||
gap = narrow
|
||||
|
||||
bar_char={'0': 'nnnwwnwnn', '1': 'wnnwnnnnw', '2': 'nnwwnnnnw',
|
||||
bar_char={'0': 'nnnwwnwnn', '1': 'wnnwnnnnw', '2': 'nnwwnnnnw',
|
||||
'3': 'wnwwnnnnn', '4': 'nnnwwnnnw', '5': 'wnnwwnnnn',
|
||||
'6': 'nnwwwnnnn', '7': 'nnnwnnwnw', '8': 'wnnwnnwnn',
|
||||
'9': 'nnwwnnwnn', 'A': 'wnnnnwnnw', 'B': 'nnwnnwnnw',
|
||||
@@ -1860,8 +1893,8 @@ class FPDF(object):
|
||||
'+': 'nwnnnwnwn', '%': 'nnnwnwnwn'}
|
||||
|
||||
self.set_fill_color(0)
|
||||
code = txt
|
||||
|
||||
code = txt
|
||||
|
||||
code = code.upper()
|
||||
for i in xrange (0, len(code), 2):
|
||||
char_bar = code[i]
|
||||
@@ -1871,7 +1904,7 @@ class FPDF(object):
|
||||
|
||||
seq= ''
|
||||
for s in xrange(0, len(bar_char[char_bar])):
|
||||
seq += bar_char[char_bar][s]
|
||||
seq += bar_char[char_bar][s]
|
||||
|
||||
for bar in xrange(0, len(seq)):
|
||||
if seq[bar] == 'n':
|
||||
|
||||
@@ -815,7 +815,7 @@ class Connection(object):
|
||||
outrec = Record(FCGI_UNKNOWN_TYPE)
|
||||
outrec.contentData = struct.pack(FCGI_UnknownTypeBody, inrec.type)
|
||||
outrec.contentLength = FCGI_UnknownTypeBody_LEN
|
||||
self.writeRecord(rec)
|
||||
self.writeRecord(outrec)
|
||||
|
||||
class MultiplexedConnection(Connection):
|
||||
"""
|
||||
|
||||
@@ -51,7 +51,7 @@ def THUMB(image, nx=120, ny=120, gae=False, name='thumb'):
|
||||
request = current.request
|
||||
from PIL import Image
|
||||
import os
|
||||
img = Image.open(request.folder + 'uploads/' + image)
|
||||
img = Image.open(os.path.join(request.folder,'uploads',image))
|
||||
img.thumbnail((nx, ny), Image.ANTIALIAS)
|
||||
root, ext = os.path.splitext(image)
|
||||
thumb = '%s_%s%s' % (root, name, ext)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1 @@
|
||||
|
||||
|
||||
@@ -52,12 +52,8 @@ class DropboxAccount(object):
|
||||
self.sess = session.DropboxSession(
|
||||
self.key, self.secret, self.access_type)
|
||||
|
||||
def get_user(self):
|
||||
request = self.request
|
||||
if not current.session.dropbox_request_token:
|
||||
return None
|
||||
elif not current.session.dropbox_access_token:
|
||||
|
||||
def get_token(self):
|
||||
if not current.session.dropbox_access_token:
|
||||
request_token = current.session.dropbox_request_token
|
||||
self.sess.set_request_token(request_token[0], request_token[1])
|
||||
access_token = self.sess.obtain_access_token(self.sess.token)
|
||||
@@ -67,6 +63,10 @@ class DropboxAccount(object):
|
||||
access_token = current.session.dropbox_access_token
|
||||
self.sess.set_token(access_token[0], access_token[1])
|
||||
|
||||
def get_user(self):
|
||||
if not current.session.dropbox_request_token:
|
||||
return None
|
||||
self.get_token()
|
||||
user = Storage()
|
||||
self.client = client.DropboxClient(self.sess)
|
||||
data = self.client.account_info()
|
||||
@@ -94,27 +94,25 @@ class DropboxAccount(object):
|
||||
return form
|
||||
|
||||
def logout_url(self, next="/"):
|
||||
current.session.dropbox_request_token = None
|
||||
self.sess.unlink()
|
||||
current.session.auth = None
|
||||
redirect('https://www.dropbox.com/logout')
|
||||
return next
|
||||
|
||||
def get_client(self):
|
||||
access_token = current.session.dropbox_access_token
|
||||
self.sess.set_token(access_token[0], access_token[1])
|
||||
self.get_token()
|
||||
self.client = client.DropboxClient(self.sess)
|
||||
|
||||
def put(self, filename, file):
|
||||
if not hasattr(self,'client'): self.get_client()
|
||||
return json.loads(self.client.put_file(filename, file))['bytes']
|
||||
return self.client.put_file(filename, file)['bytes']
|
||||
|
||||
def get(self, filename, file):
|
||||
def get(self, filename):
|
||||
if not hasattr(self,'client'): self.get_client()
|
||||
return self.client.get_file(filename)
|
||||
|
||||
def dir(self, path):
|
||||
if not hasattr(self,'client'): self.get_client()
|
||||
return json.loads(self.client.metadata(path))
|
||||
return self.client.metadata(path)
|
||||
|
||||
|
||||
def use_dropbox(auth, filename='private/dropbox.key', **kwargs):
|
||||
|
||||
@@ -653,7 +653,8 @@ def ldap_auth(server='ldap', port=None,
|
||||
ldap_groups_of_the_user = list()
|
||||
for group_row in group_search_result:
|
||||
group = group_row[1]
|
||||
ldap_groups_of_the_user.extend(group[group_name_attrib])
|
||||
if type(group) == dict and group.has_key(group_name_attrib):
|
||||
ldap_groups_of_the_user.extend(group[group_name_attrib])
|
||||
|
||||
con.unbind()
|
||||
logger.debug('User groups: %s' % ldap_groups_of_the_user)
|
||||
@@ -662,4 +663,3 @@ def ldap_auth(server='ldap', port=None,
|
||||
if filterstr[0] == '(' and filterstr[-1] == ')': # rfc4515 syntax
|
||||
filterstr = filterstr[1:-1] # parens added again where used
|
||||
return ldap_auth_aux
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
|
||||
@@ -0,0 +1,97 @@
|
||||
#!/usr/bin/env python
|
||||
# coding: utf8
|
||||
|
||||
"""
|
||||
LoginRadius Authentication for web2py
|
||||
Developed by Nathan Freeze (Copyright © 2013)
|
||||
Email <nathan@freezable.com>
|
||||
|
||||
This file contains code to allow using loginradius.com
|
||||
authentication services with web2py
|
||||
"""
|
||||
|
||||
import os
|
||||
from gluon import *
|
||||
from gluon.storage import Storage
|
||||
from gluon.contrib.simplejson import JSONDecodeError
|
||||
from gluon.tools import fetch
|
||||
import gluon.contrib.simplejson as json
|
||||
|
||||
|
||||
class LoginRadiusAccount(object):
|
||||
"""
|
||||
from gluon.contrib.login_methods.loginradius_account import LoginRadiusAccount
|
||||
auth.settings.actions_disabled=['register','change_password',
|
||||
'request_reset_password']
|
||||
auth.settings.login_form = LoginRadiusAccount(request,
|
||||
api_key="...",
|
||||
api_secret="...",
|
||||
url = "http://localhost:8000/%s/default/user/login" % request.application)
|
||||
"""
|
||||
|
||||
def __init__(self, request, api_key="", api_secret="",
|
||||
url=None, on_login_failure=None):
|
||||
|
||||
self.request = request
|
||||
self.api_key = api_key
|
||||
self.api_secret = api_secret
|
||||
self.url = url
|
||||
self.auth_base_url = "https://hub.loginradius.com/UserProfile.ashx/"
|
||||
self.profile = None
|
||||
self.on_login_failure = on_login_failure
|
||||
self.mappings = Storage()
|
||||
|
||||
def defaultmapping(profile):
|
||||
first_name = profile.get('FirstName')
|
||||
last_name = profile.get('LastName')
|
||||
email = profile.get('Email', [{}])[0].get('Value')
|
||||
reg_id = profile.get('ID', '')
|
||||
username = profile.get('ProfileName', email)
|
||||
|
||||
return dict(registration_id=reg_id, username=username, email=email,
|
||||
first_name=first_name, last_name=last_name)
|
||||
|
||||
self.mappings.default = defaultmapping
|
||||
|
||||
def get_user(self):
|
||||
request = self.request
|
||||
user = None
|
||||
if request.vars.token:
|
||||
try:
|
||||
auth_url = self.auth_base_url + self.api_secret + "/" + request.vars.token
|
||||
json_data = fetch(auth_url, headers={'User-Agent': "LoginRadius - Python - SDK"})
|
||||
self.profile = json.loads(json_data)
|
||||
provider = self.profile['Provider']
|
||||
mapping = self.mappings.get(provider, self.mappings['default'])
|
||||
user = mapping(self.profile)
|
||||
except (JSONDecodeError, KeyError):
|
||||
pass
|
||||
if user is None and self.on_login_failure:
|
||||
redirect(self.on_login_failure)
|
||||
return user
|
||||
|
||||
def login_form(self):
|
||||
loginradius_url = "https://hub.loginradius.com/include/js/LoginRadius.js"
|
||||
loginradius_lib = SCRIPT(_src=loginradius_url, _type='text/javascript')
|
||||
container = DIV(_id="interfacecontainerdiv", _class='interfacecontainerdiv')
|
||||
widget = SCRIPT("""var options={}; options.login=true;
|
||||
LoginRadius_SocialLogin.util.ready(function () {
|
||||
$ui = LoginRadius_SocialLogin.lr_login_settings;
|
||||
$ui.interfacesize = "";$ui.apikey = "%s";
|
||||
$ui.callback=""; $ui.lrinterfacecontainer ="interfacecontainerdiv";
|
||||
LoginRadius_SocialLogin.init(options); });""" % self.api_key)
|
||||
form = DIV(container, loginradius_lib, widget)
|
||||
return form
|
||||
|
||||
|
||||
def use_loginradius(auth, filename='private/loginradius.key', **kwargs):
|
||||
path = os.path.join(current.request.folder, filename)
|
||||
if os.path.exists(path):
|
||||
request = current.request
|
||||
domain, public_key, private_key = open(path, 'r').read().strip().split(':')
|
||||
url = URL('default', 'user', args='login', scheme=True)
|
||||
auth.settings.actions_disabled = \
|
||||
['register', 'change_password', 'request_reset_password']
|
||||
auth.settings.login_form = LoginRadiusAccount(
|
||||
request, api_key=public_key, api_secret=private_key,
|
||||
url=url, **kwargs)
|
||||
@@ -176,7 +176,7 @@ class OAuthAccount(object):
|
||||
|
||||
HTTP = self.globals['HTTP']
|
||||
|
||||
raise HTTP(307,
|
||||
raise HTTP(302,
|
||||
"You are not authenticated: you are being redirected to the <a href='" + auth_request_url + "'> authentication server</a>",
|
||||
Location=auth_request_url)
|
||||
|
||||
|
||||
@@ -147,7 +147,7 @@ server for requests. It can be used for the optional"scope" parameters for Face
|
||||
# reuse token until expiration
|
||||
if expires == 0 or expires > time.time():
|
||||
return current.session.token['access_token']
|
||||
|
||||
|
||||
code = current.request.vars.code
|
||||
|
||||
if code:
|
||||
@@ -285,7 +285,7 @@ server for requests. It can be used for the optional"scope" parameters for Face
|
||||
if self.args:
|
||||
data.update(self.args)
|
||||
auth_request_url = self.auth_url + "?" + urlencode(data)
|
||||
raise HTTP(307,
|
||||
raise HTTP(302,
|
||||
"You are not authenticated: you are being redirected to the <a href='" + auth_request_url + "'> authentication server</a>",
|
||||
Location=auth_request_url)
|
||||
return
|
||||
|
||||
@@ -135,7 +135,7 @@ class OpenIDAuth(object):
|
||||
Otherwise it's always 'openid' and you
|
||||
may not need it. This should be easy to changed.
|
||||
(Just remove the field of "type" and remove the
|
||||
"and db.alt_logins.oidtype == type_"
|
||||
"and db.alt_logins.oidtype == type_"
|
||||
in _find_matched_openid function)
|
||||
"""
|
||||
db = self.db
|
||||
|
||||
@@ -544,10 +544,10 @@ regex_list=re.compile('^(?:(?:(#{1,6})|(?:(\.+|\++|\-+)(\.)?))\s*)?(.*)$')
|
||||
regex_bq_headline=re.compile('^(?:(\.+|\++|\-+)(\.)?\s+)?(-{3}-*)$')
|
||||
regex_tq=re.compile('^(-{3}-*)(?::(?P<c>[a-zA-Z][_a-zA-Z\-\d]*)(?:\[(?P<p>[a-zA-Z][_a-zA-Z\-\d]*)\])?)?$')
|
||||
regex_proto = re.compile(r'(?<!["\w>/=])(?P<p>\w+):(?P<k>\w+://[\w\d\-+=?%&/:.]+)', re.M)
|
||||
regex_auto = re.compile(r'(?<!["\w>/=])(?P<k>\w+://[\w\d\-+_=?%&/:.]+)',re.M)
|
||||
regex_auto = re.compile(r'(?<!["\w>/=])(?P<k>\w+://[\w\d\-+_=?%&/:.,;#]+\w)',re.M)
|
||||
regex_link=re.compile(r'('+LINK+r')|\[\[(?P<s>.+?)\]\]',re.S)
|
||||
regex_link_level2=re.compile(r'^(?P<t>\S.*?)?(?:\s+\[(?P<a>.+?)\])?(?:\s+(?P<k>\S+))?(?:\s+(?P<p>popup))?\s*$',re.S)
|
||||
regex_media_level2=re.compile(r'^(?P<t>\S.*?)?(?:\s+\[(?P<a>.+?)\])?(?:\s+(?P<k>\S+))?\s+(?P<p>img|IMG|left|right|center|video|audio)(?:\s+(?P<w>\d+px))?\s*$',re.S)
|
||||
regex_media_level2=re.compile(r'^(?P<t>\S.*?)?(?:\s+\[(?P<a>.+?)\])?(?:\s+(?P<k>\S+))?\s+(?P<p>img|IMG|left|right|center|video|audio|blockleft|blockright)(?:\s+(?P<w>\d+px))?\s*$',re.S)
|
||||
|
||||
regex_markmin_escape = re.compile(r"(\\*)(['`:*~\\[\]{}@\$+\-.#\n])")
|
||||
regex_backslash = re.compile(r"\\(['`:*~\\[\]{}@\$+\-.#\n])")
|
||||
@@ -859,6 +859,8 @@ def render(text,
|
||||
if autolinks=="default": autolinks = autolinks_simple
|
||||
if protolinks=="default": protolinks = protolinks_simple
|
||||
pp='\n' if pretty_print else ''
|
||||
if isinstance(text,unicode):
|
||||
text = text.encode('utf8')
|
||||
text = str(text or '')
|
||||
text = regex_backslash.sub(lambda m: m.group(1).translate(ttab_in), text)
|
||||
text = text.replace('\x05','') # concatenate strings separeted by \\n
|
||||
@@ -1242,8 +1244,18 @@ def render(text,
|
||||
if p == 'center':
|
||||
p_begin = '<p style="text-align:center">'
|
||||
p_end = '</p>'+pp
|
||||
elif p == 'blockleft':
|
||||
p_begin = '<p style="text-align:left">'
|
||||
p_end = '</p>'+pp
|
||||
elif p == 'blockright':
|
||||
p_begin = '<p style="text-align:right">'
|
||||
p_end = '</p>'+pp
|
||||
elif p in ('left','right'):
|
||||
style = ('float:%s' % p)+(';%s' % style if style else '')
|
||||
if t and regex_auto.match(t):
|
||||
p_begin = p_begin + '<a href="%s">' % t
|
||||
p_end = '</a>' + p_end
|
||||
t = ''
|
||||
if style:
|
||||
style = ' style="%s"' % style
|
||||
if p in ('video','audio'):
|
||||
|
||||
@@ -80,7 +80,7 @@ class MemcacheClientObj(Client):
|
||||
newKey = self.__keyFormat__(key)
|
||||
obj = Client.get(self, newKey)
|
||||
if obj:
|
||||
if isinstance(obj,(int,double,long)):
|
||||
if isinstance(obj,(int,float,long)):
|
||||
return Client.incr(self, newKey, value)
|
||||
else:
|
||||
value += obj[1]
|
||||
|
||||
Executable
+17
@@ -0,0 +1,17 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf8 -*-
|
||||
# Plural-Forms for id (Indonesian)
|
||||
|
||||
nplurals=2 # Indonesian language has 2 forms:
|
||||
# 1 singular and 1 plural
|
||||
|
||||
# Determine plural_id for number *n* as sequence of positive
|
||||
# integers: 0,1,...
|
||||
# NOTE! For singular form ALWAYS return plural_id = 0
|
||||
get_plural_id = lambda n: int(n != 1)
|
||||
|
||||
# Construct and return plural form of *word* using
|
||||
# *plural_id* (which ALWAYS>0). This function will be executed
|
||||
# for words (or phrases) not found in plural_dict dictionary
|
||||
# construct_plural_form = lambda word, plural_id: (word + 'suffix')
|
||||
|
||||
Executable
+17
@@ -0,0 +1,17 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf8 -*-
|
||||
# Plural-Forms for id (Malay)
|
||||
|
||||
nplurals=2 # Malay language has 2 forms:
|
||||
# 1 singular and 1 plural
|
||||
|
||||
# Determine plural_id for number *n* as sequence of positive
|
||||
# integers: 0,1,...
|
||||
# NOTE! For singular form ALWAYS return plural_id = 0
|
||||
get_plural_id = lambda n: int(n != 1)
|
||||
|
||||
# Construct and return plural form of *word* using
|
||||
# *plural_id* (which ALWAYS>0). This function will be executed
|
||||
# for words (or phrases) not found in plural_dict dictionary
|
||||
# construct_plural_form = lambda word, plural_id: (word + 'suffix')
|
||||
|
||||
+87
-23
File diff suppressed because one or more lines are too long
+2364
-2364
File diff suppressed because it is too large
Load Diff
+137
-43
@@ -1,8 +1,7 @@
|
||||
"""
|
||||
Developed by 616d41631bff906704951934ffe4015e
|
||||
Developed by niphlod@gmail.com
|
||||
Released under web2py license because includes gluon/cache.py source code
|
||||
"""
|
||||
|
||||
import redis
|
||||
from redis.exceptions import ConnectionError
|
||||
from gluon import current
|
||||
@@ -12,6 +11,8 @@ import time
|
||||
import re
|
||||
import logging
|
||||
import thread
|
||||
import random
|
||||
|
||||
|
||||
logger = logging.getLogger("web2py.cache.redis")
|
||||
|
||||
@@ -23,15 +24,42 @@ def RedisCache(*args, **vars):
|
||||
Usage example: put in models
|
||||
|
||||
from gluon.contrib.redis_cache import RedisCache
|
||||
cache.redis = RedisCache('localhost:6379',db=None, debug=True)
|
||||
cache.redis = RedisCache('localhost:6379',db=None, debug=True, with_lock=True)
|
||||
|
||||
:param db: redis db to use (0..16)
|
||||
:param debug: if True adds to stats() the total_hits and misses
|
||||
:param with_lock: sets the default locking mode for creating new keys.
|
||||
By default is False (usualy when you choose Redis you do it
|
||||
for performances reason)
|
||||
When True, only one thread/process can set a value concurrently
|
||||
|
||||
When you use cache.redis directly you can use
|
||||
value = cache.redis('mykey', lambda: time.time(), with_lock=True)
|
||||
to enforce locking. The with_lock parameter overrides the one set in the
|
||||
cache.redis instance creation
|
||||
|
||||
cache.redis.stats()
|
||||
returns a dictionary with statistics of Redis server
|
||||
with one additional key ('w2p_keys') showing all keys currently set
|
||||
from web2py with their TTL
|
||||
|
||||
return a dictionary with statistics of Redis server
|
||||
with one additional key ('w2p_keys') showing all keys currently set
|
||||
from web2py with their TTL
|
||||
if debug=True additional tracking is activate and another key is added
|
||||
('w2p_stats') showing total_hits and misses
|
||||
A little wording on how keys are stored (and why the cache_it() function
|
||||
and the clear() one look a little bit convoluted): there are a lot of
|
||||
libraries that just store values and then use the KEYS command to delete it.
|
||||
Until recent releases of this module, that technique was used here too.
|
||||
In the need of deleting specific keys in a database with zillions keys in it
|
||||
(other web2py apps, other applications in the need of a Redis stack) the
|
||||
KEYS command is slow (it needs to scan every key in the database).
|
||||
So, we use Redis 'sets' to store keys in "buckets"...
|
||||
- every key created gets "indexed" in a bucket
|
||||
- all buckets are indexed in a fixed key that never expires
|
||||
- all keys generated within the same minute go in the same bucket
|
||||
- every bucket is then set to expire when every key within it is expired
|
||||
When we need to clear() cached keys:
|
||||
- we tell Redis to SUNION all buckets
|
||||
- gives us just the keys that are not expired yet
|
||||
- buckets that are expired are removed from the fixed set
|
||||
- we scan the keys and then delete them
|
||||
"""
|
||||
|
||||
locker.acquire()
|
||||
@@ -49,13 +77,15 @@ class RedisClient(object):
|
||||
MAX_RETRIES = 5
|
||||
RETRIES = 0
|
||||
|
||||
def __init__(self, server='localhost:6379', db=None, debug=False):
|
||||
def __init__(self, server='localhost:6379', db=None, debug=False, with_lock=False):
|
||||
self.server = server
|
||||
self.db = db or 0
|
||||
host, port = (self.server.split(':') + ['6379'])[:2]
|
||||
port = int(port)
|
||||
self.request = current.request
|
||||
self.debug = debug
|
||||
self.with_lock = with_lock
|
||||
self.prefix = "w2p:%s:" % (self.request.application)
|
||||
if self.request:
|
||||
app = self.request.application
|
||||
else:
|
||||
@@ -70,67 +100,112 @@ class RedisClient(object):
|
||||
else:
|
||||
self.storage = self.meta_storage[app]
|
||||
|
||||
self.cache_set_key = 'w2p:%s:___cache_set' % (self.request.application)
|
||||
|
||||
self.r_server = redis.Redis(host=host, port=port, db=self.db)
|
||||
|
||||
def __call__(self, key, f, time_expire=300):
|
||||
def __call__(self, key, f, time_expire=300, with_lock=None):
|
||||
if with_lock is None:
|
||||
with_lock = self.with_lock
|
||||
if time_expire is None:
|
||||
time_expire = 24 * 60 * 60
|
||||
newKey = self.__keyFormat__(key)
|
||||
value = None
|
||||
ttl = 0
|
||||
try:
|
||||
if time_expire is None:
|
||||
time_expire = 24 * 60 * 60
|
||||
newKey = self.__keyFormat__(key)
|
||||
value = None
|
||||
#is there a value
|
||||
obj = self.r_server.get(newKey)
|
||||
ttl = self.r_server.ttl(newKey) or 0
|
||||
#what's its ttl
|
||||
if obj:
|
||||
ttl = self.r_server.ttl(newKey)
|
||||
if ttl > time_expire:
|
||||
obj = None
|
||||
if obj:
|
||||
#was cached
|
||||
if self.debug:
|
||||
self.r_server.incr('web2py_cache_statistics:hit_total')
|
||||
value = pickle.loads(obj)
|
||||
elif f is None:
|
||||
#delete and never look back
|
||||
self.r_server.delete(newKey)
|
||||
else:
|
||||
if self.debug:
|
||||
self.r_server.incr('web2py_cache_statistics:misses')
|
||||
value = f()
|
||||
if time_expire == 0:
|
||||
time_expire = 1
|
||||
self.r_server.setex(newKey, pickle.dumps(value), time_expire)
|
||||
#naive distributed locking
|
||||
if with_lock:
|
||||
lock_key = '%s:__lock' % newKey
|
||||
try:
|
||||
while True:
|
||||
lock = self.r_server.setnx(lock_key, 1)
|
||||
if lock:
|
||||
value = self.cache_it(newKey, f, time_expire)
|
||||
break
|
||||
else:
|
||||
time.sleep(0.2)
|
||||
#did someone else create it in the meanwhile ?
|
||||
obj = self.r_server.get(newKey)
|
||||
if obj:
|
||||
value = pickle.loads(obj)
|
||||
break
|
||||
finally:
|
||||
self.r_server.delete(lock_key)
|
||||
else:
|
||||
#without distributed locking
|
||||
value = self.cache_it(newKey, f, time_expire)
|
||||
return value
|
||||
except ConnectionError:
|
||||
return self.retry_call(key, f, time_expire)
|
||||
return self.retry_call(key, f, time_expire, with_lock)
|
||||
|
||||
def retry_call(self, key, f, time_expire):
|
||||
def cache_it(self, key, f, time_expire):
|
||||
if self.debug:
|
||||
self.r_server.incr('web2py_cache_statistics:misses')
|
||||
cache_set_key = self.cache_set_key
|
||||
expireat = int(time.time() + time_expire) + 120
|
||||
bucket_key = "%s:%s" % (cache_set_key, expireat / 60)
|
||||
value = f()
|
||||
value_ = pickle.dumps(value)
|
||||
if time_expire == 0:
|
||||
time_expire = 1
|
||||
self.r_server.setex(key, value_, time_expire)
|
||||
#print '%s will expire on %s: it goes in bucket %s' % (key, time.ctime(expireat))
|
||||
#print 'that will expire on %s' % (bucket_key, time.ctime(((expireat/60) + 1)*60))
|
||||
p = self.r_server.pipeline()
|
||||
#add bucket to the fixed set
|
||||
p.sadd(cache_set_key, bucket_key)
|
||||
#sets the key
|
||||
p.setex(key, value_, time_expire)
|
||||
#add the key to the bucket
|
||||
p.sadd(bucket_key, key)
|
||||
#expire the bucket properly
|
||||
p.expireat(bucket_key, ((expireat/60) + 1)*60)
|
||||
p.execute()
|
||||
return value
|
||||
|
||||
def retry_call(self, key, f, time_expire, with_locking):
|
||||
self.RETRIES += 1
|
||||
if self.RETRIES <= self.MAX_RETRIES:
|
||||
logger.error("sleeping %s seconds before reconnecting" %
|
||||
(2 * self.RETRIES))
|
||||
time.sleep(2 * self.RETRIES)
|
||||
self.__init__(self.server, self.db, self.debug)
|
||||
return self.__call__(key, f, time_expire)
|
||||
self.__init__(self.server, self.db, self.debug, self.with_lock)
|
||||
return self.__call__(key, f, time_expire, with_locking)
|
||||
else:
|
||||
self.RETRIES = 0
|
||||
raise ConnectionError('Redis instance is unavailable at %s' % (
|
||||
self.server))
|
||||
|
||||
def increment(self, key, value=1, time_expire=300):
|
||||
def increment(self, key, value=1):
|
||||
try:
|
||||
newKey = self.__keyFormat__(key)
|
||||
obj = self.r_server.get(newKey)
|
||||
if obj:
|
||||
return self.r_server.incr(newKey, value)
|
||||
else:
|
||||
self.r_server.setex(newKey, value, time_expire)
|
||||
return value
|
||||
return self.r_server.incr(newKey, value)
|
||||
except ConnectionError:
|
||||
return self.retry_increment(key, value, time_expire)
|
||||
return self.retry_increment(key, value)
|
||||
|
||||
def retry_increment(self, key, value, time_expire):
|
||||
def retry_increment(self, key, value):
|
||||
self.RETRIES += 1
|
||||
if self.RETRIES <= self.MAX_RETRIES:
|
||||
logger.error("sleeping some seconds before reconnecting")
|
||||
time.sleep(2 * self.RETRIES)
|
||||
self.__init__(self.server, self.db, self.debug)
|
||||
return self.increment(key, value, time_expire)
|
||||
self.__init__(self.server, self.db, self.debug, self.with_lock)
|
||||
return self.increment(key, value)
|
||||
else:
|
||||
self.RETRIES = 0
|
||||
raise ConnectionError('Redis instance is unavailable at %s' % (
|
||||
@@ -142,14 +217,34 @@ class RedisClient(object):
|
||||
clear cache entries
|
||||
"""
|
||||
r = re.compile(regex)
|
||||
prefix = "w2p:%s:" % (self.request.application)
|
||||
#get all buckets
|
||||
buckets = self.r_server.smembers(self.cache_set_key)
|
||||
#get all keys in buckets
|
||||
if buckets:
|
||||
keys = self.r_server.sunion(buckets)
|
||||
else:
|
||||
return
|
||||
prefix = self.prefix
|
||||
pipe = self.r_server.pipeline()
|
||||
for a in self.r_server.keys("%s*" %
|
||||
(prefix)):
|
||||
for a in keys:
|
||||
if r.match(str(a).replace(prefix, '', 1)):
|
||||
pipe.delete(a)
|
||||
if random.randrange(0,100) < 10:
|
||||
#do this just once in a while (10% chance)
|
||||
self.clear_buckets(buckets)
|
||||
pipe.execute()
|
||||
|
||||
def clear_buckets(self, buckets):
|
||||
p = self.r_server.pipeline()
|
||||
for b in buckets:
|
||||
if not self.r_server.exists(b):
|
||||
p.srem(self.cache_set_key, b)
|
||||
p.execute()
|
||||
|
||||
def delete(self, key):
|
||||
newKey = self.__keyFormat__(key)
|
||||
return self.r_server.delete(newKey)
|
||||
|
||||
def stats(self):
|
||||
statscollector = self.r_server.info()
|
||||
if self.debug:
|
||||
@@ -159,12 +254,11 @@ class RedisClient(object):
|
||||
misses=self.r_server.get('web2py_cache_statistics:misses')
|
||||
)
|
||||
statscollector['w2p_keys'] = dict()
|
||||
|
||||
for a in self.r_server.keys("w2p:%s:*" % (
|
||||
self.request.application)):
|
||||
statscollector['w2p_keys']["%s_expire_in_sec" % (a)] = \
|
||||
self.r_server.ttl(a)
|
||||
statscollector['w2p_keys']["%s_expire_in_sec" % (a)] = self.r_server.ttl(a)
|
||||
return statscollector
|
||||
|
||||
def __keyFormat__(self, key):
|
||||
return 'w2p:%s:%s' % (self.request.application,
|
||||
key.replace(' ', '_'))
|
||||
return '%s%s' % (self.prefix, key.replace(' ', '_'))
|
||||
|
||||
@@ -29,11 +29,12 @@ def RedisSession(*args, **vars):
|
||||
|
||||
locker.acquire()
|
||||
try:
|
||||
if not hasattr(RedisSession, 'redis_instance'):
|
||||
RedisSession.redis_instance = RedisClient(*args, **vars)
|
||||
instance_name = 'redis_instance_' + current.request.application
|
||||
if not hasattr(RedisSession, instance_name):
|
||||
setattr(RedisSession, instance_name, RedisClient(*args, **vars))
|
||||
return getattr(RedisSession, instance_name)
|
||||
finally:
|
||||
locker.release()
|
||||
return RedisSession.redis_instance
|
||||
|
||||
|
||||
class RedisClient(object):
|
||||
@@ -41,8 +42,10 @@ class RedisClient(object):
|
||||
meta_storage = {}
|
||||
MAX_RETRIES = 5
|
||||
RETRIES = 0
|
||||
_release_script = None
|
||||
|
||||
def __init__(self, server='localhost:6379', db=None, debug=False, session_expiry=False):
|
||||
def __init__(self, server='localhost:6379', db=None, debug=False,
|
||||
session_expiry=False, with_lock=False):
|
||||
"""session_expiry can be an integer, in seconds, to set the default expiration
|
||||
of sessions. The corresponding record will be deleted from the redis instance,
|
||||
and there's virtually no need to run sessions2trash.py
|
||||
@@ -57,8 +60,12 @@ class RedisClient(object):
|
||||
else:
|
||||
self.app = ''
|
||||
self.r_server = redis.Redis(host=host, port=port, db=self.db)
|
||||
if with_lock:
|
||||
RedisClient._release_script = \
|
||||
self.r_server.register_script(_LUA_RELEASE_LOCK)
|
||||
self.tablename = None
|
||||
self.session_expiry = session_expiry
|
||||
self.with_lock = with_lock
|
||||
|
||||
def get(self, what, default):
|
||||
return self.tablename
|
||||
@@ -70,7 +77,8 @@ class RedisClient(object):
|
||||
def define_table(self, tablename, *fields, **args):
|
||||
if not self.tablename:
|
||||
self.tablename = MockTable(
|
||||
self, self.r_server, tablename, self.session_expiry)
|
||||
self, self.r_server, tablename, self.session_expiry,
|
||||
self.with_lock)
|
||||
return self.tablename
|
||||
|
||||
def __getitem__(self, key):
|
||||
@@ -87,7 +95,7 @@ class RedisClient(object):
|
||||
|
||||
class MockTable(object):
|
||||
|
||||
def __init__(self, db, r_server, tablename, session_expiry):
|
||||
def __init__(self, db, r_server, tablename, session_expiry, with_lock=False):
|
||||
self.db = db
|
||||
self.r_server = r_server
|
||||
self.tablename = tablename
|
||||
@@ -100,15 +108,14 @@ class MockTable(object):
|
||||
self.id_idx = "%s:id_idx" % self.keyprefix
|
||||
#remember the session_expiry setting
|
||||
self.session_expiry = session_expiry
|
||||
|
||||
def getserial(self):
|
||||
#return an auto-increment id
|
||||
return "%s" % self.r_server.incr(self.serial, 1)
|
||||
self.with_lock = with_lock
|
||||
|
||||
def __getattr__(self, key):
|
||||
if key == 'id':
|
||||
#return a fake query. We need to query it just by id for normal operations
|
||||
self.query = MockQuery(field='id', db=self.r_server, prefix=self.keyprefix, session_expiry=self.session_expiry)
|
||||
self.query = MockQuery(field='id', db=self.r_server,
|
||||
prefix=self.keyprefix, session_expiry=self.session_expiry,
|
||||
with_lock=self.with_lock)
|
||||
return self.query
|
||||
elif key == '_db':
|
||||
#needed because of the calls in sessions2trash.py and globals.py
|
||||
@@ -119,14 +126,21 @@ class MockTable(object):
|
||||
#'locked', 'client_ip','created_datetime','modified_datetime'
|
||||
#'unique_key', 'session_data'
|
||||
#retrieve a new key
|
||||
newid = self.getserial()
|
||||
key = "%s:%s" % (self.keyprefix, newid)
|
||||
#add it to the index
|
||||
self.r_server.sadd(self.id_idx, key)
|
||||
#set a hash key with the Storage
|
||||
self.r_server.hmset(key, kwargs)
|
||||
if self.session_expiry:
|
||||
self.r_server.expire(key, self.session_expiry)
|
||||
newid = str(self.r_server.incr(self.serial))
|
||||
key = self.keyprefix + ':' + newid
|
||||
if self.with_lock:
|
||||
key_lock = key + ':lock'
|
||||
acquire_lock(self.r_server, key_lock, newid)
|
||||
with self.r_server.pipeline() as pipe:
|
||||
#add it to the index
|
||||
pipe.sadd(self.id_idx, key)
|
||||
#set a hash key with the Storage
|
||||
pipe.hmset(key, kwargs)
|
||||
if self.session_expiry:
|
||||
pipe.expire(key, self.session_expiry)
|
||||
pipe.execute()
|
||||
if self.with_lock:
|
||||
release_lock(self.r_server, key_lock, newid)
|
||||
return newid
|
||||
|
||||
|
||||
@@ -134,13 +148,15 @@ class MockQuery(object):
|
||||
"""a fake Query object that supports querying by id
|
||||
and listing all keys. No other operation is supported
|
||||
"""
|
||||
def __init__(self, field=None, db=None, prefix=None, session_expiry=False):
|
||||
def __init__(self, field=None, db=None, prefix=None, session_expiry=False,
|
||||
with_lock=False):
|
||||
self.field = field
|
||||
self.value = None
|
||||
self.db = db
|
||||
self.keyprefix = prefix
|
||||
self.op = None
|
||||
self.session_expiry = session_expiry
|
||||
self.with_lock = with_lock
|
||||
|
||||
def __eq__(self, value, op='eq'):
|
||||
self.value = value
|
||||
@@ -153,12 +169,11 @@ class MockQuery(object):
|
||||
def select(self):
|
||||
if self.op == 'eq' and self.field == 'id' and self.value:
|
||||
#means that someone wants to retrieve the key self.value
|
||||
rtn = self.db.hgetall("%s:%s" % (self.keyprefix, self.value))
|
||||
if rtn == dict():
|
||||
#return an empty resultset for non existing key
|
||||
return []
|
||||
else:
|
||||
return [Storage(rtn)]
|
||||
key = self.keyprefix + ':' + self.value
|
||||
if self.with_lock:
|
||||
acquire_lock(self.db, key + ':lock', self.value)
|
||||
rtn = self.db.hgetall(key)
|
||||
return [Storage(rtn)] if rtn else []
|
||||
elif self.op == 'ge' and self.field == 'id' and self.value == 0:
|
||||
#means that someone wants the complete list
|
||||
rtn = []
|
||||
@@ -167,13 +182,11 @@ class MockQuery(object):
|
||||
allkeys = self.db.smembers(id_idx)
|
||||
for sess in allkeys:
|
||||
val = self.db.hgetall(sess)
|
||||
if val == dict():
|
||||
if not val:
|
||||
if self.session_expiry:
|
||||
#clean up the idx, because the key expired
|
||||
self.db.srem(id_idx, sess)
|
||||
continue
|
||||
else:
|
||||
continue
|
||||
continue
|
||||
val = Storage(val)
|
||||
#add a delete_record method (necessary for sessions2trash.py)
|
||||
val.delete_record = RecordDeleter(
|
||||
@@ -186,9 +199,14 @@ class MockQuery(object):
|
||||
def update(self, **kwargs):
|
||||
#means that the session has been found and needs an update
|
||||
if self.op == 'eq' and self.field == 'id' and self.value:
|
||||
rtn = self.db.hmset("%s:%s" % (self.keyprefix, self.value), kwargs)
|
||||
if self.session_expiry:
|
||||
self.db.expire(key, self.session.expiry)
|
||||
key = "%s:%s" % (self.keyprefix, self.value)
|
||||
with self.db.pipeline() as pipe:
|
||||
pipe.hmset(key, kwargs)
|
||||
if self.session_expiry:
|
||||
pipe.expire(key, self.session_expiry)
|
||||
rtn = pipe.execute()[0]
|
||||
if self.with_lock:
|
||||
release_lock(self.db, key + ':lock', self.value)
|
||||
return rtn
|
||||
|
||||
|
||||
@@ -204,3 +222,25 @@ class RecordDeleter(object):
|
||||
self.db.srem(id_idx, self.key)
|
||||
#remove the key itself
|
||||
self.db.delete(self.key)
|
||||
|
||||
|
||||
def acquire_lock(conn, lockname, identifier, ltime=10):
|
||||
while True:
|
||||
if conn.set(lockname, identifier, ex=ltime, nx=True):
|
||||
return identifier
|
||||
time.sleep(.01)
|
||||
|
||||
|
||||
_LUA_RELEASE_LOCK = """
|
||||
if redis.call("get", KEYS[1]) == ARGV[1]
|
||||
then
|
||||
return redis.call("del", KEYS[1])
|
||||
else
|
||||
return 0
|
||||
end
|
||||
"""
|
||||
|
||||
|
||||
def release_lock(conn, lockname, identifier):
|
||||
return RedisClient._release_script(keys=[lockname], args=[identifier],
|
||||
client=conn)
|
||||
|
||||
+27
-14
@@ -23,6 +23,10 @@ class Stripe:
|
||||
if paid is True than transaction was processed
|
||||
"""
|
||||
|
||||
URL_CHARGE = 'https://%s:@api.stripe.com/v1/charges'
|
||||
URL_CHECK = 'https://%s:@api.stripe.com/v1/charges/%s'
|
||||
URL_REFUND = 'https://%s:@api.stripe.com/v1/charges/%s/refund'
|
||||
|
||||
def __init__(self, key):
|
||||
self.key = key
|
||||
|
||||
@@ -33,27 +37,36 @@ class Stripe:
|
||||
card_exp_month='5',
|
||||
card_exp_year='2012',
|
||||
card_cvc_check='123',
|
||||
description='test charge'):
|
||||
params = urllib.urlencode({'amount': amount,
|
||||
'currency': currency,
|
||||
'card[number]': card_number,
|
||||
'card[exp_month]': card_exp_month,
|
||||
'card[exp_year]': card_exp_year,
|
||||
'card[cvc_check]': card_cvc_check,
|
||||
'description': description})
|
||||
u = urllib.urlopen('https://%s:@api.stripe.com/v1/charges' %
|
||||
self.key, params)
|
||||
token=None,
|
||||
description='test charge',
|
||||
more=None):
|
||||
if token:
|
||||
d = {'amount': amount,
|
||||
'currency': currency,
|
||||
'card': token,
|
||||
'description': description}
|
||||
else:
|
||||
d = {'amount': amount,
|
||||
'currency': currency,
|
||||
'card[number]': card_number,
|
||||
'card[exp_month]': card_exp_month,
|
||||
'card[exp_year]': card_exp_year,
|
||||
'card[cvc_check]': card_cvc_check,
|
||||
'description': description}
|
||||
if more:
|
||||
d.update(mode)
|
||||
params = urllib.urlencode(d)
|
||||
u = urllib.urlopen(self.URL_CHARGE % self.key, params)
|
||||
return simplejson.loads(u.read())
|
||||
|
||||
def check(self, charge_id):
|
||||
u = urllib.urlopen('https://%s:@api.stripe.com/v1/charges/%s' %
|
||||
(self.key, charge_id))
|
||||
u = urllib.urlopen(self.URL_CHECK % (self.key, charge_id))
|
||||
return simplejson.loads(u.read())
|
||||
|
||||
def refund(self, charge_id):
|
||||
params = urllib.urlencode({})
|
||||
u = urllib.urlopen('https://%s:@api.stripe.com/v1/charges/%s/refund' %
|
||||
(self.key, charge_id), params)
|
||||
u = urllib.urlopen(self.URL_REFUND % (self.key, charge_id),
|
||||
params)
|
||||
return simplejson.loads(u.read())
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
@@ -15,12 +15,12 @@ mostly for testing purposes
|
||||
|
||||
Some examples at the bottom.
|
||||
"""
|
||||
|
||||
import re
|
||||
import time
|
||||
import urllib
|
||||
import urllib2
|
||||
|
||||
|
||||
DEFAULT_HEADERS = {
|
||||
'user-agent': 'Mozilla/4.0', # some servers are picky
|
||||
'accept-language': 'en',
|
||||
@@ -126,7 +126,11 @@ class WebClient(object):
|
||||
self.time = time.time() - t0
|
||||
self.response = error
|
||||
|
||||
self.status = self.response.getcode()
|
||||
if hasattr(self.response, 'getcode'):
|
||||
self.status = self.response.getcode()
|
||||
else:#python2.5
|
||||
self.status = None
|
||||
|
||||
self.text = self.response.read()
|
||||
self.headers = dict(self.response.headers)
|
||||
|
||||
|
||||
+362
-187
File diff suppressed because it is too large
Load Diff
+11
-7
@@ -223,19 +223,20 @@ def _extractall(filename, path='.', members=None):
|
||||
return ret
|
||||
|
||||
|
||||
def tar(file, dir, expression='^.+$'):
|
||||
def tar(file, dir, expression='^.+$', filenames=None):
|
||||
"""
|
||||
tars dir into file, only tars file that match expression
|
||||
"""
|
||||
|
||||
tar = tarfile.TarFile(file, 'w')
|
||||
try:
|
||||
for file in listdir(dir, expression, add_dirs=True):
|
||||
if filenames is None:
|
||||
filenames = listdir(dir, expression, add_dirs=True)
|
||||
for file in filenames:
|
||||
tar.add(os.path.join(dir, file), file, False)
|
||||
finally:
|
||||
tar.close()
|
||||
|
||||
|
||||
def untar(file, dir):
|
||||
"""
|
||||
untar file into dir
|
||||
@@ -244,14 +245,14 @@ def untar(file, dir):
|
||||
_extractall(file, dir)
|
||||
|
||||
|
||||
def w2p_pack(filename, path, compiled=False):
|
||||
def w2p_pack(filename, path, compiled=False, filenames=None):
|
||||
filename = abspath(filename)
|
||||
path = abspath(path)
|
||||
tarname = filename + '.tar'
|
||||
if compiled:
|
||||
tar_compiled(tarname, path, '^[\w\.\-]+$')
|
||||
else:
|
||||
tar(tarname, path, '^[\w\.\-]+$')
|
||||
tar(tarname, path, '^[\w\.\-]+$', filenames=filenames)
|
||||
w2pfp = gzopen(filename, 'wb')
|
||||
tarfp = open(tarname, 'rb')
|
||||
w2pfp.write(tarfp.read())
|
||||
@@ -366,16 +367,19 @@ def get_session(request, other_application='admin'):
|
||||
return osession
|
||||
|
||||
|
||||
def check_credentials(request, other_application='admin', expiration=60 * 60):
|
||||
def check_credentials(request, other_application='admin',
|
||||
expiration=60 * 60, gae_login=True):
|
||||
""" checks that user is authorized to access other_application"""
|
||||
if request.env.web2py_runtime_gae:
|
||||
from google.appengine.api import users
|
||||
if users.is_current_user_admin():
|
||||
return True
|
||||
else:
|
||||
elif gae_login:
|
||||
login_html = '<a href="%s">Sign in with your google account</a>.' \
|
||||
% users.create_login_url(request.env.path_info)
|
||||
raise HTTP(200, '<html><body>%s</body></html>' % login_html)
|
||||
else:
|
||||
return False
|
||||
else:
|
||||
dt = time.time() - expiration
|
||||
s = get_session(request, other_application)
|
||||
|
||||
+1
-1
@@ -695,7 +695,7 @@ class Session(Storage):
|
||||
|
||||
def forget(self, response=None):
|
||||
self._close(response)
|
||||
self._forget = True
|
||||
self._forget = True
|
||||
|
||||
def _try_store_in_cookie(self, request, response):
|
||||
if response.session_storage_type != 'cookie':
|
||||
|
||||
+16
-13
@@ -586,7 +586,7 @@ class XML(XmlComponent):
|
||||
return self.text
|
||||
|
||||
def __str__(self):
|
||||
return self.xml()
|
||||
return self.text
|
||||
|
||||
def __add__(self, other):
|
||||
return '%s%s' % (self, other)
|
||||
@@ -600,8 +600,9 @@ class XML(XmlComponent):
|
||||
def __hash__(self):
|
||||
return hash(str(self))
|
||||
|
||||
def __getattr__(self, name):
|
||||
return getattr(str(self), name)
|
||||
# why was this here? Break unpickling in sessions
|
||||
# def __getattr__(self, name):
|
||||
# return getattr(str(self), name)
|
||||
|
||||
def __getitem__(self, i):
|
||||
return str(self)[i]
|
||||
@@ -840,9 +841,8 @@ class DIV(XmlComponent):
|
||||
c.latest = self.latest
|
||||
c.session = self.session
|
||||
c.formname = self.formname
|
||||
if hideerror and not \
|
||||
self.attributes.get('hideerror', False):
|
||||
c['hideerror'] = hideerror
|
||||
c['hideerror'] = hideerror or \
|
||||
self.attributes.get('hideerror', False)
|
||||
newstatus = c._traverse(status, hideerror) and newstatus
|
||||
|
||||
# for input, textarea, select, option
|
||||
@@ -1198,6 +1198,13 @@ def TAG_pickler(data):
|
||||
return (TAG_unpickler, (marshal_dump,))
|
||||
|
||||
|
||||
class __tag__(DIV):
|
||||
def __init__(self,name,*a,**b):
|
||||
DIV.__init__(self,*a,**b)
|
||||
self.tag = name
|
||||
|
||||
copy_reg.pickle(__tag__, TAG_pickler, TAG_unpickler)
|
||||
|
||||
class __TAG__(XmlComponent):
|
||||
|
||||
"""
|
||||
@@ -1216,11 +1223,7 @@ class __TAG__(XmlComponent):
|
||||
name = name[:-1] + '/'
|
||||
if isinstance(name, unicode):
|
||||
name = name.encode('utf-8')
|
||||
|
||||
class __tag__(DIV):
|
||||
tag = name
|
||||
copy_reg.pickle(__tag__, TAG_pickler, TAG_unpickler)
|
||||
return lambda *a, **b: __tag__(*a, **b)
|
||||
return lambda *a,**b: __tag__(name,*a,**b)
|
||||
|
||||
def __call__(self, html):
|
||||
return web2pyHTMLParser(decoder.decoder(html)).tree
|
||||
@@ -1992,10 +1995,10 @@ class FORM(DIV):
|
||||
status = True
|
||||
changed = False
|
||||
request_vars = self.request_vars
|
||||
if session:
|
||||
if session is not None:
|
||||
formkey = session.get('_formkey[%s]' % formname, None)
|
||||
# check if user tampering with form and void CSRF
|
||||
if formkey != request_vars._formkey:
|
||||
if not formkey or formkey != request_vars._formkey:
|
||||
status = False
|
||||
if formname != request_vars._formname:
|
||||
status = False
|
||||
|
||||
+6
-5
@@ -123,14 +123,15 @@ class HTTP(BaseException):
|
||||
|
||||
message elements that are not defined are omitted
|
||||
"""
|
||||
msg = '%(status)d'
|
||||
msg = '%(status)s'
|
||||
if self.status in defined_status:
|
||||
msg = '%(status)d %(defined_status)s'
|
||||
msg = '%(status)s %(defined_status)s'
|
||||
if 'web2py_error' in self.headers:
|
||||
msg += ' [%(web2py_error)s]'
|
||||
return msg % dict(status=self.status,
|
||||
defined_status=defined_status.get(self.status),
|
||||
web2py_error=self.headers.get('web2py_error'))
|
||||
return msg % dict(
|
||||
status=self.status,
|
||||
defined_status=defined_status.get(self.status),
|
||||
web2py_error=self.headers.get('web2py_error'))
|
||||
|
||||
def __str__(self):
|
||||
"stringify me"
|
||||
|
||||
+1
-1
@@ -238,7 +238,7 @@ def read_possible_languages_aux(langdir):
|
||||
|
||||
plurals = {}
|
||||
flist = oslistdir(langdir) if isdir(langdir) else []
|
||||
|
||||
|
||||
# scan languages directory for plural dict files:
|
||||
for pname in flist:
|
||||
if regex_plural_file.match(pname):
|
||||
|
||||
+41
-10
@@ -29,6 +29,14 @@ import tempfile
|
||||
import random
|
||||
import string
|
||||
import urllib2
|
||||
try:
|
||||
import simplejson as sj #external installed library
|
||||
except:
|
||||
try:
|
||||
import json as sj #standard installed library
|
||||
except:
|
||||
import contrib.simplejson as sj #pure python library
|
||||
|
||||
from thread import allocate_lock
|
||||
|
||||
from fileutils import abspath, write_file, parse_version, copystream
|
||||
@@ -87,7 +95,7 @@ from settings import global_settings
|
||||
from validators import CRYPT
|
||||
from cache import CacheInRam
|
||||
from html import URL, xmlescape
|
||||
from utils import is_valid_ip_address
|
||||
from utils import is_valid_ip_address, getipaddrinfo
|
||||
from rewrite import load, url_in, THREAD_LOCAL as rwthread, \
|
||||
try_rewrite_on_error, fixup_missing_path_info
|
||||
import newcron
|
||||
@@ -131,7 +139,7 @@ def get_client(env):
|
||||
"""
|
||||
g = regex_client.search(env.get('http_x_forwarded_for', ''))
|
||||
client = (g.group() or '').split(',')[0] if g else None
|
||||
if client in (None, '', 'unkown'):
|
||||
if client in (None, '', 'unknown'):
|
||||
g = regex_client.search(env.get('remote_addr', ''))
|
||||
if g:
|
||||
client = g.group()
|
||||
@@ -295,6 +303,7 @@ def environ_aux(environ, request):
|
||||
new_environ['wsgi.version'] = 1
|
||||
return new_environ
|
||||
|
||||
ISLE25 = sys.version_info[1] <= 5
|
||||
|
||||
def parse_get_post_vars(request, environ):
|
||||
|
||||
@@ -311,17 +320,36 @@ def parse_get_post_vars(request, environ):
|
||||
request.get_vars[key] = value
|
||||
request.vars[key] = request.get_vars[key]
|
||||
|
||||
# parse POST variables on POST, PUT, BOTH only in post_vars
|
||||
|
||||
try:
|
||||
request.body = body = copystream_progress(request)
|
||||
except IOError:
|
||||
raise HTTP(400, "Bad Request - HTTP body is incomplete")
|
||||
if (body and env.request_method in ('POST', 'PUT', 'BOTH')):
|
||||
|
||||
#if content-type is application/json, we must read the body
|
||||
is_json = env.get('http_content_type', '')[:16] == 'application/json'
|
||||
|
||||
|
||||
if is_json:
|
||||
try:
|
||||
json_vars = sj.load(body)
|
||||
body.seek(0)
|
||||
except:
|
||||
# incoherent request bodies can still be parsed "ad-hoc"
|
||||
json_vars = {}
|
||||
pass
|
||||
# update vars and get_vars with what was posted as json
|
||||
request.get_vars.update(json_vars)
|
||||
request.vars.update(json_vars)
|
||||
|
||||
|
||||
# parse POST variables on POST, PUT, BOTH only in post_vars
|
||||
if (body and env.request_method in ('POST', 'PUT', 'DELETE', 'BOTH')):
|
||||
dpost = cgi.FieldStorage(fp=body, environ=environ, keep_blank_values=1)
|
||||
# The same detection used by FieldStorage to detect multipart POSTs
|
||||
is_multipart = dpost.type[:10] == 'multipart/'
|
||||
body.seek(0)
|
||||
isle25 = sys.version_info[1] <= 5
|
||||
|
||||
|
||||
def listify(a):
|
||||
return (not isinstance(a, list) and [a]) or a
|
||||
@@ -348,7 +376,7 @@ def parse_get_post_vars(request, environ):
|
||||
pvalue = listify(value)
|
||||
if key in request.vars:
|
||||
gvalue = listify(request.vars[key])
|
||||
if isle25:
|
||||
if ISLE25:
|
||||
value = pvalue + gvalue
|
||||
elif is_multipart:
|
||||
pvalue = pvalue[len(gvalue):]
|
||||
@@ -358,6 +386,9 @@ def parse_get_post_vars(request, environ):
|
||||
if len(pvalue):
|
||||
request.post_vars[key] = (len(pvalue) >
|
||||
1 and pvalue) or pvalue[0]
|
||||
if is_json:
|
||||
# update post_vars with what was posted as json
|
||||
request.post_vars.update(json_vars)
|
||||
|
||||
|
||||
def wsgibase(environ, responder):
|
||||
@@ -440,13 +471,13 @@ def wsgibase(environ, responder):
|
||||
local_hosts.add(socket.gethostname())
|
||||
local_hosts.add(fqdn)
|
||||
local_hosts.update([
|
||||
ip[4][0] for ip in socket.getaddrinfo(
|
||||
fqdn, 0)])
|
||||
addrinfo[4][0] for addrinfo
|
||||
in getipaddrinfo(fqdn)])
|
||||
if env.server_name:
|
||||
local_hosts.add(env.server_name)
|
||||
local_hosts.update([
|
||||
ip[4][0] for ip in socket.getaddrinfo(
|
||||
env.server_name, 0)])
|
||||
addrinfo[4][0] for addrinfo
|
||||
in getipaddrinfo(env.server_name)])
|
||||
except (socket.gaierror, TypeError):
|
||||
pass
|
||||
global_settings.local_hosts = list(local_hosts)
|
||||
|
||||
+3
-3
@@ -66,7 +66,7 @@ class XssCleaner(HTMLParser):
|
||||
# The only schemes allowed in URLs (for href and src attributes).
|
||||
# Adding "javascript" or "vbscript" to this list would not be smart.
|
||||
|
||||
self.allowed_schemes = ['http', 'https', 'ftp']
|
||||
self.allowed_schemes = ['http', 'https', 'ftp', 'mailto']
|
||||
|
||||
#to strip or escape disallowed tags?
|
||||
self.strip_disallowed = strip_disallowed
|
||||
@@ -151,11 +151,12 @@ class XssCleaner(HTMLParser):
|
||||
|
||||
def url_is_acceptable(self, url):
|
||||
"""
|
||||
Accepts relative and absolute urls
|
||||
Accepts relative, absolute, and mailto urls
|
||||
"""
|
||||
|
||||
parsed = urlparse(url)
|
||||
return (parsed[0] in self.allowed_schemes and '.' in parsed[1]) \
|
||||
or (parsed[0] in self.allowed_schemes and '@' in parsed[2]) \
|
||||
or (parsed[0] == '' and parsed[2].startswith('/'))
|
||||
|
||||
def strip(self, rawstring, escape=True):
|
||||
@@ -225,4 +226,3 @@ def sanitize(text, permitted_tags=[
|
||||
return str(text)
|
||||
return XssCleaner(permitted_tags=permitted_tags,
|
||||
allowed_attributes=allowed_attributes).strip(text, escape)
|
||||
|
||||
|
||||
+55
-9
@@ -107,6 +107,7 @@ TERMINATE = 'TERMINATE'
|
||||
DISABLED = 'DISABLED'
|
||||
KILL = 'KILL'
|
||||
PICK = 'PICK'
|
||||
STOP_TASK = 'STOP_TASK'
|
||||
EXPIRED = 'EXPIRED'
|
||||
SECONDS = 1
|
||||
HEARTBEAT = 3 * SECONDS
|
||||
@@ -398,7 +399,7 @@ class MetaScheduler(threading.Thread):
|
||||
|
||||
TASK_STATUS = (QUEUED, RUNNING, COMPLETED, FAILED, TIMEOUT, STOPPED, EXPIRED)
|
||||
RUN_STATUS = (RUNNING, COMPLETED, FAILED, TIMEOUT, STOPPED)
|
||||
WORKER_STATUS = (ACTIVE, PICK, DISABLED, TERMINATE, KILL)
|
||||
WORKER_STATUS = (ACTIVE, PICK, DISABLED, TERMINATE, KILL, STOP_TASK)
|
||||
|
||||
|
||||
class TYPE(object):
|
||||
@@ -562,16 +563,18 @@ class Scheduler(MetaScheduler):
|
||||
self.die()
|
||||
|
||||
def wrapped_assign_tasks(self, db):
|
||||
logger.debug('Assigning tasks...')
|
||||
db.commit() #db.commit() only for Mysql
|
||||
x = 0
|
||||
while x < 10:
|
||||
try:
|
||||
self.assign_tasks(db)
|
||||
db.commit()
|
||||
logger.debug('Tasks assigned...')
|
||||
break
|
||||
except:
|
||||
db.rollback()
|
||||
logger.error('TICKER: error assigning tasks')
|
||||
logger.error('TICKER: error assigning tasks (%s)', x)
|
||||
x += 1
|
||||
time.sleep(0.5)
|
||||
|
||||
@@ -746,7 +749,7 @@ class Scheduler(MetaScheduler):
|
||||
# keep sleeping
|
||||
self.worker_status[0] = DISABLED
|
||||
if self.worker_status[1] == MAXHIBERNATION:
|
||||
logger.debug('........recording heartbeat')
|
||||
logger.debug('........recording heartbeat (%s)', self.worker_status[0])
|
||||
db(sw.worker_name == self.worker_name).update(
|
||||
last_heartbeat=now)
|
||||
elif mybackedstatus == TERMINATE:
|
||||
@@ -758,11 +761,14 @@ class Scheduler(MetaScheduler):
|
||||
self.worker_status[0] = KILL
|
||||
self.die()
|
||||
else:
|
||||
if mybackedstatus == STOP_TASK:
|
||||
logger.info('Asked to kill the current task')
|
||||
self.terminate_process()
|
||||
logger.debug('........recording heartbeat (%s)', self.worker_status[0])
|
||||
db(sw.worker_name == self.worker_name).update(
|
||||
last_heartbeat=now, status=ACTIVE)
|
||||
self.worker_status[1] = 1 # re-activating the process
|
||||
if self.worker_status[0] <> RUNNING:
|
||||
if self.worker_status[0] != RUNNING:
|
||||
self.worker_status[0] = ACTIVE
|
||||
|
||||
self.do_assign_tasks = False
|
||||
@@ -782,13 +788,17 @@ class Scheduler(MetaScheduler):
|
||||
inactive_workers._select(sw.worker_name)))(st.status == RUNNING)\
|
||||
.update(assigned_worker_name='', status=QUEUED)
|
||||
inactive_workers.delete()
|
||||
self.is_a_ticker = self.being_a_ticker()
|
||||
try:
|
||||
self.is_a_ticker = self.being_a_ticker()
|
||||
except:
|
||||
logger.error('Error coordinating TICKER')
|
||||
if self.worker_status[0] == ACTIVE:
|
||||
self.do_assign_tasks = True
|
||||
except:
|
||||
pass
|
||||
logger.error('Error cleaning up')
|
||||
db.commit()
|
||||
except:
|
||||
logger.error('Error retrieving status')
|
||||
db.rollback()
|
||||
self.adj_hibernation()
|
||||
self.sleep()
|
||||
@@ -802,14 +812,16 @@ class Scheduler(MetaScheduler):
|
||||
ticker = all_active.find(lambda row: row.is_ticker is True).first()
|
||||
not_busy = self.worker_status[0] == ACTIVE
|
||||
if not ticker:
|
||||
#if no other tickers are around
|
||||
if not_busy:
|
||||
#only if this worker isn't busy, otherwise wait for a free one
|
||||
#only if I'm not busy
|
||||
db(sw.worker_name == self.worker_name).update(is_ticker=True)
|
||||
db(sw.worker_name != self.worker_name).update(is_ticker=False)
|
||||
logger.info("TICKER: I'm a ticker")
|
||||
else:
|
||||
#giving up, only if I'm not alone
|
||||
if len(all_active) > 1:
|
||||
#I'm busy
|
||||
if len(all_active) >= 1:
|
||||
#so I'll "downgrade" myself to a "poor worker"
|
||||
db(sw.worker_name == self.worker_name).update(is_ticker=False)
|
||||
else:
|
||||
not_busy = True
|
||||
@@ -1007,6 +1019,40 @@ class Scheduler(MetaScheduler):
|
||||
object_hook=_decode_dict) or None
|
||||
return row
|
||||
|
||||
def stop_task(self, ref):
|
||||
"""
|
||||
Experimental!!!
|
||||
Shortcut for task termination.
|
||||
If the task is RUNNING it will terminate it --> execution will be set as FAILED
|
||||
If the task is QUEUED, its stop_time will be set as to "now",
|
||||
the enabled flag will be set to False, status to STOPPED
|
||||
|
||||
:param ref: can be
|
||||
- integer --> lookup will be done by scheduler_task.id
|
||||
- string --> lookup will be done by scheduler_task.uuid
|
||||
Returns:
|
||||
- 1 if task was stopped (meaning an update has been done)
|
||||
- None if task was not found, or if task was not RUNNING or QUEUED
|
||||
"""
|
||||
from gluon.dal import Query
|
||||
st, sw = self.db.scheduler_task, self.db.scheduler_worker
|
||||
if isinstance(ref, int):
|
||||
q = st.id == ref
|
||||
elif isinstance(ref, str):
|
||||
q = st.uuid == ref
|
||||
else:
|
||||
raise SyntaxError(
|
||||
"You can retrieve results only by id or uuid")
|
||||
task = self.db(q).select(st.id, st.status, st.assigned_worker_name).first()
|
||||
rtn = None
|
||||
if not task:
|
||||
return rtn
|
||||
if task.status == 'RUNNING':
|
||||
rtn = self.db(sw.worker_name == task.assigned_worker_name).update(status=STOP_TASK)
|
||||
elif task.status == 'QUEUED':
|
||||
rtn = self.db(q).update(stop_time=self.now(), enabled=False, status=STOPPED)
|
||||
return rtn
|
||||
|
||||
|
||||
def main():
|
||||
"""
|
||||
|
||||
+58
-13
@@ -12,10 +12,10 @@ from languages import lazyT
|
||||
import contrib.rss2 as rss2
|
||||
|
||||
try:
|
||||
import json as json_parser # try stdlib (Python 2.6)
|
||||
import simplejson as json_parser # try external module
|
||||
except ImportError:
|
||||
try:
|
||||
import simplejson as json_parser # try external module
|
||||
import json as json_parser # try stdlib (Python >= 2.6)
|
||||
except:
|
||||
import contrib.simplejson as json_parser # fallback to pure-Python module
|
||||
|
||||
@@ -25,9 +25,52 @@ try:
|
||||
except ImportError:
|
||||
have_yaml = False
|
||||
|
||||
def loads_json(o):
|
||||
def cast_keys(o, cast=str, encoding="utf-8"):
|
||||
""" Builds a new object with <cast> type keys
|
||||
|
||||
Arguments:
|
||||
o is the object input
|
||||
cast (defaults to str) is an object type or function
|
||||
which supports conversion such as:
|
||||
|
||||
>>> converted = cast(o)
|
||||
|
||||
encoding (defaults to utf-8) is the encoding for unicode
|
||||
keys. This is not used for custom cast functions
|
||||
|
||||
Use this funcion if you are in Python < 2.6.5
|
||||
This avoids syntax errors when unpacking dictionary arguments.
|
||||
"""
|
||||
|
||||
if isinstance(o, (dict, Storage)):
|
||||
if isinstance(o, dict):
|
||||
newobj = dict()
|
||||
else:
|
||||
newobj = Storage()
|
||||
|
||||
for k, v in o.items():
|
||||
if (cast == str) and isinstance(k, unicode):
|
||||
key = k.encode(encoding)
|
||||
else:
|
||||
key = cast(k)
|
||||
if isinstance(v, (dict, Storage)):
|
||||
value = cast_keys(v, cast=cast, encoding=encoding)
|
||||
else:
|
||||
value = v
|
||||
newobj[key] = value
|
||||
else:
|
||||
raise TypeError("Cannot cast keys: %s is not supported" % \
|
||||
type(o))
|
||||
return newobj
|
||||
|
||||
def loads_json(o, unicode_keys=True, **kwargs):
|
||||
# deserialize a json string
|
||||
return json_parser.loads(o)
|
||||
result = json_parser.loads(o, **kwargs)
|
||||
if not unicode_keys:
|
||||
# filter non-str keys in dictionary objects
|
||||
result = cast_keys(result,
|
||||
encoding=kwargs.get("encoding", "utf-8"))
|
||||
return result
|
||||
|
||||
def custom_json(o):
|
||||
if hasattr(o, 'custom_json') and callable(o.custom_json):
|
||||
@@ -84,7 +127,8 @@ def csv(value):
|
||||
return ''
|
||||
|
||||
|
||||
def ics(events, title=None, link=None, timeshift=0, **ignored):
|
||||
def ics(events, title=None, link=None, timeshift=0, calname=True,
|
||||
**ignored):
|
||||
import datetime
|
||||
title = title or '(unkown)'
|
||||
if link and not callable(link):
|
||||
@@ -92,7 +136,8 @@ def ics(events, title=None, link=None, timeshift=0, **ignored):
|
||||
'[id]', str(item['id']))
|
||||
s = 'BEGIN:VCALENDAR'
|
||||
s += '\nVERSION:2.0'
|
||||
s += '\nX-WR-CALNAME:%s' % title
|
||||
if not calname is False:
|
||||
s += '\nX-WR-CALNAME:%s' % (calname or title)
|
||||
s += '\nSUMMARY:%s' % title
|
||||
s += '\nPRODID:Generated by web2py'
|
||||
s += '\nCALSCALE:GREGORIAN'
|
||||
@@ -117,18 +162,19 @@ def rss(feed):
|
||||
if not 'entries' in feed and 'items' in feed:
|
||||
feed['entries'] = feed['items']
|
||||
now = datetime.datetime.now()
|
||||
rss = rss2.RSS2(title=str(feed.get('title', '(notitle)')),
|
||||
link=str(feed.get('link', None)),
|
||||
description=str(feed.get('description', '')),
|
||||
rss = rss2.RSS2(title=str(feed.get('title', '(notitle)').encode('utf-8', 'replace')),
|
||||
link=str(feed.get('link', None).encode('utf-8', 'replace')),
|
||||
description=str(feed.get('description', '').encode('utf-8', 'replace')),
|
||||
lastBuildDate=feed.get('created_on', now),
|
||||
items=[rss2.RSSItem(
|
||||
title=str(entry.get('title', '(notitle)')),
|
||||
link=str(entry.get('link', None)),
|
||||
description=str(entry.get('description', '')),
|
||||
title=str(entry.get('title', '(notitle)').encode('utf-8', 'replace')),
|
||||
link=str(entry.get('link', None).encode('utf-8', 'replace')),
|
||||
description=str(entry.get('description', '').encode('utf-8', 'replace')),
|
||||
pubDate=entry.get('created_on', now)
|
||||
) for entry in feed.get('entries', [])])
|
||||
return rss.to_xml(encoding='utf-8')
|
||||
|
||||
|
||||
def yaml(data):
|
||||
if have_yaml:
|
||||
return yamlib.dump(data)
|
||||
@@ -138,4 +184,3 @@ def loads_yaml(data):
|
||||
if have_yaml:
|
||||
return yamlib.load(data)
|
||||
else: raise ImportError("No YAML serializer available")
|
||||
|
||||
|
||||
+203
-86
@@ -18,9 +18,11 @@ try:
|
||||
except ImportError:
|
||||
from cgi import parse_qs as psq
|
||||
import os
|
||||
import copy
|
||||
from http import HTTP
|
||||
from html import XmlComponent
|
||||
from html import XML, SPAN, TAG, A, DIV, CAT, UL, LI, TEXTAREA, BR, IMG, SCRIPT
|
||||
from html import FORM, INPUT, LABEL, OPTION, SELECT, BUTTON
|
||||
from html import FORM, INPUT, LABEL, OPTION, SELECT
|
||||
from html import TABLE, THEAD, TBODY, TR, TD, TH, STYLE
|
||||
from html import URL, truncate_string, FIELDSET
|
||||
from dal import DAL, Field, Table, Row, CALLABLETYPES, smart_query, \
|
||||
@@ -35,7 +37,7 @@ import datetime
|
||||
import urllib
|
||||
import re
|
||||
import cStringIO
|
||||
from gluon import current, redirect, A, URL, DIV, H3, UL, LI, SPAN, INPUT
|
||||
from gluon import current, redirect
|
||||
import inspect
|
||||
import settings
|
||||
is_gae = settings.global_settings.web2py_runtime_gae
|
||||
@@ -80,6 +82,27 @@ def safe_float(x):
|
||||
return 0
|
||||
|
||||
|
||||
def show_if(cond):
|
||||
if not cond:
|
||||
return None
|
||||
base = "%s_%s" % (cond.first.tablename, cond.first.name)
|
||||
if ((cond.op.__name__ == 'EQ' and cond.second == True) or
|
||||
(cond.op.__name__ == 'NE' and cond.second == False)):
|
||||
return base,":checked"
|
||||
if ((cond.op.__name__ == 'EQ' and cond.second == False) or
|
||||
(cond.op.__name__ == 'NE' and cond.second == True)):
|
||||
return base,":not(:checked)"
|
||||
if cond.op.__name__ == 'EQ':
|
||||
return base,"[value='%s']" % cond.second
|
||||
if cond.op.__name__ == 'NE':
|
||||
return base,"[value!='%s']" % cond.second
|
||||
if cond.op.__name__ == 'CONTAINS':
|
||||
return base,"[value~='%s']" % cond.second
|
||||
if cond.op.__name__ == 'BELONGS' and isinstance(cond.second,(list,tuple)):
|
||||
return base,','.join("[value='%s']" % (v) for v in cond.second)
|
||||
raise RuntimeError("Not Implemented Error")
|
||||
|
||||
|
||||
class FormWidget(object):
|
||||
"""
|
||||
helper for SQLFORM to generate form input fields
|
||||
@@ -100,12 +123,16 @@ class FormWidget(object):
|
||||
:param attributes: any other supplied attributes
|
||||
"""
|
||||
attr = dict(
|
||||
_id='%s_%s' % (field._tablename, field.name),
|
||||
_id='%s_%s' % (field.tablename, field.name),
|
||||
_class=cls._class or
|
||||
widget_class.match(str(field.type)).group(),
|
||||
_name=field.name,
|
||||
_name=field.name,
|
||||
requires=field.requires,
|
||||
)
|
||||
if getattr(field,'show_if',None):
|
||||
trigger, cond = show_if(field.show_if)
|
||||
attr['_data-show-trigger'] = trigger
|
||||
attr['_data-show-if'] = cond
|
||||
attr.update(widget_attributes)
|
||||
attr.update(attributes)
|
||||
return attr
|
||||
@@ -260,7 +287,7 @@ class ListWidget(StringWidget):
|
||||
|
||||
@classmethod
|
||||
def widget(cls, field, value, **attributes):
|
||||
_id = '%s_%s' % (field._tablename, field.name)
|
||||
_id = '%s_%s' % (field.tablename, field.name)
|
||||
_name = field.name
|
||||
if field.type == 'list:integer':
|
||||
_class = 'integer'
|
||||
@@ -349,6 +376,12 @@ class RadioWidget(OptionsWidget):
|
||||
see also: :meth:`FormWidget.widget`
|
||||
"""
|
||||
|
||||
if isinstance(value, (list,tuple)):
|
||||
value = str(value[0])
|
||||
else:
|
||||
value = str(value)
|
||||
|
||||
|
||||
attr = cls._attributes(field, {}, **attributes)
|
||||
attr['_class'] = attr.get('_class', 'web2py_radiowidget')
|
||||
|
||||
@@ -618,7 +651,8 @@ class AutocompleteWidget(object):
|
||||
self.help_fields = help_fields or []
|
||||
self.help_string = help_string
|
||||
if self.help_fields and not self.help_string:
|
||||
self.help_string = ' '.join('%%(%s)s' for f in self.help_fields)
|
||||
self.help_string = ' '.join('%%(%s)s'%f.name
|
||||
for f in self.help_fields)
|
||||
|
||||
self.request = request
|
||||
self.keyword = keyword % dict(tablename=field.tablename,
|
||||
@@ -644,9 +678,9 @@ class AutocompleteWidget(object):
|
||||
if self.keyword in self.request.vars:
|
||||
field = self.fields[0]
|
||||
if is_gae:
|
||||
rows = self.db(field.__ge__(self.request.vars[self.keyword]) & field.__lt__(self.request.vars[self.keyword] + u'\ufffd')).select(orderby=self.orderby, limitby=self.limitby, *self.fields)
|
||||
rows = self.db(field.__ge__(self.request.vars[self.keyword]) & field.__lt__(self.request.vars[self.keyword] + u'\ufffd')).select(orderby=self.orderby, limitby=self.limitby, *(self.fields+self.help_field))
|
||||
else:
|
||||
rows = self.db(field.like(self.request.vars[self.keyword] + '%')).select(orderby=self.orderby, limitby=self.limitby, distinct=self.distinct, *self.fields)
|
||||
rows = self.db(field.like(self.request.vars[self.keyword] + '%')).select(orderby=self.orderby, limitby=self.limitby, distinct=self.distinct, *(self.fields+self.help_field))
|
||||
if rows:
|
||||
if self.is_reference:
|
||||
id_field = self.fields[1]
|
||||
@@ -1066,7 +1100,7 @@ class SQLFORM(FORM):
|
||||
cond = readonly or \
|
||||
(not ignore_rw and not field.writable and field.readable)
|
||||
|
||||
if default and not cond:
|
||||
if default is not None and not cond:
|
||||
default = field.formatter(default)
|
||||
dspval = default
|
||||
inpval = default
|
||||
@@ -1174,9 +1208,10 @@ class SQLFORM(FORM):
|
||||
xfields.append(
|
||||
(self.FIELDKEY_DELETE_RECORD + SQLFORM.ID_ROW_SUFFIX,
|
||||
LABEL(
|
||||
delete_label, separator,
|
||||
_for=self.FIELDKEY_DELETE_RECORD,
|
||||
_id=self.FIELDKEY_DELETE_RECORD + SQLFORM.ID_LABEL_SUFFIX),
|
||||
T(delete_label), separator,
|
||||
_for=self.FIELDKEY_DELETE_RECORD,
|
||||
_id=self.FIELDKEY_DELETE_RECORD + \
|
||||
SQLFORM.ID_LABEL_SUFFIX),
|
||||
widget,
|
||||
col3.get(self.FIELDKEY_DELETE_RECORD, '')))
|
||||
self.custom.delete = self.custom.deletable = widget
|
||||
@@ -1223,7 +1258,8 @@ class SQLFORM(FORM):
|
||||
table = TABLE()
|
||||
for id, a, b, c in xfields:
|
||||
newrows = formstyle(id, a, b, c)
|
||||
self.field_parent[id] = getattr(b, 'parent', None)
|
||||
self.field_parent[id] = getattr(b, 'parent', None) \
|
||||
if isinstance(b,XmlComponent) else None
|
||||
if type(newrows).__name__ != "tuple":
|
||||
newrows = [newrows]
|
||||
for newrow in newrows:
|
||||
@@ -1231,7 +1267,8 @@ class SQLFORM(FORM):
|
||||
else:
|
||||
table = formstyle(self, xfields)
|
||||
for id, a, b, c in xfields:
|
||||
self.field_parent[id] = getattr(b, 'parent', None)
|
||||
self.field_parent[id] = getattr(b, 'parent', None) \
|
||||
if isinstance(b,XmlComponent) else None
|
||||
else:
|
||||
raise RuntimeError('formstyle not supported')
|
||||
return table
|
||||
@@ -1440,13 +1477,15 @@ class SQLFORM(FORM):
|
||||
f = self.table[fieldname].default or ''
|
||||
fields[fieldname] = f
|
||||
else:
|
||||
fields[fieldname] = ''
|
||||
f = self.table[fieldname].default or ''
|
||||
fields[fieldname] = f
|
||||
self.vars[fieldname] = fields[fieldname]
|
||||
if not f:
|
||||
continue
|
||||
else:
|
||||
f = os.path.join(current.request.folder,
|
||||
os.path.normpath(f))
|
||||
f = os.path.join(
|
||||
current.request.folder,
|
||||
os.path.normpath(f))
|
||||
source_file = open(f, 'rb')
|
||||
original_filename = os.path.split(f)[1]
|
||||
elif hasattr(f, 'file'):
|
||||
@@ -1455,6 +1494,10 @@ class SQLFORM(FORM):
|
||||
### do not know why this happens, it should not
|
||||
(source_file, original_filename) = \
|
||||
(cStringIO.StringIO(f), 'file.txt')
|
||||
else:
|
||||
# this should never happen, why does it happen?
|
||||
print 'f=',repr(f)
|
||||
continue
|
||||
newfilename = field.store(source_file, original_filename,
|
||||
field.uploadfolder)
|
||||
# this line was for backward compatibility but problematic
|
||||
@@ -1580,7 +1623,7 @@ class SQLFORM(FORM):
|
||||
|
||||
table_name = attributes.get('table_name', 'no_table')
|
||||
|
||||
# So it won't interfear with SQLDB.define_table
|
||||
# So it won't interfere with SQLDB.define_table
|
||||
if 'table_name' in attributes:
|
||||
del attributes['table_name']
|
||||
|
||||
@@ -1637,7 +1680,14 @@ class SQLFORM(FORM):
|
||||
selectfields = []
|
||||
for field in fields:
|
||||
name = str(field).replace('.', '-')
|
||||
options = search_options.get(field.type.split(' ')[0], None)
|
||||
# treat ftype 'decimal' as 'double'
|
||||
# (this fixes problems but needs refactoring!
|
||||
ftype = field.type.split(' ')[0]
|
||||
if ftype.startswith('decimal'): ftype = 'double'
|
||||
elif ftype=='bigint': ftype = 'integer'
|
||||
elif ftype.startswith('big-'): ftype = ftype[4:]
|
||||
# end
|
||||
options = search_options.get(ftype, None)
|
||||
if options:
|
||||
label = isinstance(
|
||||
field.label, str) and T(field.label) or field.label
|
||||
@@ -1717,6 +1767,7 @@ class SQLFORM(FORM):
|
||||
return CAT(
|
||||
DIV(_id=panel_id, _style="display:none;", *criteria), fadd)
|
||||
|
||||
|
||||
@staticmethod
|
||||
def grid(query,
|
||||
fields=None,
|
||||
@@ -1759,9 +1810,12 @@ class SQLFORM(FORM):
|
||||
createargs={},
|
||||
editargs={},
|
||||
viewargs={},
|
||||
selectable_submit_button='Submit',
|
||||
buttons_placement = 'right',
|
||||
links_placement = 'right',
|
||||
noconfirm=False
|
||||
noconfirm=False,
|
||||
cache_count=None,
|
||||
client_side_delete=False,
|
||||
):
|
||||
|
||||
# jQuery UI ThemeRoller classes (empty if ui is disabled)
|
||||
@@ -1814,6 +1868,33 @@ class SQLFORM(FORM):
|
||||
create = wenabled and create
|
||||
editable = wenabled and editable
|
||||
deletable = wenabled and deletable
|
||||
rows = None
|
||||
|
||||
def fetch_count(dbset):
|
||||
##FIXME for google:datastore cache_count is ignored
|
||||
## if it's not an integer
|
||||
if cache_count is None or isinstance(cache_count, tuple):
|
||||
if groupby:
|
||||
c = 'count(*)'
|
||||
nrows = db.executesql(
|
||||
'select count(*) from (%s);' %
|
||||
dbset._select(c, left=left, cacheable=True,
|
||||
groupby=groupby, cache=cache_count)[:-1])[0][0]
|
||||
elif left:
|
||||
c = 'count(*)'
|
||||
nrows = dbset.select(c, left=left, cacheable=True, cache=cache_count).first()[c]
|
||||
elif dbset._db._adapter.dbengine=='google:datastore':
|
||||
#if we don't set a limit, this can timeout for a large table
|
||||
nrows = dbset.db._adapter.count(dbset.query, limit=1000)
|
||||
else:
|
||||
nrows = dbset.count(cache=cache_count)
|
||||
elif isinstance(cache_count, (int, long)):
|
||||
nrows = cache_count
|
||||
elif callable(cache_count):
|
||||
nrows = cache_count(dbset, request.vars)
|
||||
else:
|
||||
nrows = 0
|
||||
return nrows
|
||||
|
||||
def url(**b):
|
||||
b['args'] = args + b.get('args', [])
|
||||
@@ -1853,7 +1934,7 @@ class SQLFORM(FORM):
|
||||
delete=None, trap=True, noconfirm=None):
|
||||
if showbuttontext:
|
||||
return A(SPAN(_class=ui.get(buttonclass)),
|
||||
SPAN(T(buttontext), _title=buttontext,
|
||||
SPAN(T(buttontext), _title=T(buttontext),
|
||||
_class=ui.get('buttontext')),
|
||||
_href=buttonurl,
|
||||
callback=callback,
|
||||
@@ -1866,7 +1947,7 @@ class SQLFORM(FORM):
|
||||
callback=callback,
|
||||
delete=delete,
|
||||
noconfirm=noconfirm,
|
||||
_title=buttontext,
|
||||
_title=T(buttontext),
|
||||
_class=trap_class(ui.get('buttontext'), trap))
|
||||
|
||||
dbset = db(query)
|
||||
@@ -1877,21 +1958,27 @@ class SQLFORM(FORM):
|
||||
for join in left:
|
||||
tablenames += db._adapter.tables(join)
|
||||
tables = [db[tablename] for tablename in tablenames]
|
||||
if not fields:
|
||||
fields = reduce(lambda a, b: a + b,
|
||||
[[field for field in table] for table in tables])
|
||||
if fields:
|
||||
columns = copy.copy(fields)
|
||||
else:
|
||||
fields = []
|
||||
columns = []
|
||||
for table in tables:
|
||||
fields += [f for f in table]
|
||||
columns += [f for f in table]
|
||||
for k,f in table.iteritems():
|
||||
if isinstance(f,Field.Virtual) and f.readable:
|
||||
f.tablename = table._tablename
|
||||
columns.append(f)
|
||||
if not field_id:
|
||||
field_id = tables[0]._id
|
||||
columns = [str(field) for field in fields
|
||||
if field._tablename in tablenames]
|
||||
|
||||
if not any(str(f)==str(field_id) for f in fields):
|
||||
fields = [f for f in fields]+[field_id]
|
||||
table = field_id.table
|
||||
tablename = table._tablename
|
||||
if upload == '<default>':
|
||||
upload = lambda filename: url(args=['download', filename])
|
||||
if len(request.args) > 1 and request.args[-2] == 'download':
|
||||
if request.args(-2) == 'download':
|
||||
stream = response.download(request, db)
|
||||
raise HTTP(200, stream, **response.headers)
|
||||
|
||||
@@ -1928,7 +2015,7 @@ class SQLFORM(FORM):
|
||||
create_form = update_form = view_form = search_form = None
|
||||
sqlformargs = dict(formargs)
|
||||
|
||||
if create and len(request.args) > 1 and request.args[-2] == 'new':
|
||||
if create and request.args(-2) == 'new':
|
||||
table = db[request.args[-1]]
|
||||
sqlformargs.update(createargs)
|
||||
create_form = SQLFORM(
|
||||
@@ -1945,9 +2032,10 @@ class SQLFORM(FORM):
|
||||
res.update_form = update_form
|
||||
res.view_form = view_form
|
||||
res.search_form = search_form
|
||||
res.rows = None
|
||||
return res
|
||||
|
||||
elif details and len(request.args) > 2 and request.args[-3] == 'view':
|
||||
elif details and request.args(-3) == 'view':
|
||||
table = db[request.args[-2]]
|
||||
record = table(request.args[-1]) or redirect(referrer)
|
||||
sqlformargs.update(viewargs)
|
||||
@@ -1961,15 +2049,17 @@ class SQLFORM(FORM):
|
||||
res.update_form = update_form
|
||||
res.view_form = view_form
|
||||
res.search_form = search_form
|
||||
res.rows = None
|
||||
return res
|
||||
elif editable and len(request.args) > 2 and request.args[-3] == 'edit':
|
||||
elif editable and request.args(-3) == 'edit':
|
||||
table = db[request.args[-2]]
|
||||
record = table(request.args[-1]) or redirect(URL('error'))
|
||||
sqlformargs.update(editargs)
|
||||
deletable_ = deletable(record) if callable(deletable) else deletable
|
||||
update_form = SQLFORM(
|
||||
table,
|
||||
record, upload=upload, ignore_rw=ignore_rw,
|
||||
formstyle=formstyle, deletable=deletable,
|
||||
formstyle=formstyle, deletable=deletable_,
|
||||
_class='web2py_form',
|
||||
submit_button=T('Submit'),
|
||||
delete_label=T('Check to delete'),
|
||||
@@ -1986,13 +2076,21 @@ class SQLFORM(FORM):
|
||||
res.update_form = update_form
|
||||
res.view_form = view_form
|
||||
res.search_form = search_form
|
||||
res.rows = None
|
||||
return res
|
||||
elif deletable and len(request.args) > 2 and request.args[-3] == 'delete':
|
||||
elif deletable and request.args(-3) == 'delete':
|
||||
table = db[request.args[-2]]
|
||||
if ondelete:
|
||||
ondelete(table, request.args[-1])
|
||||
db(table[table._id.name] == request.args[-1]).delete()
|
||||
redirect(referrer)
|
||||
if not callable(deletable):
|
||||
if ondelete:
|
||||
ondelete(table, request.args[-1])
|
||||
db(table[table._id.name] == request.args[-1]).delete()
|
||||
else:
|
||||
record = table(request.args[-1]) or redirect(URL('error'))
|
||||
if deletable(record):
|
||||
if ondelete:
|
||||
ondelete(table, request.args[-1])
|
||||
record.delete_record()
|
||||
redirect(referrer, client_side=client_side_delete)
|
||||
|
||||
exportManager = dict(
|
||||
csv_with_hidden_cols=(ExporterCSV, 'CSV (hidden cols)'),
|
||||
@@ -2023,12 +2121,12 @@ class SQLFORM(FORM):
|
||||
if sign == '~':
|
||||
orderby = ~orderby
|
||||
|
||||
expcolumns = columns
|
||||
expcolumns = [str(f) for f in columns]
|
||||
if export_type.endswith('with_hidden_cols'):
|
||||
expcolumns = []
|
||||
for table in tables:
|
||||
for field in table:
|
||||
if field.readable and field._tablename in tablenames:
|
||||
if field.readable and field.tablename in tablenames:
|
||||
expcolumns.append(field)
|
||||
|
||||
if export_type in exportManager and exportManager[export_type]:
|
||||
@@ -2043,7 +2141,7 @@ class SQLFORM(FORM):
|
||||
else:
|
||||
rows = dbset.select(left=left, orderby=orderby,
|
||||
cacheable=True, *expcolumns)
|
||||
|
||||
|
||||
value = exportManager[export_type]
|
||||
clazz = value[0] if hasattr(value, '__getitem__') else value
|
||||
oExp = clazz(rows)
|
||||
@@ -2110,15 +2208,7 @@ class SQLFORM(FORM):
|
||||
if subquery:
|
||||
dbset = dbset(subquery)
|
||||
try:
|
||||
if left or groupby:
|
||||
c = 'count(*)'
|
||||
nrows = dbset.select(c, left=left, cacheable=True,
|
||||
groupby=groupby).first()[c]
|
||||
elif dbset._db._adapter.dbengine=='google:datastore':
|
||||
#if we don't set a limit, this can timeout for a large table
|
||||
nrows = dbset.db._adapter.count(dbset.query, limit=1000)
|
||||
else:
|
||||
nrows = dbset.count()
|
||||
nrows = fetch_count(dbset)
|
||||
except:
|
||||
nrows = 0
|
||||
error = T('Unsupported query')
|
||||
@@ -2137,9 +2227,7 @@ class SQLFORM(FORM):
|
||||
headcols = []
|
||||
if selectable:
|
||||
headcols.append(TH(_class=ui.get('default')))
|
||||
for field in fields:
|
||||
if columns and not str(field) in columns:
|
||||
continue
|
||||
for field in columns:
|
||||
if not field.readable:
|
||||
continue
|
||||
key = str(field)
|
||||
@@ -2193,7 +2281,7 @@ class SQLFORM(FORM):
|
||||
limitby = None
|
||||
|
||||
try:
|
||||
table_fields = [f for f in fields if f._tablename in tablenames]
|
||||
table_fields = [f for f in fields if f.tablename in tablenames]
|
||||
if dbset._db._adapter.dbengine=='google:datastore':
|
||||
rows = dbset.select(left=left,orderby=orderby,
|
||||
groupby=groupby,limitby=limitby,
|
||||
@@ -2219,7 +2307,7 @@ class SQLFORM(FORM):
|
||||
message = T('at least %(nrows)s records found') % dict(nrows=nrows)
|
||||
else:
|
||||
message = T('%(nrows)s records found') % dict(nrows=nrows)
|
||||
console.append(DIV(message,_class='web2py_counter'))
|
||||
console.append(DIV(message or T('None'),_class='web2py_counter'))
|
||||
|
||||
paginator = UL()
|
||||
if paginate and dbset._db._adapter.dbengine=='google:datastore':
|
||||
@@ -2281,14 +2369,12 @@ class SQLFORM(FORM):
|
||||
trcols.append(
|
||||
INPUT(_type="checkbox", _name="records", _value=id,
|
||||
value=request.vars.records))
|
||||
for field in fields:
|
||||
if not str(field) in columns:
|
||||
continue
|
||||
for field in columns:
|
||||
if not field.readable:
|
||||
continue
|
||||
if field.type == 'blob':
|
||||
continue
|
||||
value = row[field]
|
||||
value = row[str(field)]
|
||||
maxlength = maxtextlengths.get(str(field), maxtextlength)
|
||||
if field.represent:
|
||||
try:
|
||||
@@ -2296,7 +2382,7 @@ class SQLFORM(FORM):
|
||||
except KeyError:
|
||||
try:
|
||||
value = field.represent(
|
||||
value, row[field._tablename])
|
||||
value, row[field.tablename])
|
||||
except KeyError:
|
||||
pass
|
||||
elif field.type == 'boolean':
|
||||
@@ -2306,9 +2392,9 @@ class SQLFORM(FORM):
|
||||
if value:
|
||||
if callable(upload):
|
||||
value = A(
|
||||
current.T('file'), _href=upload(value))
|
||||
T('file'), _href=upload(value))
|
||||
elif upload:
|
||||
value = A(current.T('file'),
|
||||
value = A(T('file'),
|
||||
_href='%s/%s' % (upload, value))
|
||||
else:
|
||||
value = ''
|
||||
@@ -2367,9 +2453,12 @@ class SQLFORM(FORM):
|
||||
tr = TR(*trcols, **dict(_class=classtr))
|
||||
tbody.append(tr)
|
||||
htmltable.append(tbody)
|
||||
htmltable = DIV(htmltable, _style='width:100%;overflow-x:auto')
|
||||
htmltable = DIV(
|
||||
htmltable, _class='web2py_htmltable',
|
||||
_style='width:100%;overflow-x:auto;-ms-overflow-x:scroll')
|
||||
if selectable:
|
||||
htmltable = FORM(htmltable, INPUT(_type="submit"))
|
||||
htmltable = FORM(htmltable, INPUT(
|
||||
_type="submit", _value=T(selectable_submit_button)))
|
||||
if htmltable.process(formname=formname).accepted:
|
||||
htmltable.vars.records = htmltable.vars.records or []
|
||||
htmltable.vars.records = htmltable.vars.records if type(htmltable.vars.records) == list else [htmltable.vars.records]
|
||||
@@ -2377,7 +2466,7 @@ class SQLFORM(FORM):
|
||||
selectable(records)
|
||||
redirect(referrer)
|
||||
else:
|
||||
htmltable = DIV(current.T('No records found'))
|
||||
htmltable = DIV(T('No records found'))
|
||||
|
||||
if csv and nrows:
|
||||
export_links = []
|
||||
@@ -2407,6 +2496,7 @@ class SQLFORM(FORM):
|
||||
res.update_form = update_form
|
||||
res.view_form = view_form
|
||||
res.search_form = search_form
|
||||
res.rows = rows
|
||||
return res
|
||||
|
||||
@staticmethod
|
||||
@@ -2466,7 +2556,7 @@ class SQLFORM(FORM):
|
||||
name = None
|
||||
def format(table,row):
|
||||
if not row:
|
||||
return 'Unknown'
|
||||
return T('Unknown')
|
||||
elif isinstance(table._format,str):
|
||||
return table._format % row
|
||||
elif callable(table._format):
|
||||
@@ -2517,8 +2607,9 @@ class SQLFORM(FORM):
|
||||
break
|
||||
if nargs > len(args) + 1:
|
||||
query = (field == id)
|
||||
if isinstance(linked_tables, dict):
|
||||
linked_tables = linked_tables.get(table._tablename, [])
|
||||
# cjk
|
||||
# if isinstance(linked_tables, dict):
|
||||
# linked_tables = linked_tables.get(table._tablename, [])
|
||||
if linked_tables is None or referee in linked_tables:
|
||||
field.represent = lambda id, r=None, referee=referee, rep=field.represent: A(callable(rep) and rep(id) or id, _class=trap_class(), _href=url(args=['view', referee, id]))
|
||||
except (KeyError, ValueError, TypeError):
|
||||
@@ -2543,20 +2634,45 @@ class SQLFORM(FORM):
|
||||
check[rfield.tablename] = \
|
||||
check.get(rfield.tablename, []) + [rfield.name]
|
||||
if isinstance(linked_tables, dict):
|
||||
linked_tables = linked_tables.get(table._tablename, [])
|
||||
for tablename in sorted(check):
|
||||
linked_fieldnames = check[tablename]
|
||||
tb = db[tablename]
|
||||
multiple_links = len(linked_fieldnames) > 1
|
||||
for fieldname in linked_fieldnames:
|
||||
if linked_tables is None or tablename in linked_tables:
|
||||
t = T(tb._plural) if not multiple_links else \
|
||||
T(tb._plural + '(' + fieldname + ')')
|
||||
args0 = tablename + '.' + fieldname
|
||||
for tbl in linked_tables.keys():
|
||||
tb = db[tbl]
|
||||
if isinstance(linked_tables[tbl], list):
|
||||
if len(linked_tables[tbl]) > 1:
|
||||
t = T('%s(%s)' %(tbl, fld))
|
||||
else:
|
||||
t = T(tb._plural)
|
||||
for fld in linked_tables[tbl]:
|
||||
if fld not in db[tbl].fields:
|
||||
raise ValueError('Field %s not in table' %fld)
|
||||
args0 = tbl + '.' + fld
|
||||
links.append(
|
||||
lambda row, t=t, nargs=nargs, args0=args0:
|
||||
A(SPAN(t), _class=trap_class(), _href=url(
|
||||
args=[args0, row[id_field_name]])))
|
||||
else:
|
||||
t = T(tb._plural)
|
||||
fld = linked_tables[tbl]
|
||||
if fld not in db[tbl].fields:
|
||||
raise ValueError('Field %s not in table' %fld)
|
||||
args0 = tbl + '.' + fld
|
||||
links.append(
|
||||
lambda row, t=t, nargs=nargs, args0=args0:
|
||||
A(SPAN(t), _class=trap_class(), _href=url(
|
||||
args=[args0, row[id_field_name]])))
|
||||
else:
|
||||
for tablename in sorted(check):
|
||||
linked_fieldnames = check[tablename]
|
||||
tb = db[tablename]
|
||||
multiple_links = len(linked_fieldnames) > 1
|
||||
for fieldname in linked_fieldnames:
|
||||
if linked_tables is None or tablename in linked_tables:
|
||||
t = T(tb._plural) if not multiple_links else \
|
||||
T(tb._plural + '(' + fieldname + ')')
|
||||
args0 = tablename + '.' + fieldname
|
||||
links.append(
|
||||
lambda row, t=t, nargs=nargs, args0=args0:
|
||||
A(SPAN(t), _class=trap_class(), _href=url(
|
||||
args=[args0, row[id_field_name]])))
|
||||
|
||||
grid = SQLFORM.grid(query, args=request.args[:nargs], links=links,
|
||||
links_in_grid=links_in_grid,
|
||||
@@ -2566,18 +2682,18 @@ class SQLFORM(FORM):
|
||||
header = table._plural
|
||||
next = grid.create_form or grid.update_form or grid.view_form
|
||||
breadcrumbs.append(LI(
|
||||
A(T(header), _class=trap_class(),_href=url()),
|
||||
A(T(header), _class=trap_class(),_href=url()),
|
||||
SPAN(divider, _class='divider') if next else '',
|
||||
_class='active w2p_grid_breadcrumb_elem'))
|
||||
if grid.create_form:
|
||||
header = T('New %s' % table._singular)
|
||||
header = T('New %(entity)s') % dict(entity=table._singular)
|
||||
elif grid.update_form:
|
||||
header = T('Edit %s' % format(table,grid.update_form.record))
|
||||
header = T('Edit %(entity)s') % dict(entity=format(table,grid.update_form.record))
|
||||
elif grid.view_form:
|
||||
header = T('View %s' % format(table,grid.view_form.record))
|
||||
header = T('View %(entity)s') % dict(entity=format(table,grid.view_form.record))
|
||||
if next:
|
||||
breadcrumbs.append(LI(
|
||||
A(T(header), _class=trap_class(),_href=url()),
|
||||
A(T(header), _class=trap_class(),_href=url()),
|
||||
_class='active w2p_grid_breadcrumb_elem'))
|
||||
grid.insert(
|
||||
0, DIV(UL(*breadcrumbs, **{'_class': breadcrumbs_class}),
|
||||
@@ -2634,7 +2750,7 @@ class SQLTABLE(TABLE):
|
||||
:param selectid: The id you want to select
|
||||
:param renderstyle: Boolean render the style with the table
|
||||
|
||||
:param extracolums = [{'label':A('Extra',_href='#'),
|
||||
:param extracolumns = [{'label':A('Extra',_href='#'),
|
||||
'class': '', #class name of the header
|
||||
'width':'', #width in pixels or %
|
||||
'content':lambda row, rc: A('Edit',_href='edit/%s'%row.id),
|
||||
@@ -2656,8 +2772,8 @@ class SQLTABLE(TABLE):
|
||||
},
|
||||
}
|
||||
|
||||
table = SQLTABLE(rows, headers=headers, extracolums=extracolums)
|
||||
|
||||
table = SQLTABLE(rows, headers=headers, extracolumns=extracolumns)
|
||||
`<
|
||||
|
||||
"""
|
||||
|
||||
@@ -3016,3 +3132,4 @@ class ExporterJSON(ExportClass):
|
||||
return self.rows.as_json()
|
||||
else:
|
||||
return 'null'
|
||||
|
||||
|
||||
+5
-2
@@ -18,6 +18,7 @@ import portalocker
|
||||
__all__ = ['List', 'Storage', 'Settings', 'Messages',
|
||||
'StorageList', 'load_storage', 'save_storage']
|
||||
|
||||
DEFAULT = lambda:0
|
||||
|
||||
class Storage(dict):
|
||||
"""
|
||||
@@ -250,7 +251,7 @@ class List(list):
|
||||
instead of IndexOutOfBounds
|
||||
"""
|
||||
|
||||
def __call__(self, i, default=None, cast=None, otherwise=None):
|
||||
def __call__(self, i, default=DEFAULT, cast=None, otherwise=None):
|
||||
"""
|
||||
request.args(0,default=0,cast=int,otherwise='http://error_url')
|
||||
request.args(0,default=0,cast=int,otherwise=lambda:...)
|
||||
@@ -258,8 +259,10 @@ class List(list):
|
||||
n = len(self)
|
||||
if 0 <= i < n or -n <= i < 0:
|
||||
value = self[i]
|
||||
elif default is DEFAULT:
|
||||
value = None
|
||||
else:
|
||||
value = default
|
||||
value, cast = default, False
|
||||
if cast:
|
||||
try:
|
||||
value = cast(value)
|
||||
|
||||
+5
-4
@@ -562,8 +562,8 @@ class TemplateParser(object):
|
||||
if in_tag:
|
||||
line = i
|
||||
|
||||
# Get rid of '{{' and '}}'
|
||||
line = line[2:-2].strip()
|
||||
# Get rid of delimiters
|
||||
line = line[len(self.delimiters[0]):-len(self.delimiters[1])].strip()
|
||||
|
||||
# This is bad juju, but let's do it anyway
|
||||
if not line:
|
||||
@@ -832,7 +832,8 @@ def render(content="hello world",
|
||||
path=None,
|
||||
context={},
|
||||
lexers={},
|
||||
delimiters=('{{', '}}')
|
||||
delimiters=('{{', '}}'),
|
||||
writer='response.write'
|
||||
):
|
||||
"""
|
||||
>>> render()
|
||||
@@ -895,7 +896,7 @@ def render(content="hello world",
|
||||
|
||||
# Execute the template.
|
||||
code = str(TemplateParser(stream.read(
|
||||
), context=context, path=path, lexers=lexers, delimiters=delimiters))
|
||||
), context=context, path=path, lexers=lexers, delimiters=delimiters, writer=writer))
|
||||
try:
|
||||
exec(code) in context
|
||||
except Exception:
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
from test_http import *
|
||||
from test_cache import *
|
||||
from test_dal import *
|
||||
from test_html import *
|
||||
@@ -9,5 +10,8 @@ from test_storage import *
|
||||
from test_template import *
|
||||
from test_utils import *
|
||||
from test_contribs import *
|
||||
from test_markmin import *
|
||||
# from test_web import *
|
||||
from test_web import *
|
||||
|
||||
import sys
|
||||
if sys.version[:3] == '2.7':
|
||||
from test_old_doctests import *
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
[run]
|
||||
branch = True
|
||||
parallel = True
|
||||
source = gluon
|
||||
## remove comment if you want applications coverage too
|
||||
#source = gluon, applications
|
||||
|
||||
[report]
|
||||
# Regexes for lines to exclude from consideration
|
||||
exclude_lines =
|
||||
# Have to re-enable the standard pragma
|
||||
pragma: no cover
|
||||
|
||||
# Don't complain about missing debug-only code:
|
||||
def __repr__
|
||||
if self\.debug
|
||||
|
||||
# Don't complain if tests don't hit defensive assertion code:
|
||||
raise AssertionError
|
||||
raise NotImplementedError
|
||||
|
||||
# Don't complain if non-runnable code isn't run:
|
||||
if 0:
|
||||
if __name__ == .__main__.:
|
||||
|
||||
ignore_errors = True
|
||||
omit = gluon/contrib/*
|
||||
|
||||
[html]
|
||||
directory = coverage_html_report
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user