Compare commits
158 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| aca3d43f0a | |||
| 5a898cc80a | |||
| bfb3a320bd | |||
| c0b1e387b1 | |||
| c175e6340d | |||
| 3a5f7b05df | |||
| 26babd7e96 | |||
| 349088a96e | |||
| a4ff77bdb9 | |||
| 8f70d3a802 | |||
| 89021b6409 | |||
| 4a078705b3 | |||
| 6eea834777 | |||
| 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 | |||
| f13aed1a84 | |||
| cb3de825f2 | |||
| fd4c775710 | |||
| 3e550b3e97 | |||
| 7a543250f9 | |||
| a071f07634 | |||
| a078f860d2 | |||
| 2bfd7a2467 | |||
| 55c9392de4 | |||
| 7991b555ff | |||
| eab7815c24 | |||
| 79c09de103 | |||
| 24daa335b6 | |||
| 812ba9d52b | |||
| 00fb3b56cc | |||
| 3644d081f6 | |||
| f05c46b3f1 | |||
| 13e76fe278 | |||
| 0906ae28c1 | |||
| 04905adb89 | |||
| 9767109d4e | |||
| a57919bc4d | |||
| c7c94d1f8f | |||
| 817e6c3313 | |||
| a23f4c5c88 | |||
| eac9768549 | |||
| a42fb6b558 | |||
| 879e825b61 | |||
| 07f4310153 | |||
| 10c67e5be3 | |||
| 1279d5ddaa | |||
| 2af15e4b27 | |||
| 3096fcf045 | |||
| 831492448a | |||
| a5284e846c | |||
| 22accaced3 | |||
| f92d97f36e | |||
| 4f0a16a24c | |||
| 72dade793a | |||
| 8addc54015 | |||
| 25ab6f9a07 | |||
| b853f72e0c | |||
| 449a658521 | |||
| 7776a22533 | |||
| 554eccc14a | |||
| 8cd6928da3 | |||
| 8c28be1041 | |||
| 810aa8f4f3 | |||
| 8e5be952bf | |||
| 5a560fee8a | |||
| 21819ffc5d | |||
| 1f8bdd6061 | |||
| 523c813439 | |||
| 7ee638bc36 | |||
| 76c515d3af | |||
| 1c8ce00657 | |||
| 0f4bbecd2a | |||
| e292f5a869 | |||
| da25c6f843 | |||
| 5122fbe110 | |||
| dee3a3b655 | |||
| 4e2bcd22d9 | |||
| 17890027a6 | |||
| 5e93804525 | |||
| 778070dd8a | |||
| 74ecc762f3 | |||
| 63f7b35cf8 | |||
| 0c3f4601cc | |||
| 101b74398f |
@@ -0,0 +1,25 @@
|
||||
language: python
|
||||
|
||||
python:
|
||||
- '2.5'
|
||||
- '2.6'
|
||||
- '2.7'
|
||||
env:
|
||||
- DB=sqlite:memory
|
||||
- DB=mysql://root:@localhost/test_w2p
|
||||
- DB=postgres://postgres:@localhost/test_w2p
|
||||
before_script:
|
||||
- pip install unittest2
|
||||
- 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
|
||||
script: PYTHONPATH=. unit2 -v gluon.tests
|
||||
|
||||
notifications:
|
||||
email: false
|
||||
irc:
|
||||
channels: "irc.freenode.org#web2py"
|
||||
@@ -1,4 +1,16 @@
|
||||
## 2.4.1- 2.4.2
|
||||
## 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
|
||||
- support for 'json' field type in DAL
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
Web2py is Licensed under the LGPL license version 3
|
||||
(http://www.gnu.org/licenses/lgpl.html)
|
||||
|
||||
Copyrighted (c) by Massimo Di Pierro (2007-2011)
|
||||
Copyrighted (c) by Massimo Di Pierro (2007-2013)
|
||||
|
||||
### On Commercial Redistribution
|
||||
|
||||
|
||||
@@ -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.2-stable+timestamp.'`date +%Y.%m.%d.%H.%M.%S` > VERSION
|
||||
echo 'Version 2.4.6-stable+timestamp.'`date +%Y.%m.%d.%H.%M.%S` > VERSION
|
||||
### rm -f all junk files
|
||||
make clean
|
||||
### clean up baisc apps
|
||||
@@ -114,7 +114,6 @@ commit:
|
||||
make src
|
||||
echo '' > NEWINSTALL
|
||||
hg commit -m "$(S)"
|
||||
#bzr commit -m "$(S)"
|
||||
git commit -a -m "$(S)"
|
||||
push:
|
||||
hg push
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
|
||||
@@ -6,6 +6,11 @@ It is written and programmable in Python. LGPLv3 License
|
||||
|
||||
Learn more at http://web2py.com
|
||||
|
||||
|
||||
## Tests
|
||||
|
||||
[](https://travis-ci.org/web2py/web2py)
|
||||
|
||||
## Installation Instructions
|
||||
|
||||
To start web2py there is NO NEED to install it. Just unzip and do:
|
||||
|
||||
@@ -1 +1 @@
|
||||
Version 2.4.2-stable+timestamp.2013.03.03.21.22.42
|
||||
Version 2.4.6-stable+timestamp.2013.04.06.12.11.51
|
||||
|
||||
@@ -21,6 +21,10 @@ default_expiration: "24h" # for static files
|
||||
|
||||
handlers:
|
||||
|
||||
# Warning! Static mapping - below - isn't compatible with
|
||||
# the parametric router's language logic.
|
||||
# You cannot use them together.
|
||||
|
||||
- url: /(?P<a>.+?)/static/(?P<b>.+)
|
||||
static_files: applications/\1/static/\2
|
||||
upload: applications/(.+?)/static/(.+)
|
||||
|
||||
@@ -54,6 +54,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 = {}
|
||||
@@ -319,6 +323,9 @@ def state():
|
||||
|
||||
|
||||
def ccache():
|
||||
cache.ram.initialize()
|
||||
cache.disk.initialize()
|
||||
|
||||
form = FORM(
|
||||
P(TAG.BUTTON(
|
||||
T("Clear CACHE?"), _type="submit", _name="yes", _value="yes")),
|
||||
@@ -385,7 +392,7 @@ def ccache():
|
||||
|
||||
return (hours, minutes, seconds)
|
||||
|
||||
for key, value in cache.ram.storage.items():
|
||||
for key, value in cache.ram.storage.iteritems():
|
||||
if isinstance(value, dict):
|
||||
ram['hits'] = value['hit_total'] - value['misses']
|
||||
ram['misses'] = value['misses']
|
||||
|
||||
@@ -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'))
|
||||
|
||||
@@ -146,11 +146,9 @@ def check_version():
|
||||
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 version %s' % version_number)
|
||||
else:
|
||||
return sp_button(URL('upgrade_web2py'), T('upgrade now')) \
|
||||
+ XML(' <strong class="upgrade_version">%s.%s.%s</strong>'
|
||||
% version_number[:3])
|
||||
return sp_button(URL('upgrade_web2py'), T('upgrade now to %s') % version_number.split('-')[0])
|
||||
|
||||
|
||||
def logout():
|
||||
@@ -205,14 +203,12 @@ def site():
|
||||
|
||||
is_appname = IS_VALID_APPNAME()
|
||||
form_create = SQLFORM.factory(Field('name', requires=is_appname),
|
||||
table_name='appcreate',
|
||||
_class='well well-small')
|
||||
table_name='appcreate')
|
||||
form_update = SQLFORM.factory(Field('name', requires=is_appname),
|
||||
Field('file', 'upload', uploadfield=False),
|
||||
Field('url'),
|
||||
Field('overwrite', 'boolean'),
|
||||
table_name='appupdate',
|
||||
_class='well well-small')
|
||||
table_name='appupdate')
|
||||
form_create.process()
|
||||
form_update.process()
|
||||
|
||||
@@ -345,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:
|
||||
@@ -360,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'),
|
||||
@@ -686,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':
|
||||
@@ -1430,7 +1452,7 @@ def errors():
|
||||
hash2error[hash]['count'] += 1
|
||||
except KeyError:
|
||||
error_lines = error['traceback'].split("\n")
|
||||
last_line = error_lines[-2]
|
||||
last_line = error_lines[-2] if len(error_lines)>1 else 'unknown'
|
||||
error_causer = os.path.split(error['layer'])[1]
|
||||
hash2error[hash] = dict(count=1, pickel=error,
|
||||
causer=error_causer,
|
||||
@@ -1667,7 +1689,7 @@ def twitter():
|
||||
d = dict()
|
||||
for e in data:
|
||||
d[e["id"]] = e
|
||||
r = reversed(sorted(d))
|
||||
r = reversed(sorted(d))
|
||||
return dict(tweets=[d[k] for k in r])
|
||||
else:
|
||||
return 'disabled'
|
||||
|
||||
@@ -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é',
|
||||
}
|
||||
|
||||
@@ -23,9 +23,9 @@ if request.vars.app or request.args:
|
||||
|
||||
if os.path.exists('applications/examples'):
|
||||
response.menu.append(
|
||||
(T('Help'), False, URL('examples', 'default', 'index')))
|
||||
(T('Help'), False, URL('examples', 'default', 'documentation')))
|
||||
else:
|
||||
response.menu.append((T('Help'), False, 'http://web2py.com/examples'))
|
||||
response.menu.append((T('Help'), False, 'http://web2py.com/examples/default/documentation'))
|
||||
|
||||
if not session.authorized:
|
||||
response.menu = [(T('Login'), True, URL('site'))]
|
||||
|
||||
@@ -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-"]{
|
||||
|
||||
|
After Width: | Height: | Size: 4.6 KiB |
|
After Width: | Height: | Size: 4.9 KiB |
@@ -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',_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',_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',_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,44 +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">
|
||||
<div class="row-fluid">
|
||||
<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 -->
|
||||
@@ -139,322 +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">
|
||||
<div class="row-fluid">
|
||||
<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">
|
||||
<div class="row-fluid">
|
||||
<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">
|
||||
<div class="row-fluid">
|
||||
<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">
|
||||
<div class="row-fluid">
|
||||
<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">
|
||||
<div class="row-fluid">
|
||||
<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">
|
||||
<div class="row-fluid">
|
||||
<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">
|
||||
<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>
|
||||
@@ -465,7 +474,7 @@ function filter_files() {
|
||||
files=data['files'];
|
||||
message=data['message'];
|
||||
for(var i=0; i<files.length; i++)
|
||||
jQuery('li#'+files[i].replace(/\//g,'__').replace('.','__')).slideDown();
|
||||
jQuery('li#_'+files[i].replace(/\//g,'__').replace('.','__')).slideDown();
|
||||
jQuery('.flash').html(message).slideDown();
|
||||
});
|
||||
} else {
|
||||
|
||||
@@ -132,7 +132,7 @@ jQuery(document).ready(function(){
|
||||
<form action="{{=URL('edit',args=filename)}}" method="post" name="editform" id="editform">
|
||||
<div class="editor-bar-column">
|
||||
<label>{{=T('Save file:')}}</label>
|
||||
<a value="save" name="save" onclick="return doClickSave();" class="icon saveicon btn btn-mini" style="background-image: -webkit-linear-gradient(top,white,#E6E6E6);">
|
||||
<a value="save" name="save" onclick="return doClickSave();" class="icon saveicon" style="background-image: -webkit-linear-gradient(top,white,#E6E6E6);">
|
||||
{{=IMG(_src=URL('static', 'images/save_icon.png'), _alt=T('Save'))}}
|
||||
</a>
|
||||
</div>
|
||||
|
||||
@@ -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>
|
||||
@@ -6,7 +6,7 @@ def all(items):
|
||||
def peekfile(path,file):
|
||||
return A(file.replace('\\\\','/'),_href=URL('peek', args=(app, path, file)))
|
||||
def editfile(path,file):
|
||||
return A(SPAN(T('Edit')),_class='button editbutton btn',_href=URL('edit', args=(app, path, file)))
|
||||
return A(SPAN(T('Edit')),_class='button editbutton btn btn-mini',_href=URL('edit', args=(app, path, file)))
|
||||
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"))),
|
||||
@@ -16,7 +16,7 @@ def testfile(path,file):
|
||||
**{'_data-placement':'right',
|
||||
'_data-original-title':T("Run tests in this file")})
|
||||
def editlanguagefile(path,file):
|
||||
return A(SPAN(T('Edit')),_class='button editbutton',_href=URL('edit_language', args=(app, path, file)))
|
||||
return A(SPAN(T('Edit')),_class='button editbutton btn-mini',_href=URL('edit_language', args=(app, path, file)))
|
||||
def file_upload_form(location):
|
||||
form=FORM(T("upload file:")," ",
|
||||
INPUT(_type="file",_name="file")," ",T("and rename it:")," ",
|
||||
@@ -220,4 +220,4 @@ for c in controllers: controller_functions+=[c[:-3]+'/%s.html'%x for x in functi
|
||||
</ul>
|
||||
{{pass}}
|
||||
</div>
|
||||
<!-- end "plugin" block -->
|
||||
<!-- end "plugin" block -->
|
||||
|
||||
@@ -3,143 +3,158 @@
|
||||
{{block sectionclass}}site{{end}}
|
||||
<!-- begin "site" block -->
|
||||
<div class="row-fluid">
|
||||
<div class="applist f60 span7">
|
||||
<div class="applist_inner">
|
||||
<h2>{{=T("Installed applications")}}</h2>
|
||||
<ul class="unstyled">
|
||||
{{for a in apps:}}
|
||||
<li class="application"> <!-- onmouseover="jQuery(this).children('p').show()" onmouseout="jQuery(this).children('p').hide()"-->
|
||||
{{if a==request.application:}}
|
||||
<h3 class="currentapp muted">{{=a}} ({{=T('currently running')}})</h3>
|
||||
<p class="controls row-buttons">
|
||||
{{else:}}
|
||||
<h3 class="editableapp muted">{{=A(a,_href=URL(a,'default','index'))}}</h3>
|
||||
{{if MULTI_USER_MODE and db.app(name=a):}}(created by {{="%(first_name)s %(last_name)s" % db.auth_user[db.app(name=a).owner]}}){{pass}}
|
||||
<p class="controls row-buttons">
|
||||
{{if not os.path.exists('applications/%s/compiled' % a):}}
|
||||
{{=sp_button(URL('design',args=a), T("Edit"))}}
|
||||
{{else:}}
|
||||
{{=button(URL(a,'appadmin','index'), T("appadmin"))}}
|
||||
{{pass}}
|
||||
{{=button(URL('about',args=a), T("About"))}}
|
||||
{{pass}}
|
||||
{{=button(URL('errors',args=a), T("Errors"))}}
|
||||
{{=button(URL('cleanup',args=a), T("Clean"))}}
|
||||
{{=button(URL('pack',args=a), T("Pack all"))}}
|
||||
{{if not os.path.exists('applications/%s/compiled' % a):}}
|
||||
{{=button(URL('compile_app',args=a), T("Compile"))}}
|
||||
{{else:}}
|
||||
{{=button(URL('pack',args=(a, 'compiled')), T("Pack compiled"))}}
|
||||
{{if glob.glob('applications/%s/controllers/*.py' % a):}}
|
||||
{{=button(URL('remove_compiled_app',args=a), T("Remove compiled"))}}
|
||||
{{pass}}
|
||||
{{pass}}
|
||||
{{if os.path.exists(os.path.join(apath(r=request),a,'.git')): }}
|
||||
{{=button(URL('git_pull',args=a), T("Git Pull"))}}
|
||||
{{=button(URL('git_push',args=a), T("Git Push"))}}
|
||||
{{pass}}
|
||||
{{if a!=request.application:}}
|
||||
{{=button(URL('uninstall',args=a), T("Uninstall"))}}
|
||||
{{=button_enable(URL('enable',args=a), a)}}
|
||||
{{pass}}
|
||||
</p>
|
||||
</li>
|
||||
{{pass}}
|
||||
</ul>
|
||||
</div>
|
||||
</div> <!-- /applist -->
|
||||
<div class="sidebar fl60 span5">
|
||||
<div class="sidebar_inner controls well well-small">
|
||||
<!-- CHANGE ADMIN PWD -->
|
||||
<div class="pwdchange pull-right">
|
||||
{{if MULTI_USER_MODE:}}
|
||||
{{=auth.navbar()}}
|
||||
{{else:}}
|
||||
{{=sp_button(URL('change_password'), T('Change admin password'))}}
|
||||
{{pass}}
|
||||
</div> <!-- /CHANGE ADMIN PWD -->
|
||||
{{if is_manager():}}
|
||||
<!-- VERSION -->
|
||||
<div class="box">
|
||||
<h3>{{=T("Version %s.%s.%s %s (%s)", myversion)}}</h3>
|
||||
<p id="check_version" class="row-buttons">
|
||||
{{if session.check_version:}}
|
||||
{{=T('Checking for upgrades...')}}
|
||||
</p>
|
||||
<script>ajax('{{=URL('check_version')}}',[],'check_version');</script>
|
||||
{{session.check_version=False}}
|
||||
{{else:}}
|
||||
{{=button("javascript:ajax('"+URL('check_version')+"',[],'check_version')", T('Check for upgrades'))}}
|
||||
{{=button(URL('default','reload_routes'), T('Reload routes'))}}
|
||||
</p>
|
||||
{{pass}}
|
||||
<p>{{=T("Running on %s", request.env.server_software)}}</p>
|
||||
{{if session.is_mobile=='auto':}}
|
||||
<p>{{=A(T('Try the mobile interface'),_href=URL('plugin_jqmobile','about'))}}</p>
|
||||
{{pass}}
|
||||
</div> <!-- /VERSION -->
|
||||
{{pass}}
|
||||
{{if MULTI_USER_MODE and is_manager():}}
|
||||
<!-- MULTI_USER_INTERFACE -->
|
||||
<div class="box">
|
||||
<h3>{{=T("Multi User Mode")}}</h3>
|
||||
<p class="row-buttons">
|
||||
{{=button(URL('bulk_register'),T('Bulk Register'))}}
|
||||
{{=button(URL('manage_students',vars={'order':'auth_user.id'}),T('Manage Students'))}}
|
||||
</p>
|
||||
</div> <!-- /MULTI_USER_INTERFACE -->
|
||||
{{pass}}
|
||||
<!-- APP WIZARD -->
|
||||
<div class="box">
|
||||
<h3>{{=T("New application wizard")}}</h3>
|
||||
<p>{{=button(URL('wizard','index'), T('Start wizard'))}}
|
||||
{{=T("(requires internet access)")}}</p>
|
||||
</div> <!-- /APP WIZARD -->
|
||||
<!-- SCAFFOLD APP -->
|
||||
<div class="box">
|
||||
<h3>{{=T("New simple application")}}</h3>
|
||||
{{=form_create.custom.begin}}
|
||||
{{=LABEL(T("Application name:"))}}
|
||||
{{=form_create.custom.widget.name}}
|
||||
<div class="controls"><button type="submit" class="btn">{{=T('Create')}}</button></div>
|
||||
{{=form_create.custom.end}}
|
||||
</div> <!-- /SCAFFOLD APP -->
|
||||
<!-- UPLOAD PACKAGE -->
|
||||
<div class="box">
|
||||
<h3>{{=T("Upload and install packed application")}}</h3>
|
||||
{{=form_update.custom.begin}}
|
||||
<label for="appupdate_name">{{=T("Application name:")}}</label>
|
||||
{{=form_update.custom.widget.name}}
|
||||
<label for="appupdate_file">{{=T("Upload a package:")}}</label>
|
||||
{{=form_update.custom.widget.file}}
|
||||
<label for="appupdate_url">{{=T("Or Get from URL:")}}</label>
|
||||
{{=form_update.custom.widget.url}}<small class="help-block">({{=T('can be a git repo')}})</small>
|
||||
<div class="controls">
|
||||
<label class="checkbox">
|
||||
{{=form_update.custom.widget.overwrite}} {{=T("Overwrite installed app")}}
|
||||
</label>
|
||||
<button type="submit" class='btn'>{{=T('Install')}}</button>
|
||||
</div>
|
||||
{{=form_update.custom.end}}
|
||||
</div> <!-- /UPLOAD PACKAGE -->
|
||||
<!-- DEPLOY ON GAE -->
|
||||
<div class="box">
|
||||
<h3>{{=T("Deploy")}}</h3>
|
||||
<p class="row-buttons">
|
||||
{{=button(URL('gae','deploy'), T('Deploy on Google App Engine'))}}
|
||||
{{=button(URL('openshift','deploy'),T('Deploy to OpenShift'))}}
|
||||
</p>
|
||||
</div> <!-- /DEPLOY ON GAE -->
|
||||
<br/>
|
||||
{{if TWITTER_HASH:}}
|
||||
<!-- TWITTER -->
|
||||
<div class="box">
|
||||
<h3>{{=T("%s Recent Tweets"%TWITTER_HASH)}}</h3>
|
||||
<div id="tweets">{{=T('loading...')}}</div>
|
||||
<script>jQuery(document).ready(function(){jQuery('#tweets').load('{{=URL('twitter.load')}}');});</script>
|
||||
</div> <!-- /TWITTER -->
|
||||
{{pass}}
|
||||
</div>
|
||||
</div> <!-- /sidebar -->
|
||||
<div class="applist f60 span7">
|
||||
<div class="applist_inner">
|
||||
<h2>{{=T("Installed applications")}}</h2>
|
||||
<table width="100%" class="table">
|
||||
{{for a in apps:}}
|
||||
<tr>{{buttons = []}}
|
||||
<td>
|
||||
{{if a==request.application:}}
|
||||
<h4 class="currentapp">{{=a}} ({{=T('currently running')}})</h4>
|
||||
{{else:}}
|
||||
<h4 class="editableapp">{{=A(a,_href=URL(a,'default','index'))}}</h4>
|
||||
{{if MULTI_USER_MODE and db.app(name=a):}}(created by {{="%(first_name)s %(last_name)s" % db.auth_user[db.app(name=a).owner]}}){{pass}}
|
||||
{{if not os.path.exists('applications/%s/compiled' % a):}}
|
||||
{{buttons.append((URL('design',args=a), T("Edit")))}}
|
||||
{{else:}}
|
||||
{{buttons.append((URL(a,'appadmin','index'), T("appadmin")))}}
|
||||
{{pass}}
|
||||
{{buttons.append((URL('about',args=a), T("About")))}}
|
||||
{{pass}}
|
||||
{{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:}}
|
||||
{{buttons.append((URL('pack',args=(a, 'compiled')), T("Pack compiled")))}}
|
||||
{{if glob.glob('applications/%s/controllers/*.py' % a):}}
|
||||
{{buttons.append((URL('remove_compiled_app',args=a), T("Remove compiled")))}}
|
||||
{{pass}}
|
||||
{{pass}}
|
||||
{{if os.path.exists(os.path.join(apath(r=request),a,'.git')): }}
|
||||
{{buttons.append((URL('git_pull',args=a), T("Git Pull")))}}
|
||||
{{buttons.append((URL('git_push',args=a), T("Git Push")))}}
|
||||
{{pass}}
|
||||
{{if a!=request.application:}}
|
||||
{{buttons.append((URL('uninstall',args=a), T("Uninstall")))}}
|
||||
{{pass}}
|
||||
</td>
|
||||
<td>
|
||||
<div class="btn-group">
|
||||
<a class="btn dropdown-toggle" data-toggle="dropdown" href="#">
|
||||
{{=T('Manage')}}
|
||||
<span class="caret"></span>
|
||||
</a>
|
||||
<ul class="dropdown-menu">
|
||||
{{for link,name in buttons:}}
|
||||
{{=LI(A(name,_href=link))}}
|
||||
{{pass}}
|
||||
</ul>
|
||||
</div>
|
||||
{{=button_enable(URL('enable',args=a), a)}}
|
||||
</td>
|
||||
</tr>
|
||||
{{pass}}
|
||||
</table>
|
||||
</div>
|
||||
</div> <!-- /applist -->
|
||||
<div class="sidebar fl60 span5">
|
||||
<div class="sidebar_inner controls well well-small">
|
||||
<!-- CHANGE ADMIN PWD -->
|
||||
<div class="pwdchange pull-right">
|
||||
{{if MULTI_USER_MODE:}}
|
||||
{{=auth.navbar()}}
|
||||
{{else:}}
|
||||
{{=sp_button(URL('change_password'), T('Change admin password'))}}
|
||||
{{=button(URL('default','reload_routes'), T('Reload routes'))}}
|
||||
{{pass}}
|
||||
</div> <!-- /CHANGE ADMIN PWD -->
|
||||
{{if is_manager():}}
|
||||
<!-- VERSION -->
|
||||
<div class="box">
|
||||
<h4>{{=T("Version")}}</h4>
|
||||
<p>
|
||||
<tt>{{=myversion}}</tt><br/>
|
||||
({{=T("Running on %s", request.env.server_software)}})
|
||||
</p>
|
||||
<p id="check_version" class="row-buttons">
|
||||
{{if session.check_version:}}
|
||||
{{=T('Checking for upgrades...')}}
|
||||
<script>ajax('{{=URL('check_version')}}',[],'check_version');</script>
|
||||
{{session.check_version=False}}
|
||||
{{else:}}
|
||||
{{=button("javascript:ajax('"+URL('check_version')+"',[],'check_version')", T('Check for upgrades'))}}
|
||||
{{pass}}
|
||||
</p>
|
||||
{{if session.is_mobile=='auto':}}
|
||||
<p>{{=A(T('Try the mobile interface'),_href=URL('plugin_jqmobile','about'))}}</p>
|
||||
{{pass}}
|
||||
</div> <!-- /VERSION -->
|
||||
{{pass}}
|
||||
{{if MULTI_USER_MODE and is_manager():}}
|
||||
<!-- MULTI_USER_INTERFACE -->
|
||||
<div class="box">
|
||||
<h4>{{=T("Multi User Mode")}}</h4>
|
||||
<p class="row-buttons">
|
||||
{{=button(URL('bulk_register'),T('Bulk Register'))}}
|
||||
{{=button(URL('manage_students',vars={'order':'auth_user.id'}),T('Manage Students'))}}
|
||||
</p>
|
||||
</div> <!-- /MULTI_USER_INTERFACE -->
|
||||
{{pass}}
|
||||
<!-- SCAFFOLD APP -->
|
||||
<div class="box">
|
||||
<h4>{{=T("New simple application")}}</h4>
|
||||
{{=form_create.custom.begin}}
|
||||
{{=LABEL(T("Application name:"))}}
|
||||
{{=form_create.custom.widget.name}}
|
||||
<div class="controls"><button type="submit" class="btn">{{=T('Create')}}</button></div>
|
||||
{{=form_create.custom.end}}
|
||||
</div> <!-- /SCAFFOLD APP -->
|
||||
<!-- UPLOAD PACKAGE -->
|
||||
<div class="box">
|
||||
<h4>{{=T("Upload and install packed application")}}</h4>
|
||||
{{=form_update.custom.begin}}
|
||||
<label for="appupdate_name">{{=T("Application name:")}}</label>
|
||||
{{=form_update.custom.widget.name}}
|
||||
<label for="appupdate_file">{{=T("Upload a package:")}}</label>
|
||||
{{=form_update.custom.widget.file}}
|
||||
<label for="appupdate_url">{{=T("Or Get from URL:")}}</label>
|
||||
{{=form_update.custom.widget.url}}<small class="help-block">({{=T('can be a git repo')}})</small>
|
||||
<div class="controls">
|
||||
<label class="checkbox">
|
||||
{{=form_update.custom.widget.overwrite}} {{=T("Overwrite installed app")}}
|
||||
</label>
|
||||
<button type="submit" class='btn'>{{=T('Install')}}</button>
|
||||
</div>
|
||||
{{=form_update.custom.end}}
|
||||
</div> <!-- /UPLOAD PACKAGE -->
|
||||
<!-- DEPLOY ON GAE -->
|
||||
<div class="box">
|
||||
<h4>{{=T("Deploy")}}</h4>
|
||||
<p class="row-buttons">
|
||||
{{=button(URL('gae','deploy'), T('Deploy on Google App Engine'))}}
|
||||
{{=button(URL('openshift','deploy'),T('Deploy to OpenShift'))}}
|
||||
</p>
|
||||
</div> <!-- /DEPLOY ON GAE -->
|
||||
<!-- APP WIZARD -->
|
||||
<div class="box">
|
||||
<h4>{{=T("New application wizard")}}</h4>
|
||||
<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}}
|
||||
</div>
|
||||
</div> <!-- /sidebar -->
|
||||
</div> <!-- /row-fluid
|
||||
<!-- end "site" block -->
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
<tbody>
|
||||
<tr>
|
||||
<th>web2py™</th>
|
||||
<td>{{=myversion}}</td>
|
||||
<td>Version {{=myversion}}</td>
|
||||
</tr>
|
||||
{{if snapshot:}}
|
||||
<tr>
|
||||
|
||||
@@ -27,8 +27,17 @@ Tweet attributes
|
||||
"""
|
||||
}}
|
||||
|
||||
{{import re}}
|
||||
{{hashtag = re.compile('([#@])(\w+)')}}
|
||||
{{link = re.compile('(?!<")https?\:\/\/[\w\./?&]+')}}
|
||||
<table class="twitter">
|
||||
{{ for t in tweets: }}
|
||||
{{ =DIV(H5(t["from_user_name"])) }}
|
||||
{{ =DIV(t["text"]) }}
|
||||
{{ =BR() }}
|
||||
<tr class="tweet">
|
||||
<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"].encode('utf8'))),sanitize=True)}}
|
||||
</td>
|
||||
</tr>
|
||||
{{ pass }}
|
||||
</table>
|
||||
@@ -8,6 +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'))
|
||||
@@ -79,6 +80,11 @@
|
||||
jQuery("[rel=tooltip]").tooltip();
|
||||
});
|
||||
</script>
|
||||
|
||||
{{if request.function in ('index','site'):}}
|
||||
<a style="position:fixed;bottom:0;left:0;z-index:1000" href="https://groups.google.com/forum/?fromgroups#!forum/web2py" target="_blank">
|
||||
<!-- http://webchat.freenode.net/?channels=web2py" //-->
|
||||
<img src="{{=URL('static','images/questions.png')}}" />
|
||||
</a>
|
||||
{{pass}}
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -7,7 +7,6 @@ for application "{{=request.args[0]}}"</h2>
|
||||
<h3>Commit form</h3>
|
||||
{{=form}}
|
||||
|
||||
|
||||
{{if repo['.'].rev()>=0:}}
|
||||
<h3>Last Revision</h3>
|
||||
<table>
|
||||
|
||||
@@ -54,6 +54,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 = {}
|
||||
@@ -319,6 +323,9 @@ def state():
|
||||
|
||||
|
||||
def ccache():
|
||||
cache.ram.initialize()
|
||||
cache.disk.initialize()
|
||||
|
||||
form = FORM(
|
||||
P(TAG.BUTTON(
|
||||
T("Clear CACHE?"), _type="submit", _name="yes", _value="yes")),
|
||||
@@ -385,7 +392,7 @@ def ccache():
|
||||
|
||||
return (hours, minutes, seconds)
|
||||
|
||||
for key, value in cache.ram.storage.items():
|
||||
for key, value in cache.ram.storage.iteritems():
|
||||
if isinstance(value, dict):
|
||||
ram['hits'] = value['hit_total'] - value['misses']
|
||||
ram['misses'] = value['misses']
|
||||
|
||||
@@ -20,7 +20,7 @@ def what():
|
||||
import urllib
|
||||
try:
|
||||
images = XML(urllib.urlopen(
|
||||
'http://web2py.com/poweredby/default/images').read())
|
||||
'http://www.web2py.com/poweredby/default/images').read())
|
||||
except:
|
||||
images = []
|
||||
return response.render(images=images)
|
||||
@@ -61,11 +61,11 @@ def videos():
|
||||
|
||||
|
||||
def security():
|
||||
redirect('http://www.web2py.com/book/default/chapter/01#security')
|
||||
redirect('http://www.web2py.com/book/default/chapter/01#Security')
|
||||
|
||||
|
||||
def api():
|
||||
redirect('http://web2py.com/book/default/chapter/04#API')
|
||||
redirect('http://www.web2py.com/book/default/chapter/04#API')
|
||||
|
||||
|
||||
@cache('license', time_expire=cache_expire)
|
||||
@@ -74,10 +74,14 @@ def license():
|
||||
filename = os.path.join(request.env.gluon_parent, 'LICENSE')
|
||||
return response.render(dict(license=MARKMIN(read_file(filename))))
|
||||
|
||||
|
||||
def version():
|
||||
return 'Version %s.%s.%s (%s) %s' % request.env.web2py_version
|
||||
|
||||
if request.args(0)=='raw':
|
||||
return request.env.web2py_version
|
||||
from gluon.fileutils import parse_version
|
||||
(a, b, c, pre_release, build) = parse_version(request.env.web2py_version)
|
||||
return 'Version %i.%i.%i (%.4i-%.2i-%.2i %.2i:%.2i:%.2i) %s' % (
|
||||
a,b,c,build.year,build.month,build.day,
|
||||
build.hour,build.minute,build.second,pre_release)
|
||||
|
||||
@cache('examples', time_expire=cache_expire)
|
||||
def examples():
|
||||
|
||||
@@ -1,75 +1,49 @@
|
||||
session.forget()
|
||||
|
||||
response.menu = [['home', False, '/%s/default/index'
|
||||
% request.application], ['docs', True,
|
||||
'/%s/global/vars' % request.application]]
|
||||
|
||||
|
||||
def get(args):
|
||||
if args[0].startswith('__'):
|
||||
return None
|
||||
try:
|
||||
obj = globals(),get(args[0])
|
||||
for k in range(1,len(args)):
|
||||
obj = getattr(obj,args[k])
|
||||
return obj
|
||||
except:
|
||||
return None
|
||||
|
||||
def vars():
|
||||
"""the running controller function!"""
|
||||
|
||||
title = '.'.join(request.args)
|
||||
attributes = {}
|
||||
if not request.args:
|
||||
(
|
||||
doc,
|
||||
keys,
|
||||
t,
|
||||
c,
|
||||
d,
|
||||
value,
|
||||
) = (
|
||||
'Global variables',
|
||||
globals(),
|
||||
None,
|
||||
None,
|
||||
(),
|
||||
None,
|
||||
)
|
||||
(title, args) = ('globals()', '')
|
||||
(doc,keys,t,c,d,value)=('Global variables',globals(),None,None,[],None)
|
||||
elif len(request.args) < 3:
|
||||
args = '.'.join(request.args)
|
||||
try:
|
||||
doc = eval(args + '.__doc__')
|
||||
except:
|
||||
doc = 'no documentation'
|
||||
try:
|
||||
keys = eval('dir(%s)' % args)
|
||||
except:
|
||||
obj = get(request.args)
|
||||
if obj:
|
||||
doc = getattr(obj,'__doc__','no documentation')
|
||||
keys = dir(obj)
|
||||
t = type(obj)
|
||||
c = getattr(obj,'__class__',None)
|
||||
d = getattr(obj,'__bases__',None)
|
||||
|
||||
for key in keys:
|
||||
a = getattr(obj,key,None)
|
||||
if a and not isinstance(a,DAL):
|
||||
doc1 = getattr(a, '__doc__', '')
|
||||
t1 = type(a)
|
||||
c1 = getattr(a,'__class__',None)
|
||||
d1 = getattr(a,'__bases__',None)
|
||||
key = '.'.join(request.args)+'.'+key
|
||||
attributes[key] = (doc1, t1, c1, d1)
|
||||
else:
|
||||
doc = 'Unkown'
|
||||
keys = []
|
||||
t = eval('type(%s)' % args)
|
||||
try:
|
||||
c = eval('%s.__class__' % args)
|
||||
except:
|
||||
c = None
|
||||
try:
|
||||
d = eval('%s.__bases__' % args)
|
||||
except:
|
||||
d = None
|
||||
title = args
|
||||
args += '.'
|
||||
t = c = d = None
|
||||
else:
|
||||
raise HTTP(400)
|
||||
attributes = {}
|
||||
for key in keys:
|
||||
a = args + key
|
||||
if eval('isinstance(%s,SQLDB)' % a) or a == 'vars':
|
||||
continue
|
||||
try:
|
||||
doc1 = eval(a + '.__doc__')
|
||||
except:
|
||||
doc1 = 'no documentation'
|
||||
t1 = eval('type(%s)' % a)
|
||||
try:
|
||||
c1 = eval('%s.__class__' % a)
|
||||
except:
|
||||
c1 = None
|
||||
try:
|
||||
d1 = eval('%s.__bases__' % a)
|
||||
except:
|
||||
d1 = ()
|
||||
attributes[a] = (doc1, t1, c1, d1)
|
||||
return dict(
|
||||
title=title,
|
||||
args=args,
|
||||
args=request.args,
|
||||
t=t,
|
||||
c=c,
|
||||
d=d,
|
||||
|
||||
@@ -54,13 +54,6 @@ def raisehttp():
|
||||
raise HTTP(400, 'internal error')
|
||||
|
||||
|
||||
def raiseexception():
|
||||
""" generates an exeption, logs the event and returns a ticket number """
|
||||
|
||||
1 / 0
|
||||
return 'oops'
|
||||
|
||||
|
||||
def servejs():
|
||||
""" serves a js document """
|
||||
|
||||
@@ -69,7 +62,6 @@ def servejs():
|
||||
gluon.contenttype.contenttype('.js')
|
||||
return 'alert("This is a Javascript document, it is not supposed to run!");'
|
||||
|
||||
|
||||
def makejson():
|
||||
import gluon.contrib.simplejson as sj
|
||||
return sj.dumps(['foo', {'bar': ('baz', None, 1.0, 2)}])
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
from gluon.contrib.spreadsheet import Sheet
|
||||
|
||||
|
||||
def callback():
|
||||
return cache.ram('sheet1', lambda: None, None).process(request)
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
403
|
||||
@@ -0,0 +1 @@
|
||||
404
|
||||
@@ -0,0 +1 @@
|
||||
500
|
||||
@@ -1,117 +1,16 @@
|
||||
footer-content {position: relative; bottom: 0; width: 100%;}
|
||||
|
||||
.statusbar {
|
||||
padding: 2px 0;
|
||||
border: 0;
|
||||
margin-bottom: 15px;
|
||||
background-color: #C1CDCD;
|
||||
/*background: url('../images/menu.png') repeat-x;*/
|
||||
}
|
||||
.statusbar a, .statusbar a:visited {
|
||||
color: #406361;
|
||||
}
|
||||
|
||||
.footer {
|
||||
position: relative;
|
||||
}
|
||||
.footer-content {
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
}
|
||||
@import url(http://fonts.googleapis.com/css?family=Economica);
|
||||
@@import url(http://fonts.googleapis.com/css?family=Belleza);
|
||||
|
||||
body { font-family: Arial, Helvetica; }
|
||||
a, a:visited, a:hover, h1,h2,h3,h4,h5 {color: #658883}
|
||||
a.button {color: #658883}
|
||||
|
||||
.sf-menu li, .sf-menu li a { border-radius: 5px;}
|
||||
|
||||
.wrapper {
|
||||
background: url('../images/back-02.png') repeat-x;
|
||||
padding-top:10px;
|
||||
a.btn-danger, a.btn-warning, a.btn-success {color:white}
|
||||
h1,h2,h3,h4,h5 { font-family: "Economica", Arial, Helevtica; }
|
||||
body {
|
||||
background: url('../images/stripes.png') repeat-x;
|
||||
}
|
||||
h1 { font-size: 32px }
|
||||
h2 { font-size: 24px }
|
||||
h3 { font-size: 20px }
|
||||
h4 { font-size: 14px }
|
||||
sup {
|
||||
font-size: 0.5em;
|
||||
line-height: 2em;
|
||||
vertical-align: top;
|
||||
}
|
||||
ul { list-style: circle outside; padding-left: 30px;}
|
||||
|
||||
.frame {
|
||||
border: 3px solid #959595;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.header h5 {
|
||||
float: left;
|
||||
}
|
||||
.logo: {
|
||||
float:left;
|
||||
}
|
||||
|
||||
.announce {
|
||||
text-align: center;
|
||||
color: white;
|
||||
top: 0;
|
||||
font-weight: bold;
|
||||
text-align: center;
|
||||
left: 0;
|
||||
position: relative;
|
||||
background: #000;
|
||||
border-radius: 5px;
|
||||
margin: 7px 0 15px;
|
||||
}
|
||||
.announce a {color: white}
|
||||
|
||||
input:focus, textarea:focus {background:#f0f0f0}
|
||||
|
||||
table.downloads { width:100%; }
|
||||
table.downloads th, table.downloads td {text-align:center;}
|
||||
table.downloads a.button { width: 150px; }
|
||||
th,td {padding-right: 10px;}
|
||||
|
||||
p {text-align: left;}
|
||||
|
||||
p + p {
|
||||
margin-bottom: .75em;
|
||||
}
|
||||
|
||||
strong {color: inherit;}
|
||||
|
||||
img.centered {
|
||||
margin: 0 auto;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.tagCloud {
|
||||
width: 100%;
|
||||
max-width: 489px;
|
||||
}
|
||||
.mainbody {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.aboutW2P {
|
||||
margin-top: 23px;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
.aboutW2P p {
|
||||
padding: 0 0.5em;
|
||||
font-size: 1.15em;
|
||||
}
|
||||
.aboutW2P h3 {
|
||||
padding: 0 0.3em;
|
||||
}
|
||||
.userQuotes {
|
||||
/*border-top: #eee 2px solid;*/
|
||||
padding-top: 15px;
|
||||
}
|
||||
.userQuotes p {
|
||||
text-align: left;
|
||||
font-size: 111%;
|
||||
color: #777;
|
||||
}
|
||||
#menu {
|
||||
padding: 0.1em 0.5em;
|
||||
#header {
|
||||
margin-top: 40px;
|
||||
}
|
||||
.btn-180 {
|
||||
width: 180px;
|
||||
}
|
||||
@@ -1,629 +0,0 @@
|
||||
/*
|
||||
* Skeleton V1.1
|
||||
* Copyright 2011, Dave Gamache
|
||||
* www.getskeleton.com
|
||||
* Free to use under the MIT license.
|
||||
* http://www.opensource.org/licenses/mit-license.php
|
||||
* 8/17/2011
|
||||
*/
|
||||
|
||||
|
||||
/* Table of Content
|
||||
==================================================
|
||||
#Reset & Basics
|
||||
#Basic Styles
|
||||
#Site Styles
|
||||
#Typography
|
||||
#Links
|
||||
#Lists
|
||||
#Images
|
||||
#Buttons
|
||||
#Tabs
|
||||
#Forms
|
||||
#Misc */
|
||||
|
||||
|
||||
/* #Reset & Basics (Inspired by E. Meyers)
|
||||
================================================== */
|
||||
html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, b, u, i, center, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td, article, aside, canvas, details, embed, figure, figcaption, footer, header, hgroup, menu, nav, output, ruby, section, summary, time, mark, audio, video {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
border: 0;
|
||||
font-size: 100%;
|
||||
font: inherit;
|
||||
vertical-align: baseline; }
|
||||
article, aside, details, figcaption, figure, footer, header, hgroup, menu, nav, section {
|
||||
display: block; }
|
||||
body {
|
||||
line-height: 1; }
|
||||
// ol, ul { list-style: none; } /* WEB2PY EDIT */
|
||||
blockquote, q {
|
||||
quotes: none; }
|
||||
blockquote:before, blockquote:after,
|
||||
q:before, q:after {
|
||||
content: '';
|
||||
content: none; }
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
border-spacing: 0; }
|
||||
|
||||
|
||||
/* #Basic Styles
|
||||
================================================== */
|
||||
body {
|
||||
background: #fff;
|
||||
font: 14px/21px "HelveticaNeue", "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||
color: #444;
|
||||
-webkit-font-smoothing: antialiased; /* Fix for webkit rendering */
|
||||
-webkit-text-size-adjust: 100%;
|
||||
}
|
||||
|
||||
|
||||
/* #Typography
|
||||
================================================== */
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
color: #181818;
|
||||
font-family: "Georgia", "Times New Roman", Helvetica, Arial, sans-serif;
|
||||
font-weight: normal; }
|
||||
h1 a, h2 a, h3 a, h4 a, h5 a, h6 a { font-weight: inherit; }
|
||||
h1 { font-size: 46px; line-height: 50px; }
|
||||
h2 { font-size: 35px; line-height: 40px; }
|
||||
h3 { font-size: 28px; line-height: 34px; }
|
||||
h4 { font-size: 21px; line-height: 30px; }
|
||||
h5 { font-size: 17px; line-height: 24px; }
|
||||
h6 { font-size: 14px; line-height: 21px; }
|
||||
|
||||
.subheader { color: #777; }
|
||||
|
||||
p { margin: 0 0 20px 0; }
|
||||
p img { margin: 0; }
|
||||
p.lead { font-size: 21px; line-height: 27px; color: #777; }
|
||||
|
||||
em { font-style: italic; }
|
||||
strong { font-weight: bold; color: #333; }
|
||||
small { font-size: 80%; }
|
||||
|
||||
/* Blockquotes */
|
||||
blockquote, blockquote p { font-size: 17px; line-height: 24px; color: #777; font-style: italic; }
|
||||
blockquote { margin: 0 0 20px; padding: 9px 20px 0 19px;} /* WEB2PY EDIT */
|
||||
blockquote cite { display: block; font-size: 12px; color: #555; }
|
||||
blockquote cite:before { content: "\2014 \0020"; }
|
||||
blockquote cite a, blockquote cite a:visited, blockquote cite a:visited { color: #555; }
|
||||
|
||||
hr { border: solid #ddd; border-width: 1px 0 0; clear: both; margin: 10px 0 30px; height: 0; }
|
||||
|
||||
|
||||
/* #Links
|
||||
================================================== */
|
||||
a, a:visited { color: #333; text-decoration: underline; outline: 0; }
|
||||
a:hover, a:focus { color: #000; }
|
||||
p a, p a:visited { line-height: inherit; }
|
||||
|
||||
|
||||
/* #Lists
|
||||
================================================== */
|
||||
ul, ol { margin-bottom: 20px; }
|
||||
// ul { list-style: none outside; } /* WEB2PY EDIT */
|
||||
ol { list-style: decimal; }
|
||||
ol, ul.square, ul.circle, ul.disc { margin-left: 30px; }
|
||||
ul.square { list-style: square outside; }
|
||||
ul.circle { list-style: circle outside; }
|
||||
ul.disc { list-style: disc outside; }
|
||||
ul ul, ul ol,
|
||||
ol ol, ol ul { margin: 4px 0 5px 30px; font-size: 90%; }
|
||||
ul ul li, ul ol li,
|
||||
ol ol li, ol ul li { margin-bottom: 6px; }
|
||||
li { line-height: 18px; margin-bottom: 12px; }
|
||||
ul.large li { line-height: 21px; }
|
||||
li p { line-height: 21px; }
|
||||
|
||||
/* #Images
|
||||
================================================== */
|
||||
|
||||
img.scale-with-grid {
|
||||
max-width: 100%;
|
||||
height: auto; }
|
||||
|
||||
|
||||
/* #Buttons
|
||||
================================================== */
|
||||
|
||||
a.button,
|
||||
button,
|
||||
input[type="submit"],
|
||||
input[type="reset"],
|
||||
input[type="button"] {
|
||||
background: #eee; /* Old browsers */
|
||||
background: #eee -moz-linear-gradient(top, rgba(255,255,255,.2) 0%, rgba(0,0,0,.2) 100%); /* FF3.6+ */
|
||||
background: #eee -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(255,255,255,.2)), color-stop(100%,rgba(0,0,0,.2))); /* Chrome,Safari4+ */
|
||||
background: #eee -webkit-linear-gradient(top, rgba(255,255,255,.2) 0%,rgba(0,0,0,.2) 100%); /* Chrome10+,Safari5.1+ */
|
||||
background: #eee -o-linear-gradient(top, rgba(255,255,255,.2) 0%,rgba(0,0,0,.2) 100%); /* Opera11.10+ */
|
||||
background: #eee -ms-linear-gradient(top, rgba(255,255,255,.2) 0%,rgba(0,0,0,.2) 100%); /* IE10+ */
|
||||
background: #eee linear-gradient(top, rgba(255,255,255,.2) 0%,rgba(0,0,0,.2) 100%); /* W3C */
|
||||
border: 1px solid #aaa;
|
||||
border-top: 1px solid #ccc;
|
||||
border-left: 1px solid #ccc;
|
||||
padding: 4px 12px;
|
||||
-moz-border-radius: 3px;
|
||||
-webkit-border-radius: 3px;
|
||||
border-radius: 3px;
|
||||
color: #444;
|
||||
display: inline-block;
|
||||
font-size: 1em; /** WEB2PY EDIT **/
|
||||
font-weight: bold;
|
||||
text-decoration: none;
|
||||
text-shadow: 0 1px rgba(255, 255, 255, .75);
|
||||
cursor: pointer;
|
||||
margin-bottom: 5px; /** WEB2PY EDIT **/
|
||||
line-height: 21px;
|
||||
font-family: "HelveticaNeue", "Helvetica Neue", Helvetica, Arial, sans-serif; }
|
||||
|
||||
a.button:hover,
|
||||
button:hover,
|
||||
input[type="submit"]:hover,
|
||||
input[type="reset"]:hover,
|
||||
input[type="button"]:hover {
|
||||
color: #222;
|
||||
background: #ddd; /* Old browsers */
|
||||
background: #ddd -moz-linear-gradient(top, rgba(255,255,255,.3) 0%, rgba(0,0,0,.3) 100%); /* FF3.6+ */
|
||||
background: #ddd -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(255,255,255,.3)), color-stop(100%,rgba(0,0,0,.3))); /* Chrome,Safari4+ */
|
||||
background: #ddd -webkit-linear-gradient(top, rgba(255,255,255,.3) 0%,rgba(0,0,0,.3) 100%); /* Chrome10+,Safari5.1+ */
|
||||
background: #ddd -o-linear-gradient(top, rgba(255,255,255,.3) 0%,rgba(0,0,0,.3) 100%); /* Opera11.10+ */
|
||||
background: #ddd -ms-linear-gradient(top, rgba(255,255,255,.3) 0%,rgba(0,0,0,.3) 100%); /* IE10+ */
|
||||
background: #ddd linear-gradient(top, rgba(255,255,255,.3) 0%,rgba(0,0,0,.3) 100%); /* W3C */
|
||||
border: 1px solid #888;
|
||||
border-top: 1px solid #aaa;
|
||||
border-left: 1px solid #aaa; }
|
||||
|
||||
a.button:active,
|
||||
button:active,
|
||||
input[type="submit"]:active,
|
||||
input[type="reset"]:active,
|
||||
input[type="button"]:active {
|
||||
border: 1px solid #666;
|
||||
background: #ccc; /* Old browsers */
|
||||
background: #ccc -moz-linear-gradient(top, rgba(255,255,255,.35) 0%, rgba(10,10,10,.4) 100%); /* FF3.6+ */
|
||||
background: #ccc -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(255,255,255,.35)), color-stop(100%,rgba(10,10,10,.4))); /* Chrome,Safari4+ */
|
||||
background: #ccc -webkit-linear-gradient(top, rgba(255,255,255,.35) 0%,rgba(10,10,10,.4) 100%); /* Chrome10+,Safari5.1+ */
|
||||
background: #ccc -o-linear-gradient(top, rgba(255,255,255,.35) 0%,rgba(10,10,10,.4) 100%); /* Opera11.10+ */
|
||||
background: #ccc -ms-linear-gradient(top, rgba(255,255,255,.35) 0%,rgba(10,10,10,.4) 100%); /* IE10+ */
|
||||
background: #ccc linear-gradient(top, rgba(255,255,255,.35) 0%,rgba(10,10,10,.4) 100%); /* W3C */ }
|
||||
|
||||
.button.full-width,
|
||||
button.full-width,
|
||||
input[type="submit"].full-width,
|
||||
input[type="reset"].full-width,
|
||||
input[type="button"].full-width {
|
||||
width: 100%;
|
||||
padding-left: 0 !important;
|
||||
padding-right: 0 !important;
|
||||
text-align: center; }
|
||||
|
||||
|
||||
/* #Tabs (activate in tabs.js)
|
||||
================================================== */
|
||||
ul.tabs {
|
||||
display: block;
|
||||
margin: 0 0 20px 0;
|
||||
padding: 0;
|
||||
border-bottom: solid 1px #ddd; }
|
||||
ul.tabs li {
|
||||
display: block;
|
||||
width: auto;
|
||||
height: 30px;
|
||||
padding: 0;
|
||||
float: left;
|
||||
margin-bottom: 0; }
|
||||
ul.tabs li a {
|
||||
display: block;
|
||||
text-decoration: none;
|
||||
width: auto;
|
||||
height: 29px;
|
||||
padding: 0px 20px;
|
||||
line-height: 30px;
|
||||
border: solid 1px #ddd;
|
||||
border-width: 1px 1px 0 0;
|
||||
margin: 0;
|
||||
background: #f5f5f5;
|
||||
font-size: 13px; }
|
||||
ul.tabs li a.active {
|
||||
background: #fff;
|
||||
height: 30px;
|
||||
position: relative;
|
||||
top: -4px;
|
||||
padding-top: 4px;
|
||||
border-left-width: 1px;
|
||||
margin: 0 0 0 -1px;
|
||||
color: #111;
|
||||
-moz-border-radius-topleft: 2px;
|
||||
-webkit-border-top-left-radius: 2px;
|
||||
border-top-left-radius: 2px;
|
||||
-moz-border-radius-topright: 2px;
|
||||
-webkit-border-top-right-radius: 2px;
|
||||
border-top-right-radius: 2px; }
|
||||
ul.tabs li:first-child a.active {
|
||||
margin-left: 0; }
|
||||
ul.tabs li:first-child a {
|
||||
border-width: 1px 1px 0 1px;
|
||||
-moz-border-radius-topleft: 2px;
|
||||
-webkit-border-top-left-radius: 2px;
|
||||
border-top-left-radius: 2px; }
|
||||
ul.tabs li:last-child a {
|
||||
-moz-border-radius-topright: 2px;
|
||||
-webkit-border-top-right-radius: 2px;
|
||||
border-top-right-radius: 2px; }
|
||||
|
||||
ul.tabs-content { margin: 0; display: block; }
|
||||
ul.tabs-content > li { display:none; }
|
||||
ul.tabs-content > li.active { display: block; }
|
||||
|
||||
/* Clearfixing tabs for beautiful stacking */
|
||||
ul.tabs:before,
|
||||
ul.tabs:after {
|
||||
content: '\0020';
|
||||
display: block;
|
||||
overflow: hidden;
|
||||
visibility: hidden;
|
||||
width: 0;
|
||||
height: 0; }
|
||||
ul.tabs:after {
|
||||
clear: both; }
|
||||
ul.tabs {
|
||||
zoom: 1; }
|
||||
|
||||
|
||||
/* #Forms
|
||||
================================================== */
|
||||
|
||||
form {
|
||||
margin-bottom: 5px; } /** WEB2PY EDIT **/
|
||||
fieldset {
|
||||
margin-bottom: 5px; } /** WEB2PY EDIT **/
|
||||
input[type="text"],
|
||||
input[type="password"],
|
||||
input[type="email"],
|
||||
textarea,
|
||||
select {
|
||||
border: 1px solid #ccc;
|
||||
padding: 6px 4px;
|
||||
outline: none;
|
||||
-moz-border-radius: 2px;
|
||||
-webkit-border-radius: 2px;
|
||||
border-radius: 2px;
|
||||
font: 13px "HelveticaNeue", "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||
color: #777;
|
||||
margin: 0;
|
||||
width: 210px;
|
||||
max-width: 100%;
|
||||
// display: block; /** WEB2PY EDIT **/
|
||||
margin-bottom: 0; /** WEB2PY EDIT **/
|
||||
background: #fff; }
|
||||
select {
|
||||
padding: 0; }
|
||||
input[type="text"]:focus,
|
||||
input[type="password"]:focus,
|
||||
input[type="email"]:focus,
|
||||
textarea:focus {
|
||||
border: 1px solid #aaa;
|
||||
color: #444;
|
||||
-moz-box-shadow: 0 0 3px rgba(0,0,0,.2);
|
||||
-webkit-box-shadow: 0 0 3px rgba(0,0,0,.2);
|
||||
box-shadow: 0 0 3px rgba(0,0,0,.2); }
|
||||
textarea {
|
||||
min-height: 60px; }
|
||||
label,
|
||||
legend {
|
||||
display: block;
|
||||
font-weight: bold;
|
||||
font-size: 13px; }
|
||||
select {
|
||||
width: 220px; }
|
||||
input[type="checkbox"] {
|
||||
display: inline; }
|
||||
label span,
|
||||
legend span {
|
||||
font-weight: normal;
|
||||
font-size: 13px;
|
||||
color: #444; }
|
||||
|
||||
/* #Misc
|
||||
================================================== */
|
||||
.remove-bottom { margin-bottom: 0 !important; }
|
||||
.half-bottom { margin-bottom: 10px !important; }
|
||||
.add-bottom { margin-bottom: 20px !important; }
|
||||
|
||||
|
||||
/*
|
||||
* Skeleton V1.1
|
||||
* Copyright 2011, Dave Gamache
|
||||
* www.getskeleton.com
|
||||
* Free to use under the MIT license.
|
||||
* http://www.opensource.org/licenses/mit-license.php
|
||||
* 8/17/2011
|
||||
*/
|
||||
|
||||
/* Table of Content
|
||||
==================================================
|
||||
#Site Styles
|
||||
#Page Styles
|
||||
#Media Queries
|
||||
#Font-Face */
|
||||
|
||||
/* #Site Styles
|
||||
================================================== */
|
||||
|
||||
/* #Page Styles
|
||||
================================================== */
|
||||
|
||||
/* #Media Queries
|
||||
================================================== */
|
||||
|
||||
/* Smaller than standard 960 (devices and browsers) */
|
||||
@media only screen and (max-width: 959px) {}
|
||||
|
||||
/* Tablet Portrait size to standard 960 (devices and browsers) */
|
||||
@media only screen and (min-width: 768px) and (max-width: 959px) {}
|
||||
|
||||
/* All Mobile Sizes (devices and browser) */
|
||||
@media only screen and (max-width: 767px) {}
|
||||
|
||||
/* Mobile Landscape Size to Tablet Portrait (devices and browsers) */
|
||||
@media only screen and (min-width: 480px) and (max-width: 767px) {}
|
||||
|
||||
/* Mobile Portrait Size to Mobile Landscape Size (devices and browsers) */
|
||||
@media only screen and (max-width: 479px) {}
|
||||
|
||||
|
||||
/* #Font-Face
|
||||
================================================== */
|
||||
/* This is the proper syntax for an @font-face file
|
||||
Just create a "fonts" folder at the root,
|
||||
copy your FontName into code below and remove
|
||||
comment brackets */
|
||||
|
||||
/* @font-face {
|
||||
font-family: 'FontName';
|
||||
src: url('../fonts/FontName.eot');
|
||||
src: url('../fonts/FontName.eot?iefix') format('eot'),
|
||||
url('../fonts/FontName.woff') format('woff'),
|
||||
url('../fonts/FontName.ttf') format('truetype'),
|
||||
url('../fonts/FontName.svg#webfontZam02nTh') format('svg');
|
||||
font-weight: normal;
|
||||
font-style: normal; }
|
||||
*//*
|
||||
* Skeleton V1.1
|
||||
* Copyright 2011, Dave Gamache
|
||||
* www.getskeleton.com
|
||||
* Free to use under the MIT license.
|
||||
* http://www.opensource.org/licenses/mit-license.php
|
||||
* 8/17/2011
|
||||
*/
|
||||
|
||||
|
||||
/* Table of Contents
|
||||
==================================================
|
||||
#Base 960 Grid
|
||||
#Tablet (Portrait)
|
||||
#Mobile (Portrait)
|
||||
#Mobile (Landscape)
|
||||
#Clearing */
|
||||
|
||||
|
||||
|
||||
/* #Base 960 Grid
|
||||
================================================== */
|
||||
|
||||
.container { position: relative; width: 960px; margin: 0 auto; padding: 0; }
|
||||
.column, .columns { float: left; display: inline; margin-left: 10px; margin-right: 10px; }
|
||||
.row { margin-bottom: 20px; }
|
||||
|
||||
/* Nested Column Classes */
|
||||
.column.alpha, .columns.alpha { margin-left: 0; }
|
||||
.column.omega, .columns.omega { margin-right: 0; }
|
||||
|
||||
/* Base Grid */
|
||||
.container .one.column { width: 40px; }
|
||||
.container .two.columns { width: 100px; }
|
||||
.container .three.columns { width: 160px; }
|
||||
.container .four.columns { width: 220px; }
|
||||
.container .five.columns { width: 280px; }
|
||||
.container .six.columns { width: 340px; }
|
||||
.container .seven.columns { width: 400px; }
|
||||
.container .eight.columns { width: 460px; }
|
||||
.container .nine.columns { width: 520px; }
|
||||
.container .ten.columns { width: 580px; }
|
||||
.container .eleven.columns { width: 640px; }
|
||||
.container .twelve.columns { width: 700px; }
|
||||
.container .thirteen.columns { width: 760px; }
|
||||
.container .fourteen.columns { width: 820px; }
|
||||
.container .fifteen.columns { width: 880px; }
|
||||
.container .sixteen.columns { width: 940px; }
|
||||
|
||||
.container .one-third.column { width: 300px; }
|
||||
.container .two-thirds.column { width: 620px; }
|
||||
|
||||
/* Offsets */
|
||||
.container .offset-by-one { padding-left: 60px; }
|
||||
.container .offset-by-two { padding-left: 120px; }
|
||||
.container .offset-by-three { padding-left: 180px; }
|
||||
.container .offset-by-four { padding-left: 240px; }
|
||||
.container .offset-by-five { padding-left: 300px; }
|
||||
.container .offset-by-six { padding-left: 360px; }
|
||||
.container .offset-by-seven { padding-left: 420px; }
|
||||
.container .offset-by-eight { padding-left: 480px; }
|
||||
.container .offset-by-nine { padding-left: 540px; }
|
||||
.container .offset-by-ten { padding-left: 600px; }
|
||||
.container .offset-by-eleven { padding-left: 660px; }
|
||||
.container .offset-by-twelve { padding-left: 720px; }
|
||||
.container .offset-by-thirteen { padding-left: 780px; }
|
||||
.container .offset-by-fourteen { padding-left: 840px; }
|
||||
.container .offset-by-fifteen { padding-left: 900px; }
|
||||
|
||||
|
||||
|
||||
/* #Tablet (Portrait)
|
||||
================================================== */
|
||||
|
||||
/* Note: Design for a width of 768px */
|
||||
|
||||
@media only screen and (min-width: 768px) and (max-width: 959px) {
|
||||
.container { width: 768px; }
|
||||
.container .column,
|
||||
.container .columns { margin-left: 10px; margin-right: 10px; }
|
||||
.column.alpha, .columns.alpha { margin-left: 0; margin-right: 10px; }
|
||||
.column.omega, .columns.omega { margin-right: 0; margin-left: 10px; }
|
||||
|
||||
.container .one.column { width: 28px; }
|
||||
.container .two.columns { width: 76px; }
|
||||
.container .three.columns { width: 124px; }
|
||||
.container .four.columns { width: 172px; }
|
||||
.container .five.columns { width: 220px; }
|
||||
.container .six.columns { width: 268px; }
|
||||
.container .seven.columns { width: 316px; }
|
||||
.container .eight.columns { width: 364px; }
|
||||
.container .nine.columns { width: 412px; }
|
||||
.container .ten.columns { width: 460px; }
|
||||
.container .eleven.columns { width: 508px; }
|
||||
.container .twelve.columns { width: 556px; }
|
||||
.container .thirteen.columns { width: 604px; }
|
||||
.container .fourteen.columns { width: 652px; }
|
||||
.container .fifteen.columns { width: 700px; }
|
||||
.container .sixteen.columns { width: 748px; }
|
||||
|
||||
.container .one-third.column { width: 236px; }
|
||||
.container .two-thirds.column { width: 492px; }
|
||||
|
||||
/* Offsets */
|
||||
.container .offset-by-one { padding-left: 48px; }
|
||||
.container .offset-by-two { padding-left: 96px; }
|
||||
.container .offset-by-three { padding-left: 144px; }
|
||||
.container .offset-by-four { padding-left: 192px; }
|
||||
.container .offset-by-five { padding-left: 240px; }
|
||||
.container .offset-by-six { padding-left: 288px; }
|
||||
.container .offset-by-seven { padding-left: 336px; }
|
||||
.container .offset-by-eight { padding-left: 348px; }
|
||||
.container .offset-by-nine { padding-left: 432px; }
|
||||
.container .offset-by-ten { padding-left: 480px; }
|
||||
.container .offset-by-eleven { padding-left: 528px; }
|
||||
.container .offset-by-twelve { padding-left: 576px; }
|
||||
.container .offset-by-thirteen { padding-left: 624px; }
|
||||
.container .offset-by-fourteen { padding-left: 672px; }
|
||||
.container .offset-by-fifteen { padding-left: 720px; }
|
||||
}
|
||||
|
||||
|
||||
/* #Mobile (Portrait)
|
||||
================================================== */
|
||||
|
||||
/* Note: Design for a width of 320px */
|
||||
|
||||
@media only screen and (max-width: 767px) {
|
||||
.container { width: 300px; }
|
||||
.columns, .column { margin: 0; }
|
||||
|
||||
.container .one.column,
|
||||
.container .two.columns,
|
||||
.container .three.columns,
|
||||
.container .four.columns,
|
||||
.container .five.columns,
|
||||
.container .six.columns,
|
||||
.container .seven.columns,
|
||||
.container .eight.columns,
|
||||
.container .nine.columns,
|
||||
.container .ten.columns,
|
||||
.container .eleven.columns,
|
||||
.container .twelve.columns,
|
||||
.container .thirteen.columns,
|
||||
.container .fourteen.columns,
|
||||
.container .fifteen.columns,
|
||||
.container .sixteen.columns,
|
||||
.container .one-third.column,
|
||||
.container .two-thirds.column { width: 300px; }
|
||||
|
||||
/* Offsets */
|
||||
.container .offset-by-one,
|
||||
.container .offset-by-two,
|
||||
.container .offset-by-three,
|
||||
.container .offset-by-four,
|
||||
.container .offset-by-five,
|
||||
.container .offset-by-six,
|
||||
.container .offset-by-seven,
|
||||
.container .offset-by-eight,
|
||||
.container .offset-by-nine,
|
||||
.container .offset-by-ten,
|
||||
.container .offset-by-eleven,
|
||||
.container .offset-by-twelve,
|
||||
.container .offset-by-thirteen,
|
||||
.container .offset-by-fourteen,
|
||||
.container .offset-by-fifteen { padding-left: 0; }
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* #Mobile (Landscape)
|
||||
================================================== */
|
||||
|
||||
/* Note: Design for a width of 480px */
|
||||
|
||||
@media only screen and (min-width: 480px) and (max-width: 767px) {
|
||||
.container { width: 420px; }
|
||||
.columns, .column { margin: 0; }
|
||||
|
||||
.container .one.column,
|
||||
.container .two.columns,
|
||||
.container .three.columns,
|
||||
.container .four.columns,
|
||||
.container .five.columns,
|
||||
.container .six.columns,
|
||||
.container .seven.columns,
|
||||
.container .eight.columns,
|
||||
.container .nine.columns,
|
||||
.container .ten.columns,
|
||||
.container .eleven.columns,
|
||||
.container .twelve.columns,
|
||||
.container .thirteen.columns,
|
||||
.container .fourteen.columns,
|
||||
.container .fifteen.columns,
|
||||
.container .sixteen.columns,
|
||||
.container .one-third.column,
|
||||
.container .two-thirds.column { width: 420px; }
|
||||
}
|
||||
|
||||
|
||||
/* #Clearing
|
||||
================================================== */
|
||||
|
||||
/* Self Clearing Goodness */
|
||||
.container:after { content: "\0020"; display: block; height: 0; clear: both; visibility: hidden; }
|
||||
|
||||
/* Use clearfix class on parent to clear nested columns,
|
||||
or wrap each row of columns in a <div class="row"> */
|
||||
.clearfix:before,
|
||||
.clearfix:after,
|
||||
.row:before,
|
||||
.row:after {
|
||||
content: '\0020';
|
||||
display: block;
|
||||
overflow: hidden;
|
||||
visibility: hidden;
|
||||
width: 0;
|
||||
height: 0; }
|
||||
.row:after,
|
||||
.clearfix:after {
|
||||
clear: both; }
|
||||
.row,
|
||||
.clearfix {
|
||||
zoom: 1; }
|
||||
|
||||
/* You can also use a <br class="clear" /> to clear columns */
|
||||
.clear {
|
||||
clear: both;
|
||||
display: block;
|
||||
overflow: hidden;
|
||||
visibility: hidden;
|
||||
width: 0;
|
||||
height: 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,152 +0,0 @@
|
||||
|
||||
/*** ESSENTIAL STYLES ***/
|
||||
.sf-menu, .sf-menu * {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
list-style: none;
|
||||
}
|
||||
.sf-menu {
|
||||
line-height: 1.0;
|
||||
}
|
||||
.sf-menu ul {
|
||||
position: absolute;
|
||||
top: -999em;
|
||||
width: 10em; /* left offset of submenus need to match (see below) */
|
||||
}
|
||||
.sf-menu ul li {
|
||||
width: 100%;
|
||||
}
|
||||
.sf-menu li:hover {
|
||||
visibility: inherit; /* fixes IE7 'sticky bug' */
|
||||
}
|
||||
.sf-menu li {
|
||||
float: left;
|
||||
position: relative;
|
||||
}
|
||||
.sf-menu a {
|
||||
padding: 5px;
|
||||
display: block;
|
||||
position: relative;
|
||||
}
|
||||
.sf-menu li:hover ul,
|
||||
.sf-menu li.sfHover ul {
|
||||
left: 0;
|
||||
top: 26px; /* match top ul list item height */
|
||||
z-index: 99;
|
||||
}
|
||||
ul.sf-menu li:hover li ul,
|
||||
ul.sf-menu li.sfHover li ul {
|
||||
top: -999em;
|
||||
}
|
||||
ul.sf-menu li li:hover ul,
|
||||
ul.sf-menu li li.sfHover ul {
|
||||
left: 10em; /* match ul width */
|
||||
top: 0;
|
||||
}
|
||||
ul.sf-menu li li:hover li ul,
|
||||
ul.sf-menu li li.sfHover li ul {
|
||||
top: -999em;
|
||||
}
|
||||
ul.sf-menu li li li:hover ul,
|
||||
ul.sf-menu li li li.sfHover ul {
|
||||
left: 10em; /* match ul width */
|
||||
top: 0;
|
||||
}
|
||||
|
||||
/*** DEMO SKIN ***/
|
||||
.sf-menu {
|
||||
float: left;
|
||||
/*margin-bottom: 1em;*/
|
||||
}
|
||||
.sf-menu a {
|
||||
padding-left: 1em;
|
||||
padding-right: 1em;
|
||||
text-decoration:none;
|
||||
}
|
||||
.sf-menu a, .sf-menu a:visited { /* visited pseudo selector so IE6 applies text colour*/
|
||||
// color: #959595;
|
||||
background-color: transparent;
|
||||
font-weight: bold;
|
||||
}
|
||||
.sf-menu li {
|
||||
background-color: transparent;
|
||||
}
|
||||
.sf-menu li li {
|
||||
background: #232323;
|
||||
text-align: left;
|
||||
}
|
||||
.sf-menu li li a {
|
||||
padding-top: 0.25em;
|
||||
padding-bottom: 0.25em;
|
||||
color: #959595;
|
||||
}
|
||||
.sf-menu li li li {
|
||||
background: #232323;
|
||||
text-align: left;
|
||||
}
|
||||
.sf-menu li li li a {
|
||||
padding-top: 0.25em;
|
||||
padding-bottom: 0.25em;
|
||||
color: #959595;
|
||||
}
|
||||
.sf-menu li:hover, .sf-menu a:focus, .sf-menu a:active, .sf-menu li.sfHover, .sf-menu a:hover {
|
||||
color: #FFFFFF;
|
||||
background-color: #303030;
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
|
||||
/*** arrows **/
|
||||
.sf-menu a.sf-with-ul {
|
||||
padding-right: 2.25em;
|
||||
min-width: 1px; /* trigger IE7 hasLayout so spans position accurately */
|
||||
}
|
||||
.sf-sub-indicator {
|
||||
position: absolute;
|
||||
display: block;
|
||||
right: .75em;
|
||||
top: 1.05em; /* IE6 only */
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
text-indent: -999em;
|
||||
overflow: hidden;
|
||||
background: url('../images/arrows-ffffff.png') no-repeat -10px -100px; /* 8-bit indexed alpha png. IE6 gets solid image only */
|
||||
}
|
||||
a > .sf-sub-indicator { /* give all except IE6 the correct values */
|
||||
top: .8em;
|
||||
background-position: 0 -100px; /* use translucent arrow for modern browsers*/
|
||||
}
|
||||
/* apply hovers to modern browsers */
|
||||
a:focus > .sf-sub-indicator,
|
||||
a:hover > .sf-sub-indicator,
|
||||
a:active > .sf-sub-indicator,
|
||||
li:hover > a > .sf-sub-indicator,
|
||||
li.sfHover > a > .sf-sub-indicator {
|
||||
background-position: -10px -100px; /* arrow hovers for modern browsers*/
|
||||
}
|
||||
|
||||
/* point right for anchors in subs */
|
||||
.sf-menu ul .sf-sub-indicator { background-position: -10px 0; }
|
||||
.sf-menu ul a > .sf-sub-indicator { background-position: 0 0; }
|
||||
/* apply hovers to modern browsers */
|
||||
.sf-menu ul a:focus > .sf-sub-indicator,
|
||||
.sf-menu ul a:hover > .sf-sub-indicator,
|
||||
.sf-menu ul a:active > .sf-sub-indicator,
|
||||
.sf-menu ul li:hover > a > .sf-sub-indicator,
|
||||
.sf-menu ul li.sfHover > a > .sf-sub-indicator {
|
||||
background-position: -10px 0; /* arrow hovers for modern browsers*/
|
||||
}
|
||||
|
||||
/*** shadows for all but IE6 ***/
|
||||
.sf-shadow ul {
|
||||
background: url('../images/shadow.png') no-repeat bottom right;
|
||||
padding: 0 8px 9px 0;
|
||||
-moz-border-radius-bottomleft: 17px;
|
||||
-moz-border-radius-topright: 17px;
|
||||
-webkit-border-top-right-radius: 17px;
|
||||
-webkit-border-bottom-left-radius: 17px;
|
||||
}
|
||||
.sf-shadow ul.sf-shadow-off {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,232 @@
|
||||
/*=============================================================
|
||||
CUSTOM RULES
|
||||
==============================================================*/
|
||||
|
||||
body{height:auto;} /* to avoid vertical scroll bar */
|
||||
div.flash.flash-center{left:25%;right:25%;}
|
||||
div.flash.flash-top,div.flash.flash-top:hover{
|
||||
position:relative;
|
||||
display:block;
|
||||
margin:0;
|
||||
padding:1em;
|
||||
top:0;
|
||||
left:0;
|
||||
width:100%;
|
||||
text-align:center;
|
||||
text-shadow:0 1px 0 rgba(255, 255, 255, 0.5);
|
||||
color:#865100;
|
||||
background:#feea9a;
|
||||
border:1px solid;
|
||||
border-top:0px;
|
||||
border-left:0px;
|
||||
border-right:0px;
|
||||
border-radius:0;
|
||||
opacity:1;
|
||||
}
|
||||
#header{margin-top:60px;}
|
||||
.mastheader h1 {
|
||||
margin-bottom:9px;
|
||||
font-size:81px;
|
||||
font-weight:bold;
|
||||
letter-spacing:-1px;
|
||||
line-height:1;
|
||||
font-size:54px;
|
||||
}
|
||||
.mastheader small {
|
||||
font-size:20px;
|
||||
font-weight:300;
|
||||
}
|
||||
/* auth navbar - primitive style */
|
||||
.auth_navbar,.auth_navbar a{color:inherit;}
|
||||
.ie-lte7 .auth_navbar,.auth_navbar a{color:expression(this.parentNode.currentStyle['color']); /* ie7 doesn't support inherit */}
|
||||
.auth_navbar a{white-space:nowrap;} /* to avoid the nav split on more lines */
|
||||
.auth_navbar a:hover{color:white;text-decoration:none;}
|
||||
ul#navbar>.auth_navbar{
|
||||
display:inline-block;
|
||||
padding:5px;
|
||||
}
|
||||
/* form errors message box customization */
|
||||
div.error_wrapper{margin-bottom:9px;}
|
||||
div.error_wrapper .error{
|
||||
border-radius: 4px;
|
||||
-o-border-radius: 4px;
|
||||
-moz-border-radius: 4px;
|
||||
-webkit-border-radius: 4px;
|
||||
}
|
||||
/* below rules are only for formstyle = bootstrap
|
||||
trying to make errors look like bootstrap ones */
|
||||
div.controls .error_wrapper{
|
||||
display:inline-block;
|
||||
margin-bottom:0;
|
||||
vertical-align:middle;
|
||||
}
|
||||
div.controls .error{
|
||||
min-width:5px;
|
||||
background:inherit;
|
||||
color:#B94A48;
|
||||
border:none;
|
||||
padding:0;
|
||||
margin:0;
|
||||
/*display:inline;*/ /* uncommenting this, the animation effect is lost */
|
||||
}
|
||||
div.controls .help-inline{color:#3A87AD;}
|
||||
div.controls .error_wrapper +.help-inline {margin-left:-99999px;}
|
||||
div.controls select +.error_wrapper {margin-left:5px;}
|
||||
.ie-lte7 div.error{color:#fff;}
|
||||
|
||||
/* beautify brand */
|
||||
.navbar-inverse .brand{color:#c6cecc;}
|
||||
.navbar-inverse .brand b{display:inline-block;margin-top:-1px;}
|
||||
.navbar-inverse .brand b>span{font-size:22px;color:white}
|
||||
.navbar-inverse .brand:hover b>span{color:white}
|
||||
/* beautify web2py link in navbar */
|
||||
span.highlighted{color:#d8d800;}
|
||||
.open span.highlighted{color:#ffff00;}
|
||||
|
||||
/*=============================================================
|
||||
OVERRIDING WEB2PY.CSS RULES
|
||||
==============================================================*/
|
||||
|
||||
/* reset to default */
|
||||
a{white-space:normal;}
|
||||
li{margin-bottom:0;}
|
||||
textarea,button{display:block;}
|
||||
/*reset ul padding */
|
||||
ul#navbar{padding:0;}
|
||||
/* label aligned to related input */
|
||||
td.w2p_fl,td.w2p_fc {padding:0;}
|
||||
#web2py_user_form td{vertical-align:middle;}
|
||||
|
||||
/*=============================================================
|
||||
OVERRIDING BOOTSTRAP.CSS RULES
|
||||
==============================================================*/
|
||||
|
||||
/* because web2py handles this via js */
|
||||
textarea { width:90%}
|
||||
.hidden{visibility:visible;}
|
||||
/* right folder for bootstrap black images/icons */
|
||||
[class^="icon-"],[class*=" icon-"]{
|
||||
background-image:url("../images/glyphicons-halflings.png")
|
||||
}
|
||||
/* right folder for bootstrap white images/icons */
|
||||
.icon-white,
|
||||
.nav-tabs > .active > a > [class^="icon-"],
|
||||
.nav-tabs > .active > a > [class*=" icon-"],
|
||||
.nav-pills > .active > a > [class^="icon-"],
|
||||
.nav-pills > .active > a > [class*=" icon-"],
|
||||
.nav-list > .active > a > [class^="icon-"],
|
||||
.nav-list > .active > a > [class*=" icon-"],
|
||||
.navbar-inverse .nav > .active > a > [class^="icon-"],
|
||||
.navbar-inverse .nav > .active > a > [class*=" icon-"],
|
||||
.dropdown-menu > li > a:hover > [class^="icon-"],
|
||||
.dropdown-menu > li > a:hover > [class*=" icon-"],
|
||||
.dropdown-menu > .active > a > [class^="icon-"],
|
||||
.dropdown-menu > .active > a > [class*=" icon-"] {
|
||||
background-image:url("../images/glyphicons-halflings-white.png");
|
||||
}
|
||||
/* bootstrap has a label as input's wrapper while web2py has a div */
|
||||
div>input[type="radio"],div>input[type="checkbox"]{margin:0;}
|
||||
/* bootstrap has button instead of input */
|
||||
input[type="button"], input[type="submit"]{margin-right:8px;}
|
||||
|
||||
/*=============================================================
|
||||
RULES FOR SOLVING CONFLICTS BETWEEN WEB2PY.CSS AND BOOTSTRAP.CSS
|
||||
==============================================================*/
|
||||
|
||||
/*when formstyle=table3cols*/
|
||||
tr#auth_user_remember__row>td.w2p_fw>div{padding-bottom:8px;}
|
||||
td.w2p_fw div>label{vertical-align:middle;}
|
||||
td.w2p_fc {padding-bottom:5px;}
|
||||
/*when formstyle=divs*/
|
||||
div#auth_user_remember__row{margin-top:4px;}
|
||||
div#auth_user_remember__row>.w2p_fl{display:none;}
|
||||
div#auth_user_remember__row>.w2p_fw{min-height:39px;}
|
||||
div.w2p_fw,div.w2p_fc{
|
||||
display:inline-block;
|
||||
vertical-align:middle;
|
||||
margin-bottom:0;
|
||||
}
|
||||
div.w2p_fc{
|
||||
padding-left:5px;
|
||||
margin-top:-8px;
|
||||
}
|
||||
/*when formstyle=ul*/
|
||||
form>ul{
|
||||
list-style:none;
|
||||
margin:0;
|
||||
}
|
||||
li#auth_user_remember__row{margin-top:4px;}
|
||||
li#auth_user_remember__row>.w2p_fl{display:none;}
|
||||
li#auth_user_remember__row>.w2p_fw{min-height:39px;}
|
||||
/*when formstyle=bootstrap*/
|
||||
#auth_user_remember__row label.checkbox{display:block;}
|
||||
span.inline-help{display:inline-block;}
|
||||
input[type="text"].input-xlarge,input[type="password"].input-xlarge{width:270px;}
|
||||
/*when recaptcha is used*/
|
||||
#recaptcha{min-height:30px;display:inline-block;margin-bottom:0;line-height:30px;vertical-align:middle;}
|
||||
td>#recaptcha{margin-bottom:6px;}
|
||||
div>#recaptcha{margin-bottom:9px;}
|
||||
div.control-group.error{
|
||||
width:auto;
|
||||
background:transparent;
|
||||
border:0;
|
||||
color:inherit;
|
||||
padding:0;
|
||||
background-repeat:repeat;
|
||||
}
|
||||
|
||||
/*=============================================================
|
||||
OTHER RULES
|
||||
==============================================================*/
|
||||
|
||||
/* Massimo Di Pierro fixed alignment in forms with list:string */
|
||||
form table tr{margin-bottom:9px;}
|
||||
td.w2p_fw ul{margin-left:0px;}
|
||||
|
||||
/* web2py_console in grid and smartgrid */
|
||||
.hidden{visibility:visible;}
|
||||
.web2py_console input{
|
||||
display: inline-block;
|
||||
margin-bottom: 0;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.web2py_console input[type="submit"],
|
||||
.web2py_console input[type="button"],
|
||||
.web2py_console button{
|
||||
padding-top:4px;
|
||||
padding-bottom:4px;
|
||||
margin:3px 0 0 2px;
|
||||
}
|
||||
.web2py_console a,
|
||||
.web2py_console select,
|
||||
.web2py_console input
|
||||
{
|
||||
margin:3px 0 0 2px;
|
||||
}
|
||||
.web2py_grid form table{width:auto;}
|
||||
/* auth_user_remember checkbox extrapadding in IE fix */
|
||||
.ie-lte9 input#auth_user_remember.checkbox {padding-left:0;}
|
||||
|
||||
/*=============================================================
|
||||
MEDIA QUERIES
|
||||
==============================================================*/
|
||||
|
||||
@media only screen and (max-width:979px){
|
||||
body{padding-top:0px;}
|
||||
#navbar{top:5px;}
|
||||
div.flash{right:5px;}
|
||||
.dropdown-menu ul{visibility:visible;}
|
||||
}
|
||||
@media only screen and (max-width:479px){
|
||||
body{
|
||||
padding-left:10px;
|
||||
padding-right:10px;
|
||||
}
|
||||
.navbar-fixed-top,.navbar-fixed-bottom {
|
||||
margin-left:-10px;
|
||||
margin-right:-10px;
|
||||
}
|
||||
input[type="text"],input[type="password"],select{
|
||||
width:95%;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,122 @@
|
||||
/*=============================================================
|
||||
BOOTSTRAP DROPDOWN MENU
|
||||
==============================================================*/
|
||||
|
||||
.dropdown-menu ul{
|
||||
left:100%;
|
||||
position:absolute;
|
||||
top:0;
|
||||
visibility:hidden;
|
||||
margin-top:-1px;
|
||||
}
|
||||
.dropdown-menu li:hover ul{visibility:visible;}
|
||||
.navbar .dropdown-menu ul:before{
|
||||
border-bottom:7px solid transparent;
|
||||
border-left:none;
|
||||
border-right:7px solid rgba(0, 0, 0, 0.2);
|
||||
border-top:7px solid transparent;
|
||||
left:-7px;
|
||||
top:5px;
|
||||
}
|
||||
.nav > li.dropdown > a:after {
|
||||
border-left: 4px solid transparent;
|
||||
border-right: 4px solid transparent;
|
||||
border-top: 4px solid #000000;
|
||||
content: "";
|
||||
display: inline-block;
|
||||
height: 0;
|
||||
opacity: 0.7;
|
||||
vertical-align: top;
|
||||
width: 0;
|
||||
|
||||
margin-left: 2px;
|
||||
margin-top: 8px;
|
||||
|
||||
border-bottom-color: #FFFFFF;
|
||||
border-top-color: #FFFFFF;
|
||||
}
|
||||
.dropdown-menu span{display:inline-block;}
|
||||
ul.dropdown-menu li.dropdown > a:after {
|
||||
border-left: 4px solid #000;
|
||||
border-right: 4px solid transparent;
|
||||
border-bottom: 4px solid transparent;
|
||||
border-top: 4px solid transparent;
|
||||
content: "";
|
||||
display: inline-block;
|
||||
height: 0;
|
||||
opacity: 0.7;
|
||||
vertical-align: top;
|
||||
width: 0;
|
||||
|
||||
margin-left: 8px;
|
||||
margin-top: 6px;
|
||||
}
|
||||
|
||||
ul.nav li.dropdown:hover ul.dropdown-menu {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.open >.dropdown-menu ul{display:block;} /* fix menu issue when BS2.0.4 is applied */
|
||||
|
||||
/*=============================================================
|
||||
BOOTSTRAP SUBMIT BUTTON
|
||||
==============================================================*/
|
||||
|
||||
input[type='submit']:not(.btn) {
|
||||
display: inline-block;
|
||||
padding: 4px 14px;
|
||||
margin-bottom: 0;
|
||||
font-size: 14px;
|
||||
line-height: 20px;
|
||||
color: #333;
|
||||
text-align: center;
|
||||
text-shadow: 0 1px 1px rgba(255, 255, 255, 0.75);
|
||||
vertical-align: middle;
|
||||
cursor: pointer;
|
||||
background-color: whiteSmoke;
|
||||
background-image: -webkit-gradient(linear,0 0,0 100%,from(white),to(#E6E6E6));
|
||||
background-image: -webkit-linear-gradient(top,white,#E6E6E6);
|
||||
background-image: -o-linear-gradient(top,white,#E6E6E6);
|
||||
background-image: linear-gradient(to bottom,white,#E6E6E6);
|
||||
background-image: -moz-linear-gradient(top,white,#E6E6E6);
|
||||
background-repeat: repeat-x;
|
||||
border: 1px solid #BBB;
|
||||
border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
|
||||
border-bottom-color: #A2A2A2;
|
||||
-webkit-border-radius: 4px;
|
||||
-moz-border-radius: 4px;
|
||||
border-radius: 4px;
|
||||
filter: progid:dximagetransform.microsoft.gradient(startColorstr='#ffffffff',endColorstr='#ffe6e6e6',GradientType=0);
|
||||
filter: progid:dximagetransform.microsoft.gradient(enabled=false);
|
||||
-webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2),0 1px 2px rgba(0, 0, 0, 0.05);
|
||||
-moz-box-shadow: inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);
|
||||
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2),0 1px 2px rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
|
||||
input[type='submit']:not(.btn):hover {
|
||||
color: #333;
|
||||
text-decoration: none;
|
||||
background-color: #E6E6E6;
|
||||
background-position: 0 -15px;
|
||||
-webkit-transition: background-position .1s linear;
|
||||
-moz-transition: background-position .1s linear;
|
||||
-o-transition: background-position .1s linear;
|
||||
transition: background-position .1s linear;
|
||||
}
|
||||
|
||||
input[type='submit']:not(.btn).active, input[type='submit']:not(.btn):active {
|
||||
background-color: #E6E6E6;
|
||||
background-color: #D9D9D9 9;
|
||||
background-image: none;
|
||||
outline: 0;
|
||||
-webkit-box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15),0 1px 2px rgba(0, 0, 0, 0.05);
|
||||
-moz-box-shadow: inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);
|
||||
box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15),0 1px 2px rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
|
||||
/*=============================================================
|
||||
OTHER
|
||||
==============================================================*/
|
||||
|
||||
.ie-lte8 .navbar-fixed-top {position:static;}
|
||||
|
||||
|
Before Width: | Height: | Size: 478 B |
|
After Width: | Height: | Size: 29 KiB |
|
After Width: | Height: | Size: 991 B |
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 198 B |
|
Before Width: | Height: | Size: 6.3 KiB After Width: | Height: | Size: 323 B |
|
After Width: | Height: | Size: 8.6 KiB |
|
After Width: | Height: | Size: 12 KiB |
|
After Width: | Height: | Size: 1.5 KiB |
|
After Width: | Height: | Size: 25 KiB |
|
After Width: | Height: | Size: 5.7 KiB |
|
After Width: | Height: | Size: 78 KiB |
|
After Width: | Height: | Size: 1.1 KiB |
@@ -0,0 +1,44 @@
|
||||
/**
|
||||
|
||||
Created and copyrighted by Massimo Di Pierro <massimo.dipierro@gmail.com>
|
||||
(MIT license)
|
||||
|
||||
Example:
|
||||
|
||||
<script src="share.js"></script>
|
||||
|
||||
**/
|
||||
|
||||
jQuery(function(){
|
||||
var script_source = jQuery('script[src*="share.js"]').attr('src');
|
||||
var params = function(name,default_value) {
|
||||
var match = RegExp('[?&]' + name + '=([^&]*)').exec(script_source);
|
||||
return match && decodeURIComponent(match[1].replace(/\+/g, ' '))||default_value;
|
||||
}
|
||||
var path = params('static','social');
|
||||
var url = encodeURIComponent(window.location.href);
|
||||
var host = window.location.hostname;
|
||||
var title = escape(jQuery('title').text());
|
||||
var twit = 'http://twitter.com/home?status='+title+'%20'+url;
|
||||
var facebook = 'http://www.facebook.com/sharer.php?u='+url;
|
||||
var gplus = 'https://plus.google.com/share?url='+url;
|
||||
var tbar = '<div id="socialdrawer"><span>Share<br/></span><div id="sicons"><a href="'+twit+'" id="twit" title="Share on twitter"><img src="'+path+'/twitter.png" alt="Share on Twitter" width="32" height="32" /></a><a href="'+facebook+'" id="facebook" title="Share on Facebook"><img src="'+path+'/facebook.png" alt="Share on facebook" width="32" height="32" /></a><a href="'+gplus+'" id="gplus" title="Share on Google Plus"><img src="'+path+'/gplus-32.png" alt="Share on Google Plus" width="32" height="32" /></a></div></div>';
|
||||
// Add the share tool bar.
|
||||
jQuery('body').append(tbar);
|
||||
var st = jQuery('#socialdrawer');
|
||||
st.css({'opacity':'.7','z-index':'3000','background':'#FFF','border':'solid 1px #666','border-width':' 1px 0 0 1px','height':'20px','width':'40px','position':'fixed','bottom':'0','right':'0','padding':'2px 5px','overflow':'hidden','-webkit-border-top-left-radius':' 12px','-moz-border-radius-topleft':' 12px','border-top-left-radius':' 12px','-moz-box-shadow':' -3px -3px 3px rgba(0,0,0,0.5)','-webkit-box-shadow':' -3px -3px 3px rgba(0,0,0,0.5)','box-shadow':' -3px -3px 3px rgba(0,0,0,0.5)'});
|
||||
jQuery('#socialdrawer a').css({'float':'left','width':'32px','margin':'3px 2px 2px 2px','padding':'0','cursor':'pointer'});
|
||||
jQuery('#socialdrawer span').css({'float':'left','margin':'2px 3px','text-shadow':' 1px 1px 1px #FFF','color':'#444','font-size':'12px','line-height':'1em'});
|
||||
jQuery('#socialdrawer img').hide();
|
||||
// hover
|
||||
st.click(function(){
|
||||
jQuery(this).animate({height:'40px', width:'160px', opacity: 0.95}, 300);
|
||||
jQuery('#socialdrawer img').show();
|
||||
});
|
||||
//leave
|
||||
st.mouseleave(function(){
|
||||
st.animate({height:'20px', width: '40px', opacity: .7}, 300);
|
||||
jQuery('#socialdrawer img').hide();
|
||||
return false;
|
||||
} );
|
||||
});
|
||||
@@ -1,223 +0,0 @@
|
||||
|
||||
/*
|
||||
* Superfish v1.4.8 - jQuery menu widget
|
||||
* Copyright (c) 2008 Joel Birch
|
||||
*
|
||||
* Dual licensed under the MIT and GPL licenses:
|
||||
* http://www.opensource.org/licenses/mit-license.php
|
||||
* http://www.gnu.org/licenses/gpl.html
|
||||
*
|
||||
* CHANGELOG: http://users.tpg.com.au/j_birch/plugins/superfish/changelog.txt
|
||||
*/
|
||||
|
||||
;(function($){
|
||||
$.fn.superfish = function(op){
|
||||
|
||||
var sf = $.fn.superfish,
|
||||
c = sf.c,
|
||||
$arrow = $(['<span class="',c.arrowClass,'"> »</span>'].join('')),
|
||||
over = function(){
|
||||
var $$ = $(this), menu = getMenu($$);
|
||||
clearTimeout(menu.sfTimer);
|
||||
$$.showSuperfishUl().siblings().hideSuperfishUl();
|
||||
},
|
||||
out = function(){
|
||||
var $$ = $(this), menu = getMenu($$), o = sf.op;
|
||||
clearTimeout(menu.sfTimer);
|
||||
menu.sfTimer=setTimeout(function(){
|
||||
o.retainPath=($.inArray($$[0],o.$path)>-1);
|
||||
$$.hideSuperfishUl();
|
||||
if (o.$path.length && $$.parents(['li.',o.hoverClass].join('')).length<1){over.call(o.$path);}
|
||||
},o.delay);
|
||||
},
|
||||
getMenu = function($menu){
|
||||
var menu = $menu.parents(['ul.',c.menuClass,':first'].join(''))[0];
|
||||
sf.op = sf.o[menu.serial];
|
||||
return menu;
|
||||
},
|
||||
addArrow = function($a){ $a.addClass(c.anchorClass).append($arrow.clone()); };
|
||||
|
||||
return this.each(function() {
|
||||
var s = this.serial = sf.o.length;
|
||||
var o = $.extend({},sf.defaults,op);
|
||||
o.$path = $('li.'+o.pathClass,this).slice(0,o.pathLevels).each(function(){
|
||||
$(this).addClass([o.hoverClass,c.bcClass].join(' '))
|
||||
.filter('li:has(ul)').removeClass(o.pathClass);
|
||||
});
|
||||
sf.o[s] = sf.op = o;
|
||||
|
||||
$('li:has(ul)',this)[($.fn.hoverIntent && !o.disableHI) ? 'hoverIntent' : 'hover'](over,out).each(function() {
|
||||
if (o.autoArrows) addArrow( $('>a:first-child',this) );
|
||||
})
|
||||
.not('.'+c.bcClass)
|
||||
.hideSuperfishUl();
|
||||
|
||||
var $a = $('a',this);
|
||||
$a.each(function(i){
|
||||
var $li = $a.eq(i).parents('li');
|
||||
$a.eq(i).focus(function(){over.call($li);}).blur(function(){out.call($li);});
|
||||
});
|
||||
o.onInit.call(this);
|
||||
|
||||
}).each(function() {
|
||||
var menuClasses = [c.menuClass];
|
||||
if (sf.op.dropShadows && !($.browser.msie && $.browser.version < 7)) menuClasses.push(c.shadowClass);
|
||||
$(this).addClass(menuClasses.join(' '));
|
||||
});
|
||||
};
|
||||
|
||||
var sf = $.fn.superfish;
|
||||
sf.o = [];
|
||||
sf.op = {};
|
||||
sf.IE7fix = function(){
|
||||
var o = sf.op;
|
||||
if ($.browser.msie && $.browser.version > 6 && o.dropShadows && o.animation.opacity!=undefined)
|
||||
this.toggleClass(sf.c.shadowClass+'-off');
|
||||
};
|
||||
sf.c = {
|
||||
bcClass : 'sf-breadcrumb',
|
||||
menuClass : 'sf-js-enabled',
|
||||
anchorClass : 'sf-with-ul',
|
||||
arrowClass : 'sf-sub-indicator',
|
||||
shadowClass : 'sf-shadow'
|
||||
};
|
||||
sf.defaults = {
|
||||
hoverClass : 'sfHover',
|
||||
pathClass : 'overideThisToUse',
|
||||
pathLevels : 1,
|
||||
delay : 800,
|
||||
animation : {opacity:'show'},
|
||||
speed : 'normal',
|
||||
autoArrows : true,
|
||||
dropShadows : true,
|
||||
disableHI : false, // true disables hoverIntent detection
|
||||
onInit : function(){}, // callback functions
|
||||
onBeforeShow: function(){},
|
||||
onShow : function(){},
|
||||
onHide : function(){}
|
||||
};
|
||||
$.fn.extend({
|
||||
hideSuperfishUl : function(){
|
||||
var o = sf.op,
|
||||
not = (o.retainPath===true) ? o.$path : '';
|
||||
o.retainPath = false;
|
||||
var $ul = $(['li.',o.hoverClass].join(''),this).add(this).not(not).removeClass(o.hoverClass)
|
||||
.find('>ul').hide().css('visibility','hidden');
|
||||
o.onHide.call($ul);
|
||||
return this;
|
||||
},
|
||||
showSuperfishUl : function(){
|
||||
var o = sf.op,
|
||||
sh = sf.c.shadowClass+'-off',
|
||||
$ul = this.addClass(o.hoverClass)
|
||||
.find('>ul:hidden').css('visibility','visible');
|
||||
sf.IE7fix.call($ul);
|
||||
o.onBeforeShow.call($ul);
|
||||
$ul.animate(o.animation,o.speed,function(){ sf.IE7fix.call($ul); o.onShow.call($ul); });
|
||||
return this;
|
||||
}
|
||||
});
|
||||
|
||||
})(jQuery);
|
||||
|
||||
|
||||
/*
|
||||
* Supersubs v0.2b - jQuery plugin
|
||||
* Copyright (c) 2008 Joel Birch
|
||||
*
|
||||
* Dual licensed under the MIT and GPL licenses:
|
||||
* http://www.opensource.org/licenses/mit-license.php
|
||||
* http://www.gnu.org/licenses/gpl.html
|
||||
*
|
||||
*
|
||||
* This plugin automatically adjusts submenu widths of suckerfish-style menus to that of
|
||||
* their longest list item children. If you use this, please expect bugs and report them
|
||||
* to the jQuery Google Group with the word 'Superfish' in the subject line.
|
||||
*
|
||||
*/
|
||||
|
||||
;(function($){ // $ will refer to jQuery within this closure
|
||||
|
||||
$.fn.supersubs = function(options){
|
||||
var opts = $.extend({}, $.fn.supersubs.defaults, options);
|
||||
// return original object to support chaining
|
||||
return this.each(function() {
|
||||
// cache selections
|
||||
var $$ = $(this);
|
||||
// support metadata
|
||||
var o = $.meta ? $.extend({}, opts, $$.data()) : opts;
|
||||
// get the font size of menu.
|
||||
// .css('fontSize') returns various results cross-browser, so measure an em dash instead
|
||||
var fontsize = $('<li id="menu-fontsize">—</li>').css({
|
||||
'padding' : 0,
|
||||
'position' : 'absolute',
|
||||
'top' : '-999em',
|
||||
'width' : 'auto'
|
||||
}).appendTo($$).width(); //clientWidth is faster, but was incorrect here
|
||||
// remove em dash
|
||||
$('#menu-fontsize').remove();
|
||||
// cache all ul elements
|
||||
$ULs = $$.find('ul');
|
||||
// loop through each ul in menu
|
||||
$ULs.each(function(i) {
|
||||
// cache this ul
|
||||
var $ul = $ULs.eq(i);
|
||||
// get all (li) children of this ul
|
||||
var $LIs = $ul.children();
|
||||
// get all anchor grand-children
|
||||
var $As = $LIs.children('a');
|
||||
// force content to one line and save current float property
|
||||
var liFloat = $LIs.css('white-space','nowrap').css('float');
|
||||
// remove width restrictions and floats so elements remain vertically stacked
|
||||
var emWidth = $ul.add($LIs).add($As).css({
|
||||
'float' : 'none',
|
||||
'width' : 'auto'
|
||||
})
|
||||
// this ul will now be shrink-wrapped to longest li due to position:absolute
|
||||
// so save its width as ems. Clientwidth is 2 times faster than .width() - thanks Dan Switzer
|
||||
.end().end()[0].clientWidth / fontsize;
|
||||
// add more width to ensure lines don't turn over at certain sizes in various browsers
|
||||
emWidth += o.extraWidth;
|
||||
// restrict to at least minWidth and at most maxWidth
|
||||
if (emWidth > o.maxWidth) { emWidth = o.maxWidth; }
|
||||
else if (emWidth < o.minWidth) { emWidth = o.minWidth; }
|
||||
emWidth += 'em';
|
||||
// set ul to width in ems
|
||||
$ul.css('width',emWidth);
|
||||
// restore li floats to avoid IE bugs
|
||||
// set li width to full width of this ul
|
||||
// revert white-space to normal
|
||||
$LIs.css({
|
||||
'float' : liFloat,
|
||||
'width' : '100%',
|
||||
'white-space' : 'normal'
|
||||
})
|
||||
// update offset position of descendant ul to reflect new width of parent
|
||||
.each(function(){
|
||||
var $childUl = $('>ul',this);
|
||||
var offsetDirection = $childUl.css('left')!==undefined ? 'left' : 'right';
|
||||
$childUl.css(offsetDirection,$ul.width());
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
};
|
||||
// expose defaults
|
||||
$.fn.supersubs.defaults = {
|
||||
minWidth : 9, // requires em unit.
|
||||
maxWidth : 25, // requires em unit.
|
||||
extraWidth : 0 // extra width can ensure lines don't sometimes turn over due to slight browser differences in how they round-off values
|
||||
};
|
||||
|
||||
})(jQuery); // plugin code ends
|
||||
|
||||
/**
|
||||
* hoverIntent r6 // 2011.02.26 // jQuery 1.5.1+
|
||||
* <http://cherne.net/brian/resources/jquery.hoverIntent.html>
|
||||
*
|
||||
* @param f onMouseOver function || An object with configuration options
|
||||
* @param g onMouseOut function || Nothing (use configuration options object)
|
||||
* @author Brian Cherne brian(at)cherne(dot)net
|
||||
*/
|
||||
(function($){$.fn.hoverIntent=function(f,g){var cfg={sensitivity:7,interval:100,timeout:0};cfg=$.extend(cfg,g?{over:f,out:g}:f);var cX,cY,pX,pY;var track=function(ev){cX=ev.pageX;cY=ev.pageY};var compare=function(ev,ob){ob.hoverIntent_t=clearTimeout(ob.hoverIntent_t);if((Math.abs(pX-cX)+Math.abs(pY-cY))<cfg.sensitivity){$(ob).unbind("mousemove",track);ob.hoverIntent_s=1;return cfg.over.apply(ob,[ev])}else{pX=cX;pY=cY;ob.hoverIntent_t=setTimeout(function(){compare(ev,ob)},cfg.interval)}};var delay=function(ev,ob){ob.hoverIntent_t=clearTimeout(ob.hoverIntent_t);ob.hoverIntent_s=0;return cfg.out.apply(ob,[ev])};var handleHover=function(e){var ev=jQuery.extend({},e);var ob=this;if(ob.hoverIntent_t){ob.hoverIntent_t=clearTimeout(ob.hoverIntent_t)}if(e.type=="mouseenter"){pX=ev.pageX;pY=ev.pageY;$(ob).bind("mousemove",track);if(ob.hoverIntent_s!=1){ob.hoverIntent_t=setTimeout(function(){compare(ev,ob)},cfg.interval)}}else{$(ob).unbind("mousemove",track);if(ob.hoverIntent_s==1){ob.hoverIntent_t=setTimeout(function(){delay(ev,ob)},cfg.timeout)}}};return this.bind('mouseenter',handleHover).bind('mouseleave',handleHover)}})(jQuery);
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
// this code improves bootstrap menus and adds dropdown support
|
||||
jQuery(function(){
|
||||
jQuery('.nav>li>a').each(function(){
|
||||
if(jQuery(this).parent().find('ul').length)
|
||||
jQuery(this).attr({'class':'dropdown-toggle','data-toggle':'dropdown'}).append('<b class="caret"></b>');
|
||||
});
|
||||
jQuery('.nav li li').each(function(){
|
||||
if(jQuery(this).find('ul').length)
|
||||
jQuery(this).addClass('dropdown-submenu');
|
||||
});
|
||||
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')});
|
||||
});
|
||||
};
|
||||
}
|
||||
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');
|
||||
});
|
||||
@@ -5,38 +5,32 @@
|
||||
|
||||
<h2>web2py<sup style="font-size:0.5em;">TM</sup> Download</h2>
|
||||
|
||||
<div style="width: 90%; margin: 0 auto;">
|
||||
<center>
|
||||
<center style="padding:20px">
|
||||
<table class="downloads">
|
||||
<tr>
|
||||
<th>Current ({{="%s.%s.%s %s" % (version[0],version[1],version[2],version[4])}})</th>
|
||||
<th>Nightly Build (for testers)</th>
|
||||
<th>Trunk (for developers)</th>
|
||||
<th>plugin_wiki (add-on)</th>
|
||||
<th>For Normal Users</th>
|
||||
<th>For Testers</th>
|
||||
<th>For Developers</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a class="button" href="http://www.web2py.com/examples/static/web2py_win.zip">For Windows</a></td>
|
||||
<td><a class="button" href="http://www.web2py.com/examples/static/nightly/web2py_win.zip">For Windows</a></td>
|
||||
<td><a class="button" href="http://github.com/web2py/web2py/" target="_blank">Git Repository</a></td>
|
||||
<td><a class="button" href="http://web2py.com/examples/static/web2py.plugin.wiki.w2p">Download</a></td>
|
||||
<td><a class="btn btn-180 btn-success" href="http://www.web2py.com/examples/static/web2py_win.zip">For Windows</a></td>
|
||||
<td><a class="btn btn-180 btn-warning" href="http://www.web2py.com/examples/static/nightly/web2py_win.zip">For Windows</a></td>
|
||||
<td><a class="btn btn-180 btn-danger" href="http://github.com/web2py/web2py/">Git Repository</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a class="button" href="http://www.web2py.com/examples/static/web2py_osx.zip">For Mac</a></td>
|
||||
<td><a class="button" href="http://www.web2py.com/examples/static/nightly/web2py_osx.zip">For Mac</a></td>
|
||||
<td><a class="button" href="http://code.google.com/p/web2py/" target="_blank">Mercurial Repository</a></td>
|
||||
<td><a class="button" href="http://code.google.com/p/cube2py/" target="_blank">Mercurial Repository</a>
|
||||
<td><a class="btn btn-180 btn-success" href="http://www.web2py.com/examples/static/web2py_osx.zip">For Mac</a></td>
|
||||
<td><a class="btn btn-180 btn-warning" href="http://www.web2py.com/examples/static/nightly/web2py_osx.zip">For Mac</a></td>
|
||||
<td><a class="btn btn-180 btn-danger" href="http://code.google.com/p/web2py/">Mercurial Repository</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a class="button" href="http://www.web2py.com/examples/static/web2py_src.zip">Source Code</a></td>
|
||||
<td><a class="button" href="http://www.web2py.com/examples/static/nightly/web2py_src.zip">Source Code</a></td>
|
||||
<td><a class="button" href="{{=URL('static', 'epydoc/index.html')}}" target="_blank">Source Code Docs</a></td>
|
||||
<td><a class="button" href="http://vimeo.com/13485916" target="_blank">What is plugin_wiki?</a></td>
|
||||
<td><a class="btn btn-180 btn-success" href="http://www.web2py.com/examples/static/web2py_src.zip">Source Code</a></td>
|
||||
<td><a class="btn btn-180 btn-warning" href="http://www.web2py.com/examples/static/nightly/web2py_src.zip">Source Code</a></td>
|
||||
<td><a class="btn btn-180 btn-danger" href="{{=URL('static', 'epydoc/index.html')}}">Epydoc</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a class="button" href="{{=URL('changelog')}}">Change Log</a></td>
|
||||
<td><a class="button" href="http://www.web2py.com/examples/static/nightly/tests.log">Unittest Log</a></td>
|
||||
<td><a class="button" href="http://code.google.com/p/web2py/issues/list" target="_blank">Issue Tracker</a></td>
|
||||
<td></td>
|
||||
<td><a class="btn btn-180 btn-success" href="https://dl.dropbox.com/u/18065445/web2py/web2py_manual_5th.pdf">Manual</a></td>
|
||||
<td><a class="btn btn-180" href="{{=URL('changelog')}}">Change Log</a></td>
|
||||
<td><a class="btn btn-180" href="http://code.google.com/p/web2py/issues/list">Report a Bug</a></td>
|
||||
</tr>
|
||||
</table>
|
||||
</center>
|
||||
@@ -64,28 +58,28 @@
|
||||
<p>Applications built with web2py can be released under any license the author wishes as long they do not contain web2py code. They can link unmodified web2py libraries and they can be distributed with official web2py binaries. In particular web2py applications can be distributed in closed source. The admin interface provides a button to byte-code compile.</p>
|
||||
<p>It is fine to distribute web2py (source or compiled) with your applications as long as you make it clear in the license where your application ends and web2py starts.</p>
|
||||
<p>web2py is copyrighted by Massimo Di Pierro. The web2py trademark is owned by Massimo Di Pierro.</p>
|
||||
[<a href="{{=URL('license')}}">read more</a>]
|
||||
<a class="btn btn-small" href="{{=URL('license')}}">read more</a>
|
||||
|
||||
<h3>Artwork</h3>
|
||||
<center>
|
||||
<a href="{{=URL('static', 'images/logo_lb.png')}}"><img src="{{=URL('static', 'images/logo_lb.png')}}" width="200px"/></a>
|
||||
<a href="{{=URL('static', 'images/logo_db.png')}}"><img src="{{=URL('static', '\
|
||||
images/logo_db.png')}}" width="200px"/></a>
|
||||
<a href="{{=URL('static', 'images/logo_bw.png')}}"><img src="{{=URL('static', '\
|
||||
images/logo_bw.png')}}" width="200px"/></a>
|
||||
</center>
|
||||
<h3>Stickers</h3>
|
||||
<center>
|
||||
<a href="{{=URL('static', 'images/Stickers1.png')}}"><img src="{{=URL('static', 'images/Stickers1.png')}}" /></a>
|
||||
<a href="{{=URL('static', 'images/Stickers2.png')}}"><img src="{{=URL('static', 'images/Stickers2.png')}}" /></a>
|
||||
<a href="{{=URL('static', 'images/Stickers3.png')}}"><img src="{{=URL('static', 'images/Stickers3.png')}}" /></a>
|
||||
<a href="{{=URL('static', 'images/Stickers4.png')}}"><img src="{{=URL('static', 'images/Stickers4.png')}}" /></a>
|
||||
<center>
|
||||
<a href="{{=URL('static', 'images/logo_lb.png')}}"><img src="{{=URL('static', 'images/logo_lb.png')}}" width="200px"/></a>
|
||||
<a href="{{=URL('static', 'images/logo_db.png')}}"><img src="{{=URL('static', '\
|
||||
images/logo_db.png')}}" width="200px"/></a>
|
||||
<a href="{{=URL('static', 'images/logo_bw.png')}}"><img src="{{=URL('static', '\
|
||||
images/logo_bw.png')}}" width="200px"/></a>
|
||||
</center>
|
||||
<h3>Stickers</h3>
|
||||
<center>
|
||||
<a href="{{=URL('static', 'images/Stickers1.png')}}"><img src="{{=URL('static', 'images/Stickers1.png')}}" /></a>
|
||||
<a href="{{=URL('static', 'images/Stickers2.png')}}"><img src="{{=URL('static', 'images/Stickers2.png')}}" /></a>
|
||||
<a href="{{=URL('static', 'images/Stickers3.png')}}"><img src="{{=URL('static', 'images/Stickers3.png')}}" /></a>
|
||||
<a href="{{=URL('static', 'images/Stickers4.png')}}"><img src="{{=URL('static', 'images/Stickers4.png')}}" /></a>
|
||||
<a href="{{=URL('static', 'images/Stickers5.png')}}"><img src="{{=URL('static', 'images/Stickers5.png')}}" /></a>
|
||||
<a href="{{=URL('static', 'images/Stickers6.png')}}"><img src="{{=URL('static', 'images/Stickers6.png')}}" /></a>
|
||||
<a href="{{=URL('static', 'images/Stickers7.png')}}"><img src="{{=URL('static', 'images/Stickers7.png')}}" /></a>
|
||||
<a href="{{=URL('static', 'images/Stickers8.png')}}"><img src="{{=URL('static', 'images/Stickers8.png')}}" /></a>
|
||||
</center>
|
||||
|
||||
<a href="{{=URL('static', 'images/Stickers8.png')}}"><img src="{{=URL('static', 'images/Stickers8.png')}}" /></a>
|
||||
</center>
|
||||
<p></p>
|
||||
<p>
|
||||
<a href="{{=URL('static', 'artwork.tar.gz')}}" >Download WEB2PY artwork pack in editable .png format</a>
|
||||
</p>
|
||||
@@ -99,6 +93,3 @@
|
||||
Icon set made by <a href="http://chrfb.deviantart.com">Christian Burprich</a> licensed under a <a rel="license" target="_blank" href="http://creativecommons.org/licenses/by-nc-sa/3.0/">Creative Commons Attribution-Noncommercial-Share Alike 3.0 License</a>
|
||||
</p>
|
||||
|
||||
{{block sidebar}}{{end}}
|
||||
{{block leftbadges}}{{end}}
|
||||
</div>
|
||||
|
||||
@@ -119,7 +119,6 @@ def raiseexception():
|
||||
return 'oops'
|
||||
""".strip(),language='web2py',link=URL('global','vars'),_class='boxCode')}}
|
||||
<p>If an exception occurs (other than HTTP) a ticket is generated and the event is logged for the administrator. These tickets and logs can be accessed, reviewed and deleted at any later time.
|
||||
<br/>Try it here: <a href="/{{=request.application}}/simple_examples/raiseexception">raiseexception</a></p>
|
||||
|
||||
<h3>Example {{=c}}{{c+=1}}</h3><b>In controller: simple_examples.py</b>
|
||||
{{=CODE("""
|
||||
@@ -605,7 +604,7 @@ def fade():
|
||||
|
||||
<h3>Excel-like spreadsheet via Ajax</h3>
|
||||
Web2py includes a widget that acts like an Excel-like spreadsheet and can be used to build forms
|
||||
[<a href="{{=URL('spreadsheet','index')}}">read more</a>].
|
||||
<a class="btn btn-small" href="{{=URL('spreadsheet','index')}}">read more</a>.
|
||||
|
||||
<h2 id="testing_examples">Testing Examples</h2>
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
{{right_sidebar_enabled=True}}
|
||||
{{extend 'layout.html'}}
|
||||
{{
|
||||
import random
|
||||
@@ -14,73 +13,70 @@ quotes = [
|
||||
random.shuffle(quotes)
|
||||
}}
|
||||
|
||||
<table width="100%">
|
||||
<tr>
|
||||
<td>
|
||||
<a href="http://web2py.com/book">
|
||||
<img src="{{=URL('static','images/book-4th.png')}}" />
|
||||
</a>
|
||||
</td>
|
||||
<td>
|
||||
<a href="http://link.packtpub.com/SUlnrN">
|
||||
<img src="{{=URL('static','images/book-recipes.png')}}" />
|
||||
</a>
|
||||
</td>
|
||||
<td>
|
||||
<a href="http://www.youtube.com/playlist?list=PL5E2E223FE3777851">
|
||||
<img src="{{=URL('static','images/videos.png')}}" />
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
|
||||
<h3>WEB2PY<sup>TM</sup> WEB FRAMEWORK</h3>
|
||||
<p>Free open source full-stack framework for rapid development of fast, scalable, <a href="http://www.web2py.com/book/default/chapter/01#security" target="_blank">secure</a> and portable database-driven web-based applications. Written and programmable in <a href="http://www.python.org" target="_blank">Python</a>. <a href="http://www.gnu.org/licenses/lgpl.html">LGPLv3 License</a>.
|
||||
Current version: {{="%s.%s.%s (%s) %s" % request.env.web2py_version}}</p>
|
||||
|
||||
{{block extra}}
|
||||
<div class="container aboutW2P">
|
||||
<div class="sixteen columns">
|
||||
<div class="one-third column alpha">
|
||||
<h3><a href="{{=URL('what')}}">BATTERIES INCLUDED</a></h3>
|
||||
<p>Everything you need in one package including fast multi-threaded web server, SQL database and web-based interface. No third party dependencies but works with <a href={{=URL('what')}}>third party tools</a>.</p>
|
||||
<div class="row-fluid">
|
||||
<div class="span12">
|
||||
<div class="span8">
|
||||
<h3>web2py<sup>TM</sup> Web Framework</h3>
|
||||
<p>Free open source full-stack framework for rapid development of fast, scalable, <a href="http://www.web2py.com/book/default/chapter/01#Security" target="_blank">secure</a> and portable database-driven web-based applications. Written and programmable in <a href="http://www.python.org" target="_blank">Python</a>.</p>
|
||||
<table width="100%">
|
||||
<tr>
|
||||
<td>
|
||||
<a href="http://web2py.com/book">
|
||||
<img src="{{=URL('static','images/book-5th.png')}}" />
|
||||
</a>
|
||||
</td>
|
||||
<td>
|
||||
<a href="http://link.packtpub.com/SUlnrN">
|
||||
<img src="{{=URL('static','images/book-recipes.png')}}" />
|
||||
</a>
|
||||
</td>
|
||||
<td>
|
||||
<a href="http://www.youtube.com/playlist?list=PL5E2E223FE3777851">
|
||||
<img src="{{=URL('static','images/videos.png')}}" />
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<p>Current version: <a href="{{=URL('download')}}">{{=request.env.web2py_version}} (<a href="http://www.gnu.org/licenses/lgpl.html">LGPLv3 License</a>)</p>
|
||||
</div>
|
||||
<div class="one-third column">
|
||||
<h3><a href="http://web2py.com/demo_admin">WEB-BASED IDE</a></h3>
|
||||
<p>Create, modify, deploy and manage application from anywhere using your browser. One web2py instance can run multiple web sites using different databases. Try the <a href="http://web2py.com/demo_admin">interactive demo</a>.</p>
|
||||
</div>
|
||||
<div class="one-third column omega">
|
||||
<h3><a href="{{=URL('documentation')}}">EXTENSIVE DOCS</a></h3>
|
||||
<p>Start with some <a href="{{=URL('examples')}}">quick examples</a>, then read the <a href="http://web2py.com/book" target="_blank">manual</a>, watch <a href="http://vimeo.com/album/178500" target="_blank">videos</a>, and join a <a href="{{=URL('default', 'usergroups')}}">user group</a> for discussion. Take advantage of the <a href="http://web2py.com/layouts" target="_blank">layouts</a>, <a href="http://dev.s-cubism.com/web2py_plugins" target="_blank">plugins</a>, <a href="http://www.web2py.com/appliances" target="_blank">appliances</a>, and <a href="http://web2pyslices.com" target="_blank">recipes</a>.</p>
|
||||
<div class="span4" style="text-align:center">
|
||||
<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 Powered by web2py</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<img class="scale-with-grid centered" src="/examples/static/images/shadow-bottom.png">
|
||||
<div class="container userQuotes">
|
||||
<div class="sixteen columns">
|
||||
<!-- img src="{{=URL('static','images/shadow-bottom.png')}}" width="100%"/ -->
|
||||
<div class="row-fluid">
|
||||
<div class="span12">
|
||||
<div class="span4">
|
||||
<h3><a href="{{=URL('what')}}">Batteries Included</a></h3>
|
||||
<p>Everything you need in one package including fast multi-threaded web server, SQL database and web-based interface. No third party dependencies but works with <a href={{=URL('what')}}>third party tools</a>.</p>
|
||||
</div>
|
||||
<div class="span4">
|
||||
<h3><a href="http://web2py.com/demo_admin">Web-Based IDE</a></h3>
|
||||
<p>Create, modify, deploy and manage application from anywhere using your browser. One web2py instance can run multiple web sites using different databases. Try the <a href="http://www.web2py.com/demo_admin">interactive demo</a>.</p>
|
||||
</div>
|
||||
<div class="span4">
|
||||
<h3><a href="{{=URL('documentation')}}">Extensive Docs</a></h3>
|
||||
<p>Start with some <a href="{{=URL('examples')}}">quick examples</a>, then read the <a href="http://www.web2py.com/book" target="_blank">manual</a>, watch <a href="http://vimeo.com/album/178500" target="_blank">videos</a>, and join a <a href="{{=URL('default', 'usergroups')}}">user group</a> for discussion. Take advantage of the <a href="http://www.web2py.com/layouts" target="_blank">layouts</a>, <a href="http://dev.s-cubism.com/web2py_plugins" target="_blank">plugins</a>, <a href="http://www.web2py.com/appliances" target="_blank">appliances</a>, and <a href="http://web2pyslices.com" target="_blank">recipes</a>.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row-fluid">
|
||||
<div class="span12">
|
||||
<img class="scale-with-grid centered" src="/examples/static/images/shadow-bottom.png">
|
||||
</div>
|
||||
</div>
|
||||
<div class="row-fluid">
|
||||
<div class="span12">
|
||||
{{for k,quote in enumerate(quotes[:3]):}}
|
||||
<div class="one-third column {{=[' alpha', '', ' omega'][k]}}">
|
||||
<em>
|
||||
<p>{{=quote[0]}}</p>
|
||||
</em>
|
||||
<div class="span4">
|
||||
<p style="text-align: left"><em>{{=quote[0]}}</em></p>
|
||||
<span class="right">
|
||||
<a href="{{=quote[2]}}"><em>—{{=quote[1]}}</em></a>
|
||||
<a href="{{=quote[2]}}">{{=quote[1]}}</a>
|
||||
</span>
|
||||
</div>
|
||||
{{pass}}
|
||||
</div>
|
||||
</div>
|
||||
{{end}}
|
||||
|
||||
{{block right_sidebar}}
|
||||
<div class="one-third column" style="text-align:center">
|
||||
<img class="scale-with-grid centered" src="{{=URL('static','images/tag-cloud-color-small.png')}}" width="300px"/>
|
||||
<br/>
|
||||
<a class="button" href="{{=URL('download')}}" style="width:90%">DOWNLOAD NOW</a><br/>
|
||||
<a class="button" href="http://web2py.com/demo_admin" style="width:90%">ONLINE DEMO</a><br/>
|
||||
<a class="button" href="http://web2py.com/poweredby" style="width:90%">SITES POWERED BY WEB2PY</a><br/>
|
||||
<a class="button" href="http://www.chipin.com/contribute/id/dcd384d58839aa4d" style="width:90%">SUPPORT/DONATE</a></br>
|
||||
</div>
|
||||
{{end}}
|
||||
|
||||
@@ -147,8 +147,7 @@
|
||||
|
||||
<li><a href="http://www.python.org">Python</a> created by Guido van Rossum.</li>
|
||||
<li>Rocket Web Server developed by Timothy Farrell.</li>
|
||||
<li><a href="http://www.cdolivet.com/index.php?page=editArea">EditArea</a> developed by Christophe Dolivet</li>
|
||||
<li><a href="http://nicedit.com">nicEdit</a> developed by <a href="http://bkirchoff.com">Brian Kirchoff</a></li>
|
||||
<li><a href="http://codemirror.net/">CodeMirror</a></li>
|
||||
<li><a href="http://cheeseshop.python.org/pypi/simplejson">simplejson</a> developed by Bob Ippolito</li>
|
||||
<li><a href="http://pyrtf.sourceforge.net/">PyRTF</a> developed by Simon Cusack and revised by Grant Edwards</li>
|
||||
<li><a href="http://www.dalkescientific.com/Python/PyRSS2Gen.html">PyRSS2Gen</a> developed by Dalke Scientific Software</li>
|
||||
@@ -159,8 +158,8 @@
|
||||
<li><a href="http://jquery.com/">jQuery</a> developed by John Resig</li>
|
||||
<li>A syntax highlighter inspired by the code of <a href="http://www.petersblog.org/node/763">Peter Wilkinson</a></li>
|
||||
<li><a href="https://github.com/jtauber/pyuca">pyUCA</a> developed by <a href="http://jtauber.com/blog/2006/01/27/python_unicode_collation_algorithm/">James Tauber</a></li>
|
||||
|
||||
</ul>
|
||||
(... and other third party modules in the contrib folder).
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
@@ -2,46 +2,53 @@
|
||||
{{import cgi}}
|
||||
|
||||
<div class="contentleft">
|
||||
<h1>{{=T('Docs for')}} {{=title}}</h1>
|
||||
|
||||
<div align="right">
|
||||
<h1>{{=T('Docs for')}} {{=title}}</h1>
|
||||
|
||||
<div align="right">
|
||||
[ <a href="http://docs.python.org/tut/">Python Tutorial</a> ]
|
||||
[ <a href="http://docs.python.org/lib/">Python Libraries</a> ]
|
||||
[ <a href="/{{=request.application}}/static/epydoc/index.html">web2py epydoc</a> ]
|
||||
</div>
|
||||
|
||||
<h2>{{=T('Description')}}</h2>
|
||||
|
||||
<br/>
|
||||
{{if t:}}
|
||||
{{=t}}{{if d:}} extends {{=d}}{{pass}}
|
||||
{{pass}}
|
||||
<br/>
|
||||
{{pass}}
|
||||
|
||||
{{if doc:}}<br/><br/>{{=CODE(str(doc),language=None,counter=None,_class='boxCode')}}{{pass}}
|
||||
<br/><br/>
|
||||
<div class="boxInfo">
|
||||
</div>
|
||||
|
||||
<h2>{{=T('Description')}}</h2>
|
||||
|
||||
<br/>
|
||||
{{if t:}}
|
||||
{{=t}}{{if d:}} extends {{=d}}{{pass}}
|
||||
{{pass}}
|
||||
<br/>
|
||||
{{pass}}
|
||||
|
||||
{{if doc:}}<br/><br/>{{=MARKMIN(doc)}}{{pass}}
|
||||
<br/><br/>
|
||||
<div class="boxInfo">
|
||||
{{if attributes:}}
|
||||
<h2>{{=T('Attributes')}}</h2>
|
||||
|
||||
{{keys=attributes.keys(); keys.sort()}}
|
||||
|
||||
<table>
|
||||
<tr><td colspan=2><hr/></td></tr>
|
||||
{{for a in keys:}}
|
||||
{{doc1,t1,c1,d1=attributes[a]}}
|
||||
<tr>
|
||||
<td><b>{{#=a}}</b>{{=A(a,_href=URL(r=request,args=a.split('.')))}}</td>
|
||||
<td>
|
||||
{{if t1:}}
|
||||
{{=t1}}{{if d1:}} extends {{=d1}}{{pass}}
|
||||
{{if c1:}} belongs to class {{=c1}}{{pass}}
|
||||
<br/>
|
||||
{{pass}}
|
||||
{{if doc1:}}{{=XML(cgi.escape(str(doc1)).replace(chr(13),'<br/>'))}}{{pass}}
|
||||
<tr><td colspan=2><hr/></td></tr>
|
||||
{{for key in sorted(attributes):}}
|
||||
{{doc1,t1,c1,d1=attributes[key]}}
|
||||
<tr>
|
||||
<td>
|
||||
{{if key.count('.')<2:}}
|
||||
{{=A(key,_rel="nofollow",_href=URL(args=key.split('.')))}}
|
||||
{{else:}}
|
||||
{{=key}}
|
||||
{{pass}}
|
||||
</td>
|
||||
<td>
|
||||
{{if t1:}}
|
||||
{{=t1}}{{if d1:}} extends {{=d1}}{{pass}}
|
||||
{{if c1:}} belongs to class {{=c1}}{{pass}}
|
||||
<br/>
|
||||
{{pass}}
|
||||
{{if doc1:}}{{=MARKMIN(doc1)}}{{pass}}
|
||||
</td>
|
||||
</tr>
|
||||
<tr><td colspan=2><hr/></td></tr>
|
||||
{{pass}}
|
||||
</tr>
|
||||
<tr><td colspan=2><hr/></td></tr>
|
||||
{{pass}}
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
{{pass}}
|
||||
</div>
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
<!--[if HTML5]><![endif]-->
|
||||
<!DOCTYPE html>
|
||||
<!-- paulirish.com/2008/conditional-stylesheets-vs-css-hacks-answer-neither/ -->
|
||||
<!--[if lt IE 7]><html class="ie ie6 ie-lte9 ie-lte8 ie-lte7 no-js" lang="{{=T.accepted_language or 'en'}}"> <![endif]-->
|
||||
@@ -6,139 +7,167 @@
|
||||
<!--[if IE 9]><html class="ie9 ie-lte9 no-js" lang="{{=T.accepted_language or 'en'}}"> <![endif]-->
|
||||
<!--[if (gt IE 9)|!(IE)]><!--> <html class="no-js" lang="{{=T.accepted_language or 'en'}}"> <!--<![endif]-->
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<title>{{=response.title or request.application}}</title>
|
||||
<!--[if !HTML5]>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge{{=not request.is_local and ',chrome=1' or ''}}">
|
||||
<![endif]-->
|
||||
<!-- www.phpied.com/conditional-comments-block-downloads/ -->
|
||||
<!-- Always force latest IE rendering engine
|
||||
(even in intranet) & Chrome Frame
|
||||
Remove this if you use the .htaccess -->
|
||||
<!--[if IE]>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<![endif]-->
|
||||
|
||||
<title>{{=response.title or request.application}}</title>
|
||||
|
||||
(even in intranet) & Chrome Frame
|
||||
Remove this if you use the .htaccess -->
|
||||
|
||||
<meta charset="utf-8" />
|
||||
|
||||
<!-- http://dev.w3.org/html5/markup/meta.name.html -->
|
||||
<meta name="application-name" content="{{=request.application}}" />
|
||||
|
||||
|
||||
<!-- Speaking of Google, don't forget to set your site up:
|
||||
http://google.com/webmasters -->
|
||||
http://google.com/webmasters -->
|
||||
<meta name="google-site-verification" content="" />
|
||||
|
||||
<!-- Mobile Viewport Fix
|
||||
j.mp/mobileviewport & davidbcalhoun.com/2010/viewport-metatag
|
||||
device-width: Occupy full width of the screen in its current orientation
|
||||
initial-scale = 1.0 retains dimensions instead of zooming out if page height > device height
|
||||
user-scalable = yes allows the user to zoom in -->
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
|
||||
|
||||
<!-- Place favicon.ico and apple-touch-icon.png in the root of your domain and delete these references -->
|
||||
<link rel="shortcut icon" href="{{=URL('static','favicon.ico')}}" type="image/x-icon">
|
||||
<link rel="apple-touch-icon" href="{{=URL('static','favicon.png')}}">
|
||||
j.mp/mobileviewport & davidbcalhoun.com/2010/viewport-metatag
|
||||
device-width: Occupy full width of the screen in its current orientation
|
||||
initial-scale = 1.0 retains dimensions instead of zooming out if page height > device height
|
||||
user-scalable = yes allows the user to zoom in -->
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
|
||||
<!-- All JavaScript at the bottom, except for Modernizr which enables
|
||||
HTML5 elements & feature detects -->
|
||||
<script src="{{=URL('static','js/modernizr.custom.js')}}"></script>
|
||||
<link rel="shortcut icon" href="{{=URL('static','images/favicon.ico')}}" type="image/x-icon">
|
||||
<link rel="apple-touch-icon" href="{{=URL('static','images/favicon.png')}}">
|
||||
|
||||
<!-- All JavaScript at the bottom, except for Modernizr which enables
|
||||
HTML5 elements & feature detects -->
|
||||
<script src="{{=URL('static','js/modernizr.custom.js')}}"></script>
|
||||
|
||||
<!-- include stylesheets -->
|
||||
{{
|
||||
response.files.append(URL('static','css/skeleton.css'))
|
||||
{{
|
||||
response.files.append(URL('static','css/web2py.css'))
|
||||
response.files.append(URL('static','css/bootstrap.min.css'))
|
||||
response.files.append(URL('static','css/bootstrap-responsive.min.css'))
|
||||
response.files.append(URL('static','css/web2py_bootstrap.css'))
|
||||
response.files.append(URL('static','css/examples.css'))
|
||||
response.files.append(URL('static','css/superfish.css'))
|
||||
response.files.append(URL('static','js/superfish.js'))
|
||||
}}
|
||||
|
||||
{{include 'web2py_ajax.html'}}
|
||||
|
||||
<script type="text/javascript">
|
||||
jQuery(function(){jQuery('.sf-menu').superfish();});
|
||||
</script>
|
||||
|
||||
{{
|
||||
# using sidebars need to know what sidebar you want to use
|
||||
left_sidebar_enabled = globals().get('left_sidebar_enabled',False)
|
||||
right_sidebar_enabled = globals().get('right_sidebar_enabled',False)
|
||||
middle_columns = {0:'span12',1:'span9',2:'span6'}[
|
||||
(left_sidebar_enabled and 1 or 0)+(right_sidebar_enabled and 1 or 0)]
|
||||
}}
|
||||
|
||||
<!-- uncomment here to load jquery-ui
|
||||
<link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.16/themes/base/jquery-ui.css" type="text/css" media="all" />
|
||||
<script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.16/jquery-ui.min.js" type="text/javascript"></script>
|
||||
uncomment to load jquery-ui //-->
|
||||
</style>
|
||||
<link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.16/themes/base/jquery-ui.css" type="text/css" media="all" />
|
||||
<script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.16/jquery-ui.min.js" type="text/javascript"></script>
|
||||
uncomment to load jquery-ui //-->
|
||||
<noscript><link href="{{=URL('static', 'css/web2py_bootstrap_nojs.css')}}" rel="stylesheet" type="text/css" /></noscript>
|
||||
{{block head}}{{end}}
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="wrapper"><!-- for sticky footer -->
|
||||
<div class="flash">{{=response.flash or ''}}</div>
|
||||
<div class="header">
|
||||
<!-- Navbar ================================================== -->
|
||||
<div class="navbar navbar-inverse navbar-fixed-top">
|
||||
<div class="flash">{{=response.flash or ''}}</div>
|
||||
<div class="navbar-inner">
|
||||
<div class="container">
|
||||
<div class="sixteen columns">
|
||||
<img src="{{=URL('static','images/web2py_logo.png')}}" class="logo" alt="web2py logo" />
|
||||
<h5>{{=response.subtitle or ''}}</h5>
|
||||
</div>
|
||||
|
||||
<div class="sixteen columns statusbar">
|
||||
{{block statusbar}}
|
||||
{{is_mobile=request.user_agent().is_mobile}}
|
||||
<div id="menu" class="clearfix">{{=MENU(response.menu,_class='mobile-menu' if is_mobile else 'sf-menu',mobile=is_mobile)}}
|
||||
{{end}}
|
||||
<!-- AddToAny BEGIN -->
|
||||
<div style="float:right;padding-top:6px;" class="a2a_kit a2a_default_style">
|
||||
<a class="a2a_dd" href="http://www.addtoany.com/share_save">Share</a></div>
|
||||
<script type="text/javascript" src="http://static.addtoany.com/menu/page.js"></script>
|
||||
<!-- AddToAny END -->
|
||||
</div>
|
||||
</div>
|
||||
<div class="sixteen columns announce">
|
||||
<a href="http://www.infoworld.com/slideshow/24605/infoworlds-2012-technology-of-the-year-award-winners-183313#slide23"target="_blank">InfoWorld's 2012 Technology of the Year Award Winner</a>
|
||||
</div>
|
||||
<!-- the next tag is necessary for bootstrap menus, do not remove -->
|
||||
<button type="button" class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
</button>
|
||||
{{=response.logo or ''}}
|
||||
<ul id="navbar" class="nav pull-right">{{='auth' in globals() and auth.navbar(mode="dropdown") or ''}}</ul>
|
||||
<div class="nav-collapse">
|
||||
{{is_mobile=request.user_agent().is_mobile}}
|
||||
{{if response.menu:}}
|
||||
{{=MENU(response.menu, _class='mobile-menu nav' if is_mobile else 'nav',mobile=is_mobile,li_class='dropdown',ul_class='dropdown-menu')}}
|
||||
{{pass}}
|
||||
</div><!--/.nav-collapse -->
|
||||
</div>
|
||||
</div>
|
||||
<div class="main">
|
||||
<div class="container mainbody">
|
||||
<div class="sixteen columns">
|
||||
<div class="{{=right_sidebar_enabled and 'two-thirds column alpha' or 'sixteen columns alpha omega'}}">
|
||||
</div><!--/top navbar -->
|
||||
|
||||
<div class="container">
|
||||
<!-- Masthead ================================================== -->
|
||||
<header class="mastheader" id="header">
|
||||
<div class="span4">
|
||||
<div class="page-header">
|
||||
<img src="{{=URL('static','images/web2py_logo.png')}}" class="logo" alt="web2py logo" />
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
</div>
|
||||
<div class="container">
|
||||
|
||||
<section id="main" class="main row">
|
||||
{{if left_sidebar_enabled:}}
|
||||
<div class="span3 left-sidebar">
|
||||
{{block left_sidebar}}
|
||||
<h3>Left Sidebar</h3>
|
||||
<p></p>
|
||||
{{end}}
|
||||
</div>
|
||||
{{pass}}
|
||||
|
||||
<div class="{{=middle_columns}}">
|
||||
{{block center}}
|
||||
{{include}}
|
||||
{{end}}
|
||||
</div>
|
||||
|
||||
{{if right_sidebar_enabled:}}
|
||||
<div class="one-third column omega">
|
||||
</div>
|
||||
|
||||
{{if right_sidebar_enabled:}}
|
||||
<div class="span3">
|
||||
{{block right_sidebar}}
|
||||
<h3>Right Sidebar</h3>
|
||||
<p></p>
|
||||
{{end}}
|
||||
</div>
|
||||
{{pass}}
|
||||
</div>
|
||||
</div><!-- container -->
|
||||
{{block extra}}{{end}}
|
||||
|
||||
</div><!-- main -->
|
||||
|
||||
<div class="push"></div>
|
||||
</div><!-- wrapper -->
|
||||
{{pass}}
|
||||
</section><!--/main-->
|
||||
|
||||
<div class="footer">
|
||||
<div class="container header">
|
||||
<div class="sixteen columns">
|
||||
{{block footer}} <!-- this is default footer -->
|
||||
<div class="footer-content" >
|
||||
{{=T('Copyright')}} © {{=request.now.year}}
|
||||
- User communities in <a href="https://groups.google.com/forum/?fromgroups#!forum/web2py" target="_blank">English<a>, <a href="https://groups.google.com/forum/?fromgroups#!forum/web2py-fr" target="_blank">French</a>, <a href="https://groups.google.com/forum/?fromgroups#!forum/web2py-japan" target="_blank">Japanese</a>, <a href="https://groups.google.com/forum/?fromgroups#!forum/web2py-users-brazil" target="_blank">Portuguese</a>, and <a href="https://groups.google.com/forum/?fromgroups#!forum/web2py-usuarios" target="_blank">Spanish</a>.
|
||||
<div style="float: right;">
|
||||
<a href="http://www.web2py.com/" style="float: left; padding-right: 6px;">
|
||||
<img style="padding-bottom: 0;" src="{{=URL('static','images/poweredby.png')}}"/>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
{{end}}
|
||||
</div>
|
||||
</div><!-- container -->
|
||||
</div><!-- footer -->
|
||||
|
||||
<!-- Footer ================================================== -->
|
||||
<div class="row">
|
||||
<footer class="footer span12" id="footer">
|
||||
<div class="footer-content">
|
||||
{{block footer}} <!-- this is default footer -->
|
||||
<div id="poweredBy" class="pull-right">
|
||||
{{=T('Copyright')}} © {{=request.now.year}} -
|
||||
{{=T('Powered by')}}
|
||||
<a href="http://www.web2py.com/">web2py</a> -
|
||||
{{=T('Hosted by')}}
|
||||
<a href="http://pythonanywhere.com">PythonAnywhere</a>
|
||||
</div>
|
||||
{{end}}
|
||||
</div>
|
||||
</footer>
|
||||
</div>
|
||||
|
||||
</div> <!-- /container -->
|
||||
|
||||
<!-- The javascript =============================================
|
||||
(Placed at the end of the document so the pages load faster) -->
|
||||
<script src="{{=URL('static','js/bootstrap.min.js')}}"></script>
|
||||
<script src="{{=URL('static','js/web2py_bootstrap.js')}}"></script>
|
||||
<!--[if lt IE 7 ]>
|
||||
<script src="{{=URL('static','js/dd_belatedpng.js')}}"></script>
|
||||
<script> DD_belatedPNG.fix('img, .png_bg'); //fix any <img> or .png_bg background-images </script>
|
||||
<![endif]-->
|
||||
{{if response.google_analytics_id:}}<script>/* http://mathiasbynens.be/notes/async-analytics-snippet */ var _gaq=[['_setAccount','{{=response.google_analytics_id}}'],['_trackPageview']];(function(d,t){var g=d.createElement(t),s=d.getElementsByTagName(t)[0];g.src='//www.google-analytics.com/ga.js';s.parentNode.insertBefore(g,s)}(document,'script')) </script>{{pass}}
|
||||
<script src="{{=URL('static','js/dd_belatedpng.js')}}"></script>
|
||||
<script> DD_belatedPNG.fix('img, .png_bg'); //fix any <img> or .png_bg background-images </script>
|
||||
<![endif]-->
|
||||
|
||||
{{if response.google_analytics_id:}}
|
||||
<script src="{{=URL('static','js/analytics.min.js')}}"></script>
|
||||
<script type="text/javascript">
|
||||
analytics.initialize({
|
||||
'Google Analytics':{trackingId:'{{=response.google_analytics_id}}'}
|
||||
});</script>
|
||||
{{pass}}
|
||||
<script src="{{=URL('static','js/share.js',vars=dict(static=URL('static','images')))}}"></script>
|
||||
<a style="position:fixed;bottom:0;left:0;z-index:1000" href="https://groups.google.com/forum/?fromgroups#!forum/web2py" target="_blank">
|
||||
<img src="{{=URL('static','images/questions.png')}}" />
|
||||
</a>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
{{extend 'layout.html'}}
|
||||
|
||||
<style>
|
||||
input {width: 70px;}
|
||||
input:focus {background-color: yellow}
|
||||
table, td, tr { border: 0; margin: 0; padding: 0}
|
||||
</style>
|
||||
<h1>Excel-like spreadsheet widget</h1>
|
||||
|
||||
Try insert "=r0c1+1" in cell r0c0 and "2" in r0c1. Formulas start with "=" as in Excel. You can use a subset of python commands and math function, and reference cells by r[row]c[col]. All computations are performed serverside via Ajax (input is validated for security). Cell values and formulas can be set and locked serverside. The shape of the spreadsheet can be modifed serverside and does not need to be tabular (think of it as a graph of css-friendly widgets you can place where you want). Cells can be given arbistrary names. This example is distributed with web2py so look at the source code of the example to learn more.
|
||||
|
||||
@@ -54,6 +54,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 = {}
|
||||
@@ -319,6 +323,9 @@ def state():
|
||||
|
||||
|
||||
def ccache():
|
||||
cache.ram.initialize()
|
||||
cache.disk.initialize()
|
||||
|
||||
form = FORM(
|
||||
P(TAG.BUTTON(
|
||||
T("Clear CACHE?"), _type="submit", _name="yes", _value="yes")),
|
||||
@@ -385,7 +392,7 @@ def ccache():
|
||||
|
||||
return (hours, minutes, seconds)
|
||||
|
||||
for key, value in cache.ram.storage.items():
|
||||
for key, value in cache.ram.storage.iteritems():
|
||||
if isinstance(value, dict):
|
||||
ram['hits'] = value['hit_total'] - value['misses']
|
||||
ram['misses'] = value['misses']
|
||||
|
||||
@@ -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,37 +33,37 @@
|
||||
'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',
|
||||
'Components and Plugins': 'Componentes y Plugins',
|
||||
'Controller': 'Controlador',
|
||||
'Controllers': 'Controladores',
|
||||
'controllers': 'controladores',
|
||||
@@ -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,9 +115,9 @@
|
||||
'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',
|
||||
@@ -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 llegasta hasta allá?',
|
||||
'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 LLavel 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 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',
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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-"]{
|
||||
|
||||
@@ -91,16 +91,18 @@
|
||||
|
||||
<div class="container">
|
||||
<!-- Masthead ================================================== -->
|
||||
{{if response.title:}}
|
||||
<header class="mastheader row" id="header">
|
||||
<div class="span12">
|
||||
<div class="page-header">
|
||||
<h1>
|
||||
{{=response.title or request.application}}
|
||||
{{=response.title}}
|
||||
<small>{{=response.subtitle or ''}}</small>
|
||||
</h1>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
{{pass}}
|
||||
|
||||
<section id="main" class="main row">
|
||||
{{if left_sidebar_enabled:}}
|
||||
|
||||
@@ -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:
|
||||
@@ -374,11 +374,15 @@ def check_new_version(myversion, version_URL):
|
||||
"""
|
||||
try:
|
||||
from urllib import urlopen
|
||||
version = parse_version(urlopen(version_URL).read())
|
||||
except Exception:
|
||||
version = urlopen(version_URL).read()
|
||||
pversion = parse_version(version)
|
||||
pmyversion = parse_version(myversion)
|
||||
except Exception,e:
|
||||
import traceback
|
||||
print traceback.format_exc()
|
||||
return -1, myversion
|
||||
|
||||
if version > myversion:
|
||||
if pversion[:3]+pversion[-6:] > pmyversion[:3]+pmyversion[-6:]:
|
||||
return True, version
|
||||
else:
|
||||
return False, version
|
||||
|
||||
@@ -27,6 +27,8 @@ import thread
|
||||
import os
|
||||
import logging
|
||||
import re
|
||||
import hashlib
|
||||
import datetime
|
||||
try:
|
||||
import settings
|
||||
have_settings = True
|
||||
@@ -241,7 +243,7 @@ class CacheOnDisk(CacheAbstract):
|
||||
|
||||
This is implemented as a shelve object and it is shared by multiple web2py
|
||||
processes (and threads) as long as they share the same filesystem.
|
||||
The file is locked wen accessed.
|
||||
The file is locked when accessed.
|
||||
|
||||
Disk cache provides persistance when web2py is started/stopped but it slower
|
||||
than `CacheInRam`
|
||||
@@ -376,7 +378,6 @@ class CacheOnDisk(CacheAbstract):
|
||||
self._close_shelve_and_unlock()
|
||||
return value
|
||||
|
||||
|
||||
class CacheAction(object):
|
||||
def __init__(self, func, key, time_expire, cache, cache_model):
|
||||
self.__name__ = func.__name__
|
||||
@@ -436,6 +437,89 @@ class Cache(object):
|
||||
# been accounted for
|
||||
logger.warning('no cache.disk (AttributeError)')
|
||||
|
||||
def client(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):
|
||||
"""
|
||||
Experimental!
|
||||
Currently only HTTP 1.1 compliant
|
||||
reference : http://code.google.com/p/doctype-mirror/wiki/ArticleHttpCaching
|
||||
time_expire: same as @cache
|
||||
cache_model: same as @cache
|
||||
prefix: add a prefix to the calculated key
|
||||
session: adds response.session_id to the key
|
||||
vars: adds request.env.query_string
|
||||
lang: adds T.accepted_language
|
||||
user_agent: if True, adds is_mobile and is_tablet to the key.
|
||||
Pass a dict to use all the needed values (uses str(.items())) (e.g. user_agent=request.user_agent())
|
||||
used only if session is not True
|
||||
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:
|
||||
fast overrides with initial strings, e.g. 'SVLP' or 'VLP', or 'VLP'
|
||||
"""
|
||||
from gluon import current
|
||||
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)
|
||||
else:
|
||||
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
|
||||
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(cache_key, None)
|
||||
return rtn
|
||||
return func()
|
||||
wrapped_f.__name__ = func.__name__
|
||||
wrapped_f.__doc__ = func.__doc__
|
||||
return wrapped_f
|
||||
return wrap
|
||||
|
||||
def __call__(self,
|
||||
key=None,
|
||||
time_expire=DEFAULT_TIME_EXPIRE,
|
||||
@@ -469,7 +553,7 @@ class Cache(object):
|
||||
refresh.
|
||||
|
||||
If the function `f` is an action, we suggest using
|
||||
`request.env.path_info` as key.
|
||||
@cache.client instead
|
||||
"""
|
||||
|
||||
def tmp(func, cache=self, cache_model=cache_model):
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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':
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
|
||||
@@ -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 -*-
|
||||
|
||||
|
||||
@@ -15,8 +15,6 @@ Dependencies:
|
||||
import oauth2 as oauth
|
||||
import cgi
|
||||
|
||||
from urllib2 import urlopen
|
||||
import urllib2
|
||||
from urllib import urlencode
|
||||
|
||||
from gluon import current
|
||||
@@ -64,9 +62,7 @@ class OAuthAccount(object):
|
||||
Appends the _next action to the generated url so the flows continues.
|
||||
"""
|
||||
r = self.request
|
||||
http_host = r.env.http_x_forwarded_for
|
||||
if not http_host:
|
||||
http_host = r.env.http_host
|
||||
http_host = r.env.http_host
|
||||
|
||||
url_scheme = r.env.wsgi_url_scheme
|
||||
if next:
|
||||
|
||||
@@ -103,9 +103,7 @@ server for requests. It can be used for the optional"scope" parameters for Face
|
||||
"""
|
||||
|
||||
r = current.request
|
||||
http_host = r.env.http_x_forwarded_for
|
||||
if not http_host:
|
||||
http_host = r.env.http_host
|
||||
http_host = r.env.http_host
|
||||
|
||||
if r.env.https == 'on':
|
||||
url_scheme = 'https'
|
||||
@@ -149,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:
|
||||
@@ -163,7 +161,7 @@ server for requests. It can be used for the optional"scope" parameters for Face
|
||||
open_url = None
|
||||
opener = self.__build_url_opener(self.token_url)
|
||||
try:
|
||||
open_url = opener.open(self.token_url, urlencode(data))
|
||||
open_url = opener.open(self.token_url, urlencode(data), self.socket_timeout)
|
||||
except urllib2.HTTPError, e:
|
||||
tmp = e.read()
|
||||
raise Exception(tmp)
|
||||
@@ -208,7 +206,7 @@ server for requests. It can be used for the optional"scope" parameters for Face
|
||||
|
||||
def __init__(self, g=None,
|
||||
client_id=None, client_secret=None,
|
||||
auth_url=None, token_url=None, **args):
|
||||
auth_url=None, token_url=None, socket_timeout=60, **args):
|
||||
"""
|
||||
first argument is unused. Here only for legacy reasons.
|
||||
"""
|
||||
@@ -224,6 +222,7 @@ server for requests. It can be used for the optional"scope" parameters for Face
|
||||
self.auth_url = auth_url
|
||||
self.token_url = token_url
|
||||
self.args = args
|
||||
self.socket_timeout = socket_timeout
|
||||
|
||||
def login_url(self, next="/"):
|
||||
self.__oauth_login(next)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -75,7 +75,7 @@ def da_du_ma(n=4):
|
||||
[random.randint(0, 11)] for i in range(n)])
|
||||
|
||||
|
||||
def populate(table, n, default=True, compute=False):
|
||||
def populate(table, n, default=True, compute=False, contents={}):
|
||||
ell = Learner()
|
||||
#ell.learn(open('20417.txt','r').read())
|
||||
#ell.save('frequencies.pickle')
|
||||
@@ -84,7 +84,14 @@ def populate(table, n, default=True, compute=False):
|
||||
ids = {}
|
||||
for i in range(n):
|
||||
record = {}
|
||||
|
||||
record.update(contents) # load user supplied contents.
|
||||
|
||||
for fieldname in table.fields:
|
||||
|
||||
if record.get(fieldname) is not None:
|
||||
continue # if user supplied it, let it be.
|
||||
|
||||
field = table[fieldname]
|
||||
if not isinstance(field.type, (str, unicode)):
|
||||
continue
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -117,10 +117,12 @@ Supported DAL URI strings:
|
||||
'firebird_embedded://username:password@c://path'
|
||||
'informix://user:password@server:3050/database'
|
||||
'informixu://user:password@server:3050/database' # unicode informix
|
||||
'ingres://database' # or use an ODBC connection string, e.g. 'ingres://dsn=dsn_name'
|
||||
'google:datastore' # for google app engine datastore
|
||||
'google:sql' # for google app engine with sql (mysql compatible)
|
||||
'teradata://DSN=dsn;UID=user;PWD=pass; DATABASE=database' # experimental
|
||||
'imap://user:password@server:port' # experimental
|
||||
'mongodb://user:password@server:port/database' # experimental
|
||||
|
||||
For more info:
|
||||
help(DAL)
|
||||
@@ -198,7 +200,7 @@ TABLE_ARGS = set(
|
||||
|
||||
SELECT_ARGS = set(
|
||||
('orderby', 'groupby', 'limitby','required', 'cache', 'left',
|
||||
'distinct', 'having', 'join','for_update', 'processor','cacheable'))
|
||||
'distinct', 'having', 'join','for_update', 'processor','cacheable', 'orderby_on_limitby'))
|
||||
|
||||
ogetattr = object.__getattribute__
|
||||
osetattr = object.__setattr__
|
||||
@@ -350,8 +352,9 @@ if not 'google' in DRIVERS:
|
||||
DRIVERS.append('MSSQL(pyodbc)')
|
||||
DRIVERS.append('DB2(pyodbc)')
|
||||
DRIVERS.append('Teradata(pyodbc)')
|
||||
DRIVERS.append('Ingres(pyodbc)')
|
||||
except ImportError:
|
||||
LOGGER.debug('no MSSQL/DB2/Teradata driver pyodbc')
|
||||
LOGGER.debug('no MSSQL/DB2/Teradata/Ingres driver pyodbc')
|
||||
|
||||
try:
|
||||
import Sybase
|
||||
@@ -368,7 +371,7 @@ if not 'google' in DRIVERS:
|
||||
|
||||
try:
|
||||
import fdb
|
||||
DRIVERS.append('Firbird(fdb)')
|
||||
DRIVERS.append('Firebird(fdb)')
|
||||
except ImportError:
|
||||
LOGGER.debug('no Firebird driver fdb')
|
||||
#####
|
||||
@@ -413,13 +416,6 @@ if not 'google' in DRIVERS:
|
||||
LOGGER.debug('no SQLite/PostgreSQL driver zxJDBC')
|
||||
is_jdbc = False
|
||||
|
||||
try:
|
||||
import ingresdbi
|
||||
DRIVERS.append('Ingres(ingresdbi)')
|
||||
except ImportError:
|
||||
LOGGER.debug('no Ingres driver ingresdbi')
|
||||
# NOTE could try JDBC.......
|
||||
|
||||
try:
|
||||
import couchdb
|
||||
DRIVERS.append('CouchDB(couchdb)')
|
||||
@@ -638,6 +634,7 @@ class BaseAdapter(ConnectionPool):
|
||||
|
||||
TRUE = 'T'
|
||||
FALSE = 'F'
|
||||
T_SEP = ' '
|
||||
types = {
|
||||
'boolean': 'CHAR(1)',
|
||||
'string': 'CHAR(%(length)s)',
|
||||
@@ -1130,6 +1127,9 @@ class BaseAdapter(ConnectionPool):
|
||||
def EPOCH(self, first):
|
||||
return self.EXTRACT(first, 'epoch')
|
||||
|
||||
def LENGTH(self, first):
|
||||
return "LENGTH(%s)" % self.expand(first)
|
||||
|
||||
def AGGREGATE(self, first, what):
|
||||
return "%s(%s)" % (what, self.expand(first))
|
||||
|
||||
@@ -1255,24 +1255,15 @@ class BaseAdapter(ConnectionPool):
|
||||
return '(%s LIKE %s)' % (self.expand(first),
|
||||
self.expand('%'+second, 'string'))
|
||||
|
||||
def CONTAINS(self, first, second, case_sensitive=False):
|
||||
if isinstance(second,Expression):
|
||||
field = self.expand(first)
|
||||
expr = self.expand(second,'string')
|
||||
if first.type.startswith('list:'):
|
||||
expr = 'CONCAT("|", %s, "|")' % expr
|
||||
elif not first.type in ('string', 'text', 'json'):
|
||||
raise RuntimeError("Expression Not Supported")
|
||||
return 'INSTR(%s,%s)' % (field, expr)
|
||||
else:
|
||||
if first.type in ('string', 'text', 'json'):
|
||||
key = '%'+str(second).replace('%','%%')+'%'
|
||||
elif first.type.startswith('list:'):
|
||||
key = '%|'+str(second).replace('|','||').replace('%','%%')+'|%'
|
||||
else:
|
||||
raise RuntimeError("Expression Not Supported")
|
||||
op = case_sensitive and self.LIKE or self.ILIKE
|
||||
return op(first,key)
|
||||
def CONTAINS(self,first,second,case_sensitive=False):
|
||||
if first.type in ('string','text', 'json'):
|
||||
second = Expression(None,self.CONCAT('%',Expression(
|
||||
None,self.REPLACE(second,('%','%%'))),'%'))
|
||||
elif first.type.startswith('list:'):
|
||||
second = Expression(None,self.CONCAT('%|',Expression(None,self.REPLACE(
|
||||
Expression(None,self.REPLACE(second,('%','%%'))),('|','||'))),'|%'))
|
||||
op = case_sensitive and self.LIKE or self.ILIKE
|
||||
return op(first,second)
|
||||
|
||||
def EQ(self, first, second=None):
|
||||
if second is None:
|
||||
@@ -1310,9 +1301,24 @@ class BaseAdapter(ConnectionPool):
|
||||
return '(%s >= %s)' % (self.expand(first),
|
||||
self.expand(second,first.type))
|
||||
|
||||
def is_numerical_type(self, ftype):
|
||||
return ftype in ('integer','boolean','double','bigint') or \
|
||||
ftype.startswith('decimal')
|
||||
|
||||
def REPLACE(self, first, (second, third)):
|
||||
return 'REPLACE(%s,%s,%s)' % (self.expand(first,'string'),
|
||||
self.expand(second,'string'),
|
||||
self.expand(third,'string'))
|
||||
|
||||
def CONCAT(self, *items):
|
||||
return '(%s)' % ' || '.join(self.expand(x,'string') for x in items)
|
||||
|
||||
def ADD(self, first, second):
|
||||
return '(%s + %s)' % (self.expand(first),
|
||||
self.expand(second, first.type))
|
||||
if self.is_numerical_type(first.type):
|
||||
return '(%s + %s)' % (self.expand(first),
|
||||
self.expand(second, first.type))
|
||||
else:
|
||||
return self.CONCAT(first, second)
|
||||
|
||||
def SUB(self, first, second):
|
||||
return '(%s - %s)' % (self.expand(first),
|
||||
@@ -1503,6 +1509,7 @@ class BaseAdapter(ConnectionPool):
|
||||
raise SyntaxError('invalid select attribute: %s' % key)
|
||||
args_get = attributes.get
|
||||
tablenames = tables(query)
|
||||
tablenames_for_common_filters = tablenames
|
||||
for field in fields:
|
||||
if isinstance(field, basestring) \
|
||||
and REGEX_TABLE_DOT_FIELD.match(field):
|
||||
@@ -1529,6 +1536,7 @@ class BaseAdapter(ConnectionPool):
|
||||
orderby = args_get('orderby', False)
|
||||
having = args_get('having', False)
|
||||
limitby = args_get('limitby', False)
|
||||
orderby_on_limitby = args_get('orderby_on_limitby', True)
|
||||
for_update = args_get('for_update', False)
|
||||
if self.can_select_for_update is False and for_update is True:
|
||||
raise SyntaxError('invalid select attribute: for_update')
|
||||
@@ -1566,6 +1574,8 @@ class BaseAdapter(ConnectionPool):
|
||||
dict.fromkeys(tables(t))) for t in joinon]
|
||||
joinont = [t.first._tablename for t in joinon]
|
||||
[tables_to_merge.pop(t) for t in joinont if t in tables_to_merge]
|
||||
tablenames_for_common_filters = [t for t in tablenames
|
||||
if not t in joinont ]
|
||||
important_tablenames = joint + joinont + tables_to_merge.keys()
|
||||
excluded = [t for t in tablenames
|
||||
if not t in important_tablenames ]
|
||||
@@ -1573,7 +1583,7 @@ class BaseAdapter(ConnectionPool):
|
||||
excluded = tablenames
|
||||
|
||||
if use_common_filters(query):
|
||||
query = self.common_filter(query,excluded)
|
||||
query = self.common_filter(query,tablenames_for_common_filters)
|
||||
sql_w = ' WHERE ' + self.expand(query) if query else ''
|
||||
|
||||
def alias(t):
|
||||
@@ -1620,7 +1630,7 @@ class BaseAdapter(ConnectionPool):
|
||||
else:
|
||||
sql_o += ' ORDER BY %s' % self.expand(orderby)
|
||||
if limitby:
|
||||
if not orderby and tablenames:
|
||||
if orderby_on_limitby and not orderby and tablenames:
|
||||
sql_o += ' ORDER BY %s' % ', '.join(['%s.%s'%(t,x) for t in tablenames for x in (hasattr(self.db[t],'_primarykey') and self.db[t]._primarykey or [self.db[t]._id.name])])
|
||||
# oracle does not support limitby
|
||||
sql = self.select_limitby(sql_s, sql_f, sql_t, sql_w, sql_o, limitby)
|
||||
@@ -1815,7 +1825,7 @@ class BaseAdapter(ConnectionPool):
|
||||
obj = str(obj)
|
||||
elif fieldtype == 'datetime':
|
||||
if isinstance(obj, datetime.datetime):
|
||||
obj = obj.isoformat()[:19].replace('T',' ')
|
||||
obj = obj.isoformat(self.T_SEP)[:19]
|
||||
elif isinstance(obj, datetime.date):
|
||||
obj = obj.isoformat()[:10]+' 00:00:00'
|
||||
else:
|
||||
@@ -1943,17 +1953,17 @@ class BaseAdapter(ConnectionPool):
|
||||
return value
|
||||
|
||||
def parse_list_integers(self, value, field_type):
|
||||
if not self.dbengine=='google:datastore':
|
||||
if not isinstance(self, NoSQLAdapter):
|
||||
value = bar_decode_integer(value)
|
||||
return value
|
||||
|
||||
def parse_list_references(self, value, field_type):
|
||||
if not self.dbengine=='google:datastore':
|
||||
if not isinstance(self, NoSQLAdapter):
|
||||
value = bar_decode_integer(value)
|
||||
return [self.parse_reference(r, field_type[5:]) for r in value]
|
||||
|
||||
def parse_list_strings(self, value, field_type):
|
||||
if not self.dbengine=='google:datastore':
|
||||
if not isinstance(self, NoSQLAdapter):
|
||||
value = bar_decode_string(value)
|
||||
return value
|
||||
|
||||
@@ -2264,7 +2274,7 @@ class SpatiaLiteAdapter(SQLiteAdapter):
|
||||
# Linux uses libspatialite.so
|
||||
# Mac OS X uses libspatialite.dylib
|
||||
libspatialite = SPATIALLIBS[platform.system()]
|
||||
self.execute(r'SELECT load_extension("%s");') % libspatialite
|
||||
self.execute(r'SELECT load_extension("%s");' % libspatialite)
|
||||
|
||||
self.connection.create_function('web2py_extract', 2,
|
||||
SQLiteAdapter.web2py_extract)
|
||||
@@ -2414,6 +2424,9 @@ class MySQLAdapter(BaseAdapter):
|
||||
def EPOCH(self, first):
|
||||
return "UNIX_TIMESTAMP(%s)" % self.expand(first)
|
||||
|
||||
def CONCAT(self, *items):
|
||||
return 'CONCAT(%s)' % ','.join(self.expand(x,'string') for x in items)
|
||||
|
||||
def REGEXP(self,first,second):
|
||||
return '(%s REGEXP %s)' % (self.expand(first),
|
||||
self.expand(second,'string'))
|
||||
@@ -2423,6 +2436,9 @@ class MySQLAdapter(BaseAdapter):
|
||||
return ['SET FOREIGN_KEY_CHECKS=0;','DROP TABLE %s;' % table,
|
||||
'SET FOREIGN_KEY_CHECKS=1;']
|
||||
|
||||
def _insert_empty(self, table):
|
||||
return 'INSERT INTO %s VALUES (DEFAULT);' % table
|
||||
|
||||
def distributed_transaction_begin(self,key):
|
||||
self.execute('XA START;')
|
||||
|
||||
@@ -2607,7 +2623,11 @@ class PostgreSQLAdapter(BaseAdapter):
|
||||
"port=%s password='%s'") \
|
||||
% (db, user, host, port, password)
|
||||
# choose diver according uri
|
||||
self.__version__ = "%s %s" % (self.driver.__name__, self.driver.__version__)
|
||||
if self.driver:
|
||||
self.__version__ = "%s %s" % (self.driver.__name__,
|
||||
self.driver.__version__)
|
||||
else:
|
||||
self.__version__ = None
|
||||
def connector(msg=msg,driver_args=driver_args):
|
||||
return self.driver.connect(msg,**driver_args)
|
||||
self.connector = connector
|
||||
@@ -2662,14 +2682,6 @@ class PostgreSQLAdapter(BaseAdapter):
|
||||
return '(%s ILIKE %s)' % (self.expand(first),
|
||||
self.expand('%'+second,'string'))
|
||||
|
||||
def CONTAINS(self,first,second,case_sensitive=False):
|
||||
if first.type in ('string','text', 'json'):
|
||||
key = '%'+str(second).replace('%','%%')+'%'
|
||||
elif first.type.startswith('list:'):
|
||||
key = '%|'+str(second).replace('|','||').replace('%','%%')+'|%'
|
||||
op = case_sensitive and self.LIKE or self.ILIKE
|
||||
return op(first,key)
|
||||
|
||||
# GIS functions
|
||||
|
||||
def ST_ASGEOJSON(self, first, second):
|
||||
@@ -3038,6 +3050,7 @@ class OracleAdapter(BaseAdapter):
|
||||
|
||||
class MSSQLAdapter(BaseAdapter):
|
||||
drivers = ('pyodbc',)
|
||||
T_SEP = 'T'
|
||||
|
||||
types = {
|
||||
'boolean': 'BIT',
|
||||
@@ -3103,7 +3116,9 @@ class MSSQLAdapter(BaseAdapter):
|
||||
(lmin, lmax) = limitby
|
||||
sql_s += ' TOP %i' % lmax
|
||||
if 'GROUP BY' in sql_o:
|
||||
sql_o = sql_o[:sql_o.find('ORDER BY ')]
|
||||
orderfound = sql_o.find('ORDER BY ')
|
||||
if orderfound >= 0:
|
||||
sql_o = sql_o[:orderfound]
|
||||
return 'SELECT %s %s FROM %s%s%s;' % (sql_s, sql_f, sql_t, sql_w, sql_o)
|
||||
|
||||
TRUE = 1
|
||||
@@ -3193,6 +3208,9 @@ class MSSQLAdapter(BaseAdapter):
|
||||
def EPOCH(self, first):
|
||||
return "DATEDIFF(second, '1970-01-01 00:00:00', %s)" % self.expand(first)
|
||||
|
||||
def CONCAT(self, *items):
|
||||
return '(%s)' % ' + '.join(self.expand(x,'string') for x in items)
|
||||
|
||||
# GIS Spatial Extensions
|
||||
|
||||
# No STAsGeoJSON in MSSQL
|
||||
@@ -3448,18 +3466,16 @@ class FireBirdAdapter(BaseAdapter):
|
||||
def SUBSTRING(self,field,parameters):
|
||||
return 'SUBSTRING(%s from %s for %s)' % (self.expand(field), parameters[0], parameters[1])
|
||||
|
||||
def CONTAINING(self,first,second):
|
||||
"case in-sensitive like operator"
|
||||
def LENGTH(self, first):
|
||||
return "CHAR_LENGTH(%s)" % self.expand(first)
|
||||
|
||||
def CONTAINS(self,first,second,case_sensitive=False):
|
||||
if first.type.startswith('list:'):
|
||||
second = Expression(None,self.CONCAT('|',Expression(
|
||||
None,self.REPLACE(second,('|','||'))),'|'))
|
||||
return '(%s CONTAINING %s)' % (self.expand(first),
|
||||
self.expand(second, 'string'))
|
||||
|
||||
def CONTAINS(self, first, second, case_sensitive=False):
|
||||
if first.type in ('string','text'):
|
||||
key = str(second).replace('%','%%')
|
||||
elif first.type.startswith('list:'):
|
||||
key = '|'+str(second).replace('|','||').replace('%','%%')+'|'
|
||||
return self.CONTAINING(first,second)
|
||||
|
||||
def _drop(self,table,mode):
|
||||
sequence_name = table._sequence_name
|
||||
return ['DROP TABLE %s %s;' % (table, mode), 'DROP GENERATOR %s;' % sequence_name]
|
||||
@@ -3862,7 +3878,7 @@ INGRES_SEQNAME='ii***lineitemsequence' # NOTE invalid database object name
|
||||
# to be a delimited identifier)
|
||||
|
||||
class IngresAdapter(BaseAdapter):
|
||||
drivers = ('ingresdbi',)
|
||||
drivers = ('pyodbc',)
|
||||
|
||||
types = {
|
||||
'boolean': 'CHAR(1)',
|
||||
@@ -3913,6 +3929,7 @@ class IngresAdapter(BaseAdapter):
|
||||
adapter_args={}, do_connect=True, after_connection=None):
|
||||
self.db = db
|
||||
self.dbengine = "ingres"
|
||||
self._driver = pyodbc
|
||||
self.uri = uri
|
||||
if do_connect: self.find_driver(adapter_args,uri)
|
||||
self.pool_size = pool_size
|
||||
@@ -3920,22 +3937,27 @@ class IngresAdapter(BaseAdapter):
|
||||
self.db_codec = db_codec
|
||||
self._after_connection = after_connection
|
||||
self.find_or_make_work_folder()
|
||||
connstr = self._uri.split(':', 1)[1]
|
||||
connstr = uri.split(':', 1)[1]
|
||||
# Simple URI processing
|
||||
connstr = connstr.lstrip()
|
||||
while connstr.startswith('/'):
|
||||
connstr = connstr[1:]
|
||||
database_name=connstr # Assume only (local) dbname is passed in
|
||||
vnode = '(local)'
|
||||
servertype = 'ingres'
|
||||
trace = (0, None) # No tracing
|
||||
driver_args.update(database=database_name,
|
||||
vnode=vnode,
|
||||
servertype=servertype,
|
||||
trace=trace)
|
||||
def connector(driver_args=driver_args):
|
||||
return self.driver.connect(**driver_args)
|
||||
if '=' in connstr:
|
||||
# Assume we have a regular ODBC connection string and just use it
|
||||
ruri = connstr
|
||||
else:
|
||||
# Assume only (local) dbname is passed in with OS auth
|
||||
database_name = connstr
|
||||
default_driver_name = 'Ingres'
|
||||
vnode = '(local)'
|
||||
servertype = 'ingres'
|
||||
ruri = 'Driver={%s};Server=%s;Database=%s' % (default_driver_name, vnode, database_name)
|
||||
def connector(cnxn=ruri,driver_args=driver_args):
|
||||
return self.driver.connect(cnxn,**driver_args)
|
||||
|
||||
self.connector = connector
|
||||
|
||||
# TODO if version is >= 10, set types['id'] to Identity column, see http://community.actian.com/wiki/Using_Ingres_Identity_Columns
|
||||
if do_connect: self.reconnect()
|
||||
|
||||
def create_sequence_and_triggers(self, query, table, **args):
|
||||
@@ -3961,12 +3983,12 @@ class IngresAdapter(BaseAdapter):
|
||||
return int(self.cursor.fetchone()[0]) # don't really need int type cast here...
|
||||
|
||||
def integrity_error_class(self):
|
||||
return ingresdbi.IntegrityError
|
||||
return self._driver.IntegrityError
|
||||
|
||||
|
||||
class IngresUnicodeAdapter(IngresAdapter):
|
||||
|
||||
drivers = ('ingresdbi',)
|
||||
drivers = ('pyodbc',)
|
||||
|
||||
types = {
|
||||
'boolean': 'CHAR(1)',
|
||||
@@ -4352,13 +4374,14 @@ class NoSQLAdapter(BaseAdapter):
|
||||
elif fieldtype == 'blob':
|
||||
pass
|
||||
elif fieldtype == 'json':
|
||||
obj = self.to_unicode(obj)
|
||||
if have_serializers:
|
||||
obj = serializers.loads_json(obj)
|
||||
elif simplejson:
|
||||
obj = simplejson.loads(obj)
|
||||
else:
|
||||
raise RuntimeError("missing simplejson")
|
||||
if isinstance(obj, basestring):
|
||||
obj = self.to_unicode(obj)
|
||||
if have_serializers:
|
||||
obj = serializers.loads_json(obj)
|
||||
elif simplejson:
|
||||
obj = simplejson.loads(obj)
|
||||
else:
|
||||
raise RuntimeError("missing simplejson")
|
||||
elif is_string and field_is_type('list:string'):
|
||||
return map(self.to_unicode,obj)
|
||||
elif is_list:
|
||||
@@ -4416,6 +4439,7 @@ class NoSQLAdapter(BaseAdapter):
|
||||
def LOWER(self,first): raise SyntaxError("Not supported")
|
||||
def UPPER(self,first): raise SyntaxError("Not supported")
|
||||
def EXTRACT(self,first,what): raise SyntaxError("Not supported")
|
||||
def LENGTH(self, first): raise SyntaxError("Not supported")
|
||||
def AGGREGATE(self,first,what): raise SyntaxError("Not supported")
|
||||
def LEFT_JOIN(self): raise SyntaxError("Not supported")
|
||||
def RANDOM(self): raise SyntaxError("Not supported")
|
||||
@@ -4464,7 +4488,7 @@ class GoogleDatastoreAdapter(NoSQLAdapter):
|
||||
adapter_args={}, do_connect=True, after_connection=None):
|
||||
self.types.update({
|
||||
'boolean': gae.BooleanProperty,
|
||||
'string': (lambda: gae.StringProperty(multiline=True)),
|
||||
'string': (lambda **kwargs: gae.StringProperty(multiline=True, **kwargs)),
|
||||
'text': gae.TextProperty,
|
||||
'json': gae.TextProperty,
|
||||
'password': gae.StringProperty,
|
||||
@@ -4480,9 +4504,9 @@ class GoogleDatastoreAdapter(NoSQLAdapter):
|
||||
'datetime': gae.DateTimeProperty,
|
||||
'id': None,
|
||||
'reference': gae.IntegerProperty,
|
||||
'list:string': (lambda: gae.StringListProperty(default=None)),
|
||||
'list:integer': (lambda: gae.ListProperty(int,default=None)),
|
||||
'list:reference': (lambda: gae.ListProperty(int,default=None)),
|
||||
'list:string': (lambda **kwargs: gae.StringListProperty(default=None, **kwargs)),
|
||||
'list:integer': (lambda **kwargs: gae.ListProperty(int,default=None, **kwargs)),
|
||||
'list:reference': (lambda **kwargs: gae.ListProperty(int,default=None, **kwargs)),
|
||||
})
|
||||
self.db = db
|
||||
self.uri = uri
|
||||
@@ -4505,7 +4529,7 @@ class GoogleDatastoreAdapter(NoSQLAdapter):
|
||||
if isinstance(polymodel,Table) and field.name in polymodel.fields():
|
||||
continue
|
||||
attr = {}
|
||||
if isinstance(field.custom_qaulifier, dict):
|
||||
if isinstance(field.custom_qualifier, dict):
|
||||
#this is custom properties to add to the GAE field declartion
|
||||
attr = field.custom_qualifier
|
||||
field_type = field.type
|
||||
@@ -4653,7 +4677,7 @@ class GoogleDatastoreAdapter(NoSQLAdapter):
|
||||
return self.expand(first)
|
||||
|
||||
def truncate(self,table,mode):
|
||||
self.db(table._id).delete()
|
||||
self.db(self.db._adapter.id_query(table)).delete()
|
||||
|
||||
def select_raw(self,query,fields=None,attributes=None):
|
||||
db = self.db
|
||||
@@ -5175,6 +5199,7 @@ class MongoDBAdapter(NoSQLAdapter):
|
||||
"Requires an integer or base 16 value")
|
||||
elif isinstance(arg, self.ObjectId):
|
||||
return arg
|
||||
|
||||
if not isinstance(arg, (int, long)):
|
||||
raise TypeError("object_id argument must be of type " +
|
||||
"ObjectId or an objectid representable integer")
|
||||
@@ -5184,8 +5209,26 @@ class MongoDBAdapter(NoSQLAdapter):
|
||||
hexvalue = hex(arg)[2:].replace("L", "")
|
||||
return self.ObjectId(hexvalue)
|
||||
|
||||
def parse_reference(self, value, field_type):
|
||||
# here we have to check for ObjectID before base parse
|
||||
if isinstance(value, self.ObjectId):
|
||||
value = int(str(value), 16)
|
||||
return super(MongoDBAdapter,
|
||||
self).parse_reference(value, field_type)
|
||||
|
||||
def parse_id(self, value, field_type):
|
||||
if isinstance(value, self.ObjectId):
|
||||
value = int(str(value), 16)
|
||||
return super(MongoDBAdapter,
|
||||
self).parse_id(value, field_type)
|
||||
|
||||
def represent(self, obj, fieldtype):
|
||||
value = NoSQLAdapter.represent(self, obj, fieldtype)
|
||||
# the base adatpter does not support MongoDB ObjectId
|
||||
if isinstance(obj, self.ObjectId):
|
||||
value = obj
|
||||
else:
|
||||
value = NoSQLAdapter.represent(self, obj, fieldtype)
|
||||
# reference types must be convert to ObjectID
|
||||
if fieldtype =='date':
|
||||
if value == None:
|
||||
return value
|
||||
@@ -5202,15 +5245,24 @@ class MongoDBAdapter(NoSQLAdapter):
|
||||
# mongodb doesn't has a time object and so it must datetime,
|
||||
# string or integer
|
||||
return datetime.datetime.combine(d, value)
|
||||
elif fieldtype == 'list:string' or \
|
||||
fieldtype == 'list:integer' or \
|
||||
fieldtype == 'list:reference':
|
||||
elif (isinstance(fieldtype, basestring) and
|
||||
fieldtype.startswith('list:')):
|
||||
if fieldtype.startswith('list:reference'):
|
||||
newval = []
|
||||
for v in value:
|
||||
newval.append(self.object_id(v))
|
||||
return newval
|
||||
return value
|
||||
elif ((isinstance(fieldtype, basestring) and
|
||||
fieldtype.startswith("reference")) or
|
||||
(isinstance(fieldtype, Table))):
|
||||
value = self.object_id(value)
|
||||
|
||||
return value
|
||||
|
||||
# Safe determines whether a asynchronious request is done or a
|
||||
# synchronious action is done
|
||||
# For safety, we use by default synchronious requests
|
||||
# For safety, we use by default synchronous requests
|
||||
def insert(self, table, fields, safe=None):
|
||||
if safe==None:
|
||||
safe = self.safe
|
||||
@@ -5258,14 +5310,18 @@ class MongoDBAdapter(NoSQLAdapter):
|
||||
if expression.first.type == 'id':
|
||||
expression.first.name = '_id'
|
||||
# cast to Mongo ObjectId
|
||||
expression.second = self.object_id(expression.second)
|
||||
if isinstance(expression.second, (tuple, list, set)):
|
||||
expression.second = [self.object_id(item) for
|
||||
item in expression.second]
|
||||
else:
|
||||
expression.second = self.object_id(expression.second)
|
||||
result = expression.op(expression.first, expression.second)
|
||||
|
||||
if isinstance(expression, Field):
|
||||
if expression.type=='id':
|
||||
result = "_id"
|
||||
else:
|
||||
result = expression.name
|
||||
|
||||
elif isinstance(expression, (Expression, Query)):
|
||||
if not expression.second is None:
|
||||
result = expression.op(expression.first, expression.second)
|
||||
@@ -5276,7 +5332,7 @@ class MongoDBAdapter(NoSQLAdapter):
|
||||
else:
|
||||
result = expression.op
|
||||
elif field_type:
|
||||
result = str(self.represent(expression,field_type))
|
||||
result = self.represent(expression,field_type)
|
||||
elif isinstance(expression,(list,tuple)):
|
||||
result = ','.join(self.represent(item,field_type) for
|
||||
item in expression)
|
||||
@@ -5330,7 +5386,6 @@ class MongoDBAdapter(NoSQLAdapter):
|
||||
else:
|
||||
raise SyntaxError("The table name could not be found in " +
|
||||
"the query nor from the select statement.")
|
||||
|
||||
mongoqry_dict = self.expand(query)
|
||||
fields = fields or self.db[tablename]
|
||||
for field in fields:
|
||||
@@ -5380,15 +5435,12 @@ class MongoDBAdapter(NoSQLAdapter):
|
||||
# record id's
|
||||
if fieldname == "id": fieldname = "_id"
|
||||
if fieldname in record:
|
||||
if isinstance(record[fieldname],
|
||||
self.ObjectId):
|
||||
value = int(str(record[fieldname]), 16)
|
||||
else:
|
||||
value = record[fieldname]
|
||||
value = record[fieldname]
|
||||
else:
|
||||
value = None
|
||||
row.append(value)
|
||||
rows.append(row)
|
||||
|
||||
processor = attributes.get('processor', self.parse)
|
||||
result = processor(rows, fields, newnames, False)
|
||||
return result
|
||||
@@ -5488,7 +5540,7 @@ class MongoDBAdapter(NoSQLAdapter):
|
||||
def BELONGS(self, first, second):
|
||||
if isinstance(second, str):
|
||||
return {self.expand(first) : {"$in" : [ second[:-1]]} }
|
||||
elif second==[] or second==():
|
||||
elif second==[] or second==() or second==set():
|
||||
return {1:0}
|
||||
items = [self.expand(item, first.type) for item in second]
|
||||
return {self.expand(first) : {"$in" : items} }
|
||||
@@ -7051,15 +7103,13 @@ class DAL(object):
|
||||
Example::
|
||||
|
||||
db = DAL('sqlite://test.db')
|
||||
|
||||
or
|
||||
|
||||
db = DAL({"uri": ..., "items": ...}) # experimental
|
||||
|
||||
db.define_table('tablename', Field('fieldname1'),
|
||||
Field('fieldname2'))
|
||||
|
||||
(experimental)
|
||||
you can pass a dict object as uri with the uri string
|
||||
and table/field definitions. For an example of valid data check
|
||||
the output of:
|
||||
|
||||
>>> db.as_dict(flat=True, sanitize=False)
|
||||
"""
|
||||
|
||||
def __new__(cls, uri='sqlite://dummy.db', *args, **kwargs):
|
||||
@@ -7180,6 +7230,28 @@ class DAL(object):
|
||||
|
||||
:uri: string that contains information for connecting to a database.
|
||||
(default: 'sqlite://dummy.db')
|
||||
|
||||
experimental: you can specify a dictionary as uri
|
||||
parameter i.e. with
|
||||
db = DAL({"uri": "sqlite://storage.sqlite",
|
||||
"items": {...}, ...})
|
||||
|
||||
for an example of dict input you can check the output
|
||||
of the scaffolding db model with
|
||||
|
||||
db.as_dict()
|
||||
|
||||
Note that for compatibility with Python older than
|
||||
version 2.6.5 you should cast your dict input keys
|
||||
to str due to a syntax limitation on kwarg names.
|
||||
for proper DAL dictionary input you can use one of:
|
||||
|
||||
obj = serializers.cast_keys(dict, [encoding="utf-8"])
|
||||
|
||||
or else (for parsing json input)
|
||||
|
||||
obj = serializers.loads_json(data, unicode_keys=False)
|
||||
|
||||
:pool_size: How many open connections to make to the database object.
|
||||
:folder: where .table files will be created.
|
||||
automatically set within web2py
|
||||
@@ -8720,7 +8792,7 @@ class Expression(object):
|
||||
|
||||
def len(self):
|
||||
db = self.db
|
||||
return Expression(db, db._adapter.AGGREGATE, self, 'LENGTH', 'integer')
|
||||
return Expression(db, db._adapter.LENGTH, self, None, 'integer')
|
||||
|
||||
def avg(self):
|
||||
db = self.db
|
||||
@@ -8738,6 +8810,10 @@ class Expression(object):
|
||||
db = self.db
|
||||
return Expression(db, db._adapter.UPPER, self, None, self.type)
|
||||
|
||||
def replace(self,a,b):
|
||||
db = self.db
|
||||
return Expression(db, db._adapter.REPLACE, self, (a,b), self.type)
|
||||
|
||||
def year(self):
|
||||
db = self.db
|
||||
return Expression(db, db._adapter.EXTRACT, self, 'year', 'integer')
|
||||
@@ -8816,6 +8892,8 @@ class Expression(object):
|
||||
result_type = 'integer'
|
||||
elif self.type in ['date','time','datetime','double','float']:
|
||||
result_type = 'double'
|
||||
elif self.type.startswith('decimal('):
|
||||
result_type = self.type
|
||||
else:
|
||||
raise SyntaxError("subtraction operation not supported for type")
|
||||
return Expression(db,db._adapter.SUB,self,other,result_type)
|
||||
@@ -9036,7 +9114,7 @@ class FieldVirtual(object):
|
||||
(self.name, self.f) = (name, f) if f else ('unkown', name)
|
||||
self.type = ftype
|
||||
self.label = label or self.name.capitalize().replace('_',' ')
|
||||
self.represent = IDENTITY
|
||||
self.represent = IDENTITY
|
||||
self.formatter = IDENTITY
|
||||
self.comment = None
|
||||
self.readable = True
|
||||
@@ -9234,7 +9312,11 @@ class Field(Expression):
|
||||
dest_file.close()
|
||||
return newfilename
|
||||
|
||||
def retrieve(self, name, path=None):
|
||||
def retrieve(self, name, path=None, nameonly=False):
|
||||
"""
|
||||
if nameonly==True return (filename, fullfilename) instead of
|
||||
(filename, stream)
|
||||
"""
|
||||
self_uploadfield = self.uploadfield
|
||||
if self.custom_retrieve:
|
||||
return self.custom_retrieve(name, path)
|
||||
@@ -9262,7 +9344,12 @@ class Field(Expression):
|
||||
stream = self.uploadfs.open(name, 'rb')
|
||||
else:
|
||||
# ## if file is on regular filesystem
|
||||
stream = pjoin(file_properties['path'], name)
|
||||
# this is intentially a sting with filename and not a stream
|
||||
# this propagates and allows stream_file_or_304_or_206 to be called
|
||||
fullname = pjoin(file_properties['path'],name)
|
||||
if nameonly:
|
||||
return (filename, fullname)
|
||||
stream = open(fullname,'rb')
|
||||
return (filename, stream)
|
||||
|
||||
def retrieve_file_properties(self, name, path=None):
|
||||
@@ -9389,7 +9476,7 @@ class Field(Expression):
|
||||
if k == "other":
|
||||
if isinstance(v, dict):
|
||||
otype, other = v.popitem()
|
||||
else:
|
||||
else:
|
||||
otype = flatten(type(v))
|
||||
other = v
|
||||
newr[k] = {otype: filter_requires(otype, other,
|
||||
@@ -9535,6 +9622,10 @@ class Query(object):
|
||||
newd[k] = loop(v.__dict__)
|
||||
elif isinstance(v, SERIALIZABLE_TYPES):
|
||||
newd[k] = v
|
||||
elif isinstance(v, (datetime.date,
|
||||
datetime.time,
|
||||
datetime.datetime)):
|
||||
newd[k] = unicode(v)
|
||||
elif k == "op":
|
||||
if callable(v):
|
||||
newd[k] = v.__name__
|
||||
|
||||
@@ -47,8 +47,8 @@ __all__ = [
|
||||
|
||||
def parse_semantic(version="Version 1.99.0-rc.1+timestamp.2011.09.19.08.23.26"):
|
||||
"http://semver.org/"
|
||||
re_version = re.compile('Version (\d+)\.(\d+)\.(\d+)(\-(?P<pre>[^\s+]*))?(\+(?P<build>\S*))')
|
||||
m = re_version.match(version)
|
||||
re_version = re.compile('(\d+)\.(\d+)\.(\d+)(\-(?P<pre>[^\s+]*))?(\+(?P<build>\S*))')
|
||||
m = re_version.match(version.strip().split()[-1])
|
||||
if not m:
|
||||
return None
|
||||
a, b, c = int(m.group(1)), int(m.group(2)), int(m.group(3))
|
||||
@@ -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)
|
||||
|
||||
@@ -56,6 +56,7 @@ current = threading.local() # thread-local storage for request-scope globals
|
||||
css_template = '<link href="%s" rel="stylesheet" type="text/css" />'
|
||||
js_template = '<script src="%s" type="text/javascript"></script>'
|
||||
coffee_template = '<script src="%s" type="text/coffee"></script>'
|
||||
typescript_template = '<script src="%s" type="text/typescript"></script>'
|
||||
less_template = '<link href="%s" rel="stylesheet/less" type="text/css" />'
|
||||
css_inline = '<style type="text/css">\n%s\n</style>'
|
||||
js_inline = '<script type="text/javascript">\n%s\n</script>'
|
||||
@@ -292,6 +293,9 @@ class Response(Storage):
|
||||
s += js_template % item
|
||||
elif f.endswith('.coffee'):
|
||||
s += coffee_template % item
|
||||
elif f.endswith('.ts'):
|
||||
# http://www.typescriptlang.org/
|
||||
s += typescript_template % item
|
||||
elif f.endswith('.less'):
|
||||
s += less_template % item
|
||||
elif isinstance(item, (list, tuple)):
|
||||
@@ -400,7 +404,7 @@ class Response(Storage):
|
||||
except AttributeError:
|
||||
raise HTTP(404)
|
||||
try:
|
||||
(filename, stream) = field.retrieve(name)
|
||||
(filename, stream) = field.retrieve(name,nameonly=True)
|
||||
except IOError:
|
||||
raise HTTP(404)
|
||||
headers = self.headers
|
||||
@@ -691,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':
|
||||
|
||||
@@ -840,9 +840,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
|
||||
@@ -887,9 +886,8 @@ class DIV(XmlComponent):
|
||||
|
||||
# get the attributes for this component
|
||||
# (they start with '_', others may have special meanings)
|
||||
fa = ''
|
||||
for key in sorted(self.attributes):
|
||||
value = self[key]
|
||||
attr = []
|
||||
for key, value in self.attributes.iteritems():
|
||||
if key[:1] != '_':
|
||||
continue
|
||||
name = key[1:]
|
||||
@@ -897,8 +895,16 @@ class DIV(XmlComponent):
|
||||
value = name
|
||||
elif value is False or value is None:
|
||||
continue
|
||||
attr.append((name, value))
|
||||
data = self.attributes.get('data',{})
|
||||
for key, value in data.iteritems():
|
||||
name = 'data-' + key
|
||||
value = data[key]
|
||||
attr.append((name,value))
|
||||
attr.sort()
|
||||
fa = ''
|
||||
for name,value in attr:
|
||||
fa += ' %s="%s"' % (name, xmlescape(value, True))
|
||||
|
||||
# get the xml for the inner components
|
||||
co = join([xmlescape(component) for component in
|
||||
self.components])
|
||||
@@ -1479,7 +1485,7 @@ class A(DIV):
|
||||
self['_href'] = self['_href'] or '#null'
|
||||
elif self['callback']:
|
||||
returnfalse = "var e = arguments[0] || window.event; e.cancelBubble=true; if (e.stopPropagation) {e.stopPropagation(); e.stopImmediatePropagation(); e.preventDefault();}"
|
||||
if d:
|
||||
if d and not self['noconfirm']:
|
||||
self['_onclick'] = "if(confirm(w2p_ajax_confirm_message||'Are you sure you want to delete this object?')){ajax('%s',[],'%s');%s};%s" % \
|
||||
(self['callback'], self['target'] or '', d, returnfalse)
|
||||
else:
|
||||
@@ -2305,7 +2311,7 @@ class BEAUTIFY(DIV):
|
||||
for c in self.components:
|
||||
if hasattr(c, 'value') and not callable(c.value):
|
||||
if c.value:
|
||||
components.append(c.value)
|
||||
components.append(c.value)
|
||||
if hasattr(c, 'xml') and callable(c.xml):
|
||||
components.append(c)
|
||||
continue
|
||||
|
||||
@@ -237,7 +237,8 @@ def read_possible_languages_aux(langdir):
|
||||
construct_plural_form) # construct_plural_form() for current language
|
||||
|
||||
plurals = {}
|
||||
flist = oslistdir(langdir)
|
||||
flist = oslistdir(langdir) if isdir(langdir) else []
|
||||
|
||||
# scan languages directory for plural dict files:
|
||||
for pname in flist:
|
||||
if regex_plural_file.match(pname):
|
||||
|
||||
@@ -102,16 +102,14 @@ requests = 0 # gc timer
|
||||
# pattern used to validate client address
|
||||
regex_client = re.compile('[\w\-:]+(\.[\w\-]+)*\.?') # ## to account for IPV6
|
||||
|
||||
#try:
|
||||
if 1:
|
||||
try:
|
||||
version_info = open(pjoin(global_settings.gluon_parent, 'VERSION'), 'r')
|
||||
raw_version_string = version_info.read().strip()
|
||||
raw_version_string = version_info.read().split()[-1].strip()
|
||||
version_info.close()
|
||||
global_settings.web2py_version = parse_version(raw_version_string)
|
||||
#except:
|
||||
# raise RuntimeError("Cannot determine web2py version")
|
||||
|
||||
web2py_version = global_settings.web2py_version
|
||||
global_settings.web2py_version = raw_version_string
|
||||
web2py_version = global_settings.web2py_version
|
||||
except:
|
||||
raise RuntimeError("Cannot determine web2py version")
|
||||
|
||||
try:
|
||||
import rocket
|
||||
@@ -133,7 +131,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()
|
||||
|
||||
@@ -22,6 +22,7 @@ from settings import global_settings
|
||||
|
||||
logger = logging.getLogger("web2py.cron")
|
||||
_cron_stopping = False
|
||||
_cron_subprocs = []
|
||||
|
||||
|
||||
def absolute_path_link(path):
|
||||
@@ -42,7 +43,8 @@ def stopcron():
|
||||
"graceful shutdown of cron"
|
||||
global _cron_stopping
|
||||
_cron_stopping = True
|
||||
|
||||
while _cron_subprocs:
|
||||
_cron_subprocs.pop().terminate()
|
||||
|
||||
class extcron(threading.Thread):
|
||||
|
||||
@@ -232,6 +234,7 @@ class cronlauncher(threading.Thread):
|
||||
|
||||
def run(self):
|
||||
import subprocess
|
||||
global _cron_subprocs
|
||||
if isinstance(self.cmd, (list, tuple)):
|
||||
cmd = self.cmd
|
||||
else:
|
||||
@@ -241,6 +244,7 @@ class cronlauncher(threading.Thread):
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE,
|
||||
shell=self.shell)
|
||||
_cron_subprocs.append(proc)
|
||||
(stdoutdata, stderrdata) = proc.communicate()
|
||||
if proc.returncode != 0:
|
||||
logger.warning(
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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():
|
||||
"""
|
||||
|
||||
@@ -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):
|
||||
@@ -117,18 +160,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 +182,3 @@ def loads_yaml(data):
|
||||
if have_yaml:
|
||||
return yamlib.load(data)
|
||||
else: raise ImportError("No YAML serializer available")
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@ except ImportError:
|
||||
from cgi import parse_qs as psq
|
||||
import os
|
||||
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 TABLE, THEAD, TBODY, TR, TD, TH, STYLE
|
||||
@@ -286,9 +287,9 @@ jQuery.fn.grow_input = function() {
|
||||
function pe(ul, e) {
|
||||
var new_line = ml(ul);
|
||||
rel(ul);
|
||||
if ($(e.target).parent().is(':visible')) {
|
||||
if (jQuery(e.target).parent().is(':visible')) {
|
||||
//make sure we didn't delete the element before we insert after
|
||||
new_line.insertAfter($(e.target).parent());
|
||||
new_line.insertAfter(jQuery(e.target).parent());
|
||||
} else {
|
||||
//the line we clicked on was deleted, just add to end of list
|
||||
new_line.appendTo(ul);
|
||||
@@ -299,7 +300,7 @@ function pe(ul, e) {
|
||||
function rl(ul, e) {
|
||||
if (jQuery(ul).children().length > 1) {
|
||||
//only remove if we have more than 1 item so the list is never empty
|
||||
$(e.target).parent().remove();
|
||||
jQuery(e.target).parent().remove();
|
||||
}
|
||||
}
|
||||
function ml(ul) {
|
||||
@@ -349,6 +350,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')
|
||||
|
||||
@@ -461,8 +468,8 @@ class CheckboxesWidget(OptionsWidget):
|
||||
if opts:
|
||||
opts.append(
|
||||
INPUT(requires=attr.get('requires', None),
|
||||
_style="display:none;",
|
||||
_disabled="disabled",
|
||||
_style="display:none;",
|
||||
_disabled="disabled",
|
||||
_name=field.name,
|
||||
hideerror=False))
|
||||
return parent(*opts, **attr)
|
||||
@@ -542,7 +549,7 @@ class UploadWidget(FormWidget):
|
||||
|
||||
requires = attr["requires"]
|
||||
if requires == [] or isinstance(requires, IS_EMPTY_OR):
|
||||
inp = DIV(inp,
|
||||
inp = DIV(inp,
|
||||
SPAN('[',
|
||||
A(current.T(
|
||||
UploadWidget.GENERIC_DESCRIPTION), _href=url),
|
||||
@@ -553,13 +560,13 @@ class UploadWidget(FormWidget):
|
||||
LABEL(current.T(cls.DELETE_FILE),
|
||||
_for=field.name + cls.ID_DELETE_SUFFIX,
|
||||
_style='display:inline'),
|
||||
']', _style='white-space:nowrap'),
|
||||
']', _style='white-space:nowrap'),
|
||||
br, image)
|
||||
else:
|
||||
inp = DIV(inp,
|
||||
inp = DIV(inp,
|
||||
SPAN('[',
|
||||
A(cls.GENERIC_DESCRIPTION, _href=url),
|
||||
']', _style='white-space:nowrap'),
|
||||
']', _style='white-space:nowrap'),
|
||||
br, image)
|
||||
return inp
|
||||
|
||||
@@ -1174,13 +1181,14 @@ 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
|
||||
|
||||
|
||||
|
||||
# when writable, add submit button
|
||||
self.custom.submit = ''
|
||||
@@ -1223,7 +1231,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 +1240,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,7 +1450,8 @@ 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
|
||||
@@ -1580,7 +1591,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']
|
||||
|
||||
@@ -1654,7 +1665,7 @@ class SQLFORM(FORM):
|
||||
value_input = SQLFORM.widgets.date.widget(field,field.default,_id=_id)
|
||||
elif field.type == 'datetime':
|
||||
value_input = SQLFORM.widgets.datetime.widget(field,field.default,_id=_id)
|
||||
elif (field.type.startswith('reference ') or
|
||||
elif (field.type.startswith('reference ') or
|
||||
field.type.startswith('list:reference ')) and \
|
||||
hasattr(field.requires,'options'):
|
||||
value_input = SELECT(
|
||||
@@ -1669,7 +1680,7 @@ class SQLFORM(FORM):
|
||||
else:
|
||||
value_input = INPUT(
|
||||
_type='text', _id=_id, _class=field.type)
|
||||
|
||||
|
||||
new_button = INPUT(
|
||||
_type="button", _value=T('New'), _class="btn",
|
||||
_onclick="%s_build_query('new','%s')" % (prefix,field))
|
||||
@@ -1759,8 +1770,10 @@ class SQLFORM(FORM):
|
||||
createargs={},
|
||||
editargs={},
|
||||
viewargs={},
|
||||
selectable_submit_button='Submit',
|
||||
buttons_placement = 'right',
|
||||
links_placement = 'right'
|
||||
links_placement = 'right',
|
||||
noconfirm=False
|
||||
):
|
||||
|
||||
# jQuery UI ThemeRoller classes (empty if ui is disabled)
|
||||
@@ -1816,7 +1829,7 @@ class SQLFORM(FORM):
|
||||
|
||||
def url(**b):
|
||||
b['args'] = args + b.get('args', [])
|
||||
localvars = request.vars.copy()
|
||||
localvars = request.get_vars.copy()
|
||||
localvars.update(b.get('vars', {}))
|
||||
b['vars'] = localvars
|
||||
b['hash_vars'] = False
|
||||
@@ -1825,7 +1838,7 @@ class SQLFORM(FORM):
|
||||
|
||||
def url2(**b):
|
||||
b['args'] = request.args + b.get('args', [])
|
||||
localvars = request.vars.copy()
|
||||
localvars = request.get_vars.copy()
|
||||
localvars.update(b.get('vars', {}))
|
||||
b['vars'] = localvars
|
||||
b['hash_vars'] = False
|
||||
@@ -1849,7 +1862,7 @@ class SQLFORM(FORM):
|
||||
|
||||
def gridbutton(buttonclass='buttonadd', buttontext=T('Add'),
|
||||
buttonurl=url(args=[]), callback=None,
|
||||
delete=None, trap=True):
|
||||
delete=None, trap=True, noconfirm=None):
|
||||
if showbuttontext:
|
||||
return A(SPAN(_class=ui.get(buttonclass)),
|
||||
SPAN(T(buttontext), _title=buttontext,
|
||||
@@ -1857,12 +1870,14 @@ class SQLFORM(FORM):
|
||||
_href=buttonurl,
|
||||
callback=callback,
|
||||
delete=delete,
|
||||
noconfirm=noconfirm,
|
||||
_class=trap_class(ui.get('button'), trap))
|
||||
else:
|
||||
return A(SPAN(_class=ui.get(buttonclass)),
|
||||
_href=buttonurl,
|
||||
callback=callback,
|
||||
delete=delete,
|
||||
noconfirm=noconfirm,
|
||||
_title=buttontext,
|
||||
_class=trap_class(ui.get('buttontext'), trap))
|
||||
|
||||
@@ -1888,7 +1903,7 @@ class SQLFORM(FORM):
|
||||
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)
|
||||
|
||||
@@ -1925,7 +1940,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(
|
||||
@@ -1944,7 +1959,7 @@ class SQLFORM(FORM):
|
||||
res.search_form = search_form
|
||||
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)
|
||||
@@ -1959,7 +1974,7 @@ class SQLFORM(FORM):
|
||||
res.view_form = view_form
|
||||
res.search_form = search_form
|
||||
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)
|
||||
@@ -1984,7 +1999,7 @@ class SQLFORM(FORM):
|
||||
res.view_form = view_form
|
||||
res.search_form = search_form
|
||||
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])
|
||||
@@ -2056,7 +2071,8 @@ class SQLFORM(FORM):
|
||||
elif not request.vars.records:
|
||||
request.vars.records = []
|
||||
|
||||
session['_web2py_grid_referrer_' + formname] = url2(vars=request.vars)
|
||||
session['_web2py_grid_referrer_' + formname] = \
|
||||
url2(vars=request.get_vars)
|
||||
console = DIV(_class='web2py_console %(header)s %(cornertop)s' % ui)
|
||||
error = None
|
||||
if create:
|
||||
@@ -2106,10 +2122,15 @@ class SQLFORM(FORM):
|
||||
if subquery:
|
||||
dbset = dbset(subquery)
|
||||
try:
|
||||
if left or groupby:
|
||||
if groupby:
|
||||
c = 'count(*)'
|
||||
nrows = dbset.select(c, left=left, cacheable=True,
|
||||
groupby=groupby).first()[c]
|
||||
nrows = db.executesql(
|
||||
'select count(*) from (%s);' %
|
||||
dbset._select(c, left=left, cacheable=True,
|
||||
groupby=groupby)[:-1])[0][0]
|
||||
elif left:
|
||||
c = 'count(*)'
|
||||
nrows = dbset.select(c, left=left, cacheable=True).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)
|
||||
@@ -2341,6 +2362,7 @@ class SQLFORM(FORM):
|
||||
'buttondelete', 'Delete',
|
||||
url(args=['delete', tablename, id]),
|
||||
callback=url(args=['delete', tablename, id]),
|
||||
noconfirm=noconfirm,
|
||||
delete='tr'))
|
||||
if buttons_placement in ['right', 'both']:
|
||||
trcols.append(row_buttons)
|
||||
@@ -2362,9 +2384,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]
|
||||
@@ -2458,6 +2483,16 @@ class SQLFORM(FORM):
|
||||
if constraints is None:
|
||||
constraints = {}
|
||||
field = None
|
||||
name = None
|
||||
def format(table,row):
|
||||
if not row:
|
||||
return 'Unknown'
|
||||
elif isinstance(table._format,str):
|
||||
return table._format % row
|
||||
elif callable(table._format):
|
||||
return table._format(row)
|
||||
else:
|
||||
return '#'+str(row.id)
|
||||
try:
|
||||
nargs = len(args) + 1
|
||||
previous_tablename, previous_fieldname, previous_id = \
|
||||
@@ -2484,14 +2519,7 @@ class SQLFORM(FORM):
|
||||
raise HTTP(400)
|
||||
previous_tablename, previous_fieldname, previous_id = \
|
||||
tablename, fieldname, id
|
||||
try:
|
||||
format = db[referee]._format
|
||||
if callable(format):
|
||||
name = format(record)
|
||||
else:
|
||||
name = format % record
|
||||
except TypeError:
|
||||
name = id
|
||||
name = format(db[referee],record)
|
||||
breadcrumbs.append(
|
||||
LI(A(T(db[referee]._plural),
|
||||
_class=trap_class(),
|
||||
@@ -2509,8 +2537,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):
|
||||
@@ -2535,31 +2564,70 @@ 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,
|
||||
user_signature=user_signature, **kwargs)
|
||||
|
||||
if isinstance(grid, DIV):
|
||||
header = table._plural + (field and ' for ' + field.label or '')
|
||||
breadcrumbs.append(LI(A(T(header), _class=trap_class(),
|
||||
_href=url()), _class='active w2p_grid_breadcrumb_elem'))
|
||||
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()),
|
||||
SPAN(divider, _class='divider') if next else '',
|
||||
_class='active w2p_grid_breadcrumb_elem'))
|
||||
if grid.create_form:
|
||||
header = T('New %s' % table._singular)
|
||||
elif grid.update_form:
|
||||
header = T('Edit %s' % format(table,grid.update_form.record))
|
||||
elif grid.view_form:
|
||||
header = T('View %s' % format(table,grid.view_form.record))
|
||||
if next:
|
||||
breadcrumbs.append(LI(
|
||||
A(T(header), _class=trap_class(),_href=url()),
|
||||
_class='active w2p_grid_breadcrumb_elem'))
|
||||
grid.insert(
|
||||
0, DIV(UL(*breadcrumbs, **{'_class': breadcrumbs_class}),
|
||||
_class='web2py_breadcrumbs'))
|
||||
_class='web2py_breadcrumbs'))
|
||||
return grid
|
||||
|
||||
|
||||
@@ -2612,7 +2680,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),
|
||||
@@ -2634,8 +2702,8 @@ class SQLTABLE(TABLE):
|
||||
},
|
||||
}
|
||||
|
||||
table = SQLTABLE(rows, headers=headers, extracolums=extracolums)
|
||||
|
||||
table = SQLTABLE(rows, headers=headers, extracolumns=extracolumns)
|
||||
`<
|
||||
|
||||
"""
|
||||
|
||||
@@ -2994,4 +3062,3 @@ class ExporterJSON(ExportClass):
|
||||
return self.rows.as_json()
|
||||
else:
|
||||
return 'null'
|
||||
|
||||
|
||||