Merge github.com:web2py/web2py
This commit is contained in:
2
VERSION
2
VERSION
@@ -1 +1 @@
|
||||
Version 2.00.0 (2012-08-18 16:21:48) dev
|
||||
Version 2.00.0 (2012-08-21 07:57:05) dev
|
||||
|
||||
@@ -222,14 +222,15 @@ def select():
|
||||
(rows, nrows) = ([], 0)
|
||||
response.flash = DIV(T('Invalid Query'),PRE(str(e)))
|
||||
# begin handle upload csv
|
||||
if table:
|
||||
csv_table = table or request.vars.table
|
||||
if csv_table:
|
||||
formcsv = FORM(str(T('or import from csv file'))+" ",
|
||||
INPUT(_type='file',_name='csvfile'),
|
||||
INPUT(_type='hidden',_value=table,_name='table'),
|
||||
INPUT(_type='hidden',_value=csv_table,_name='table'),
|
||||
INPUT(_type='submit',_value=T('import')))
|
||||
else:
|
||||
formcsv = None
|
||||
if formcsv and formcsv.process().accepted and request.vars.csvfile:
|
||||
if formcsv and formcsv.process().accepted:
|
||||
try:
|
||||
import_csv(db[request.vars.table],
|
||||
request.vars.csvfile.file)
|
||||
|
||||
@@ -1102,7 +1102,7 @@ def plugin():
|
||||
|
||||
def filter_plugins(items):
|
||||
regex=re.compile('^plugin_'+plugin+'(/.*|\..*)?$')
|
||||
return [item for item in items if regex.match(item)]
|
||||
return [item for item in items if item and regex.match(item)]
|
||||
|
||||
return dict(app=app,
|
||||
models=filter_plugins(models),
|
||||
|
||||
481
applications/admin/languages/nl.py
Executable file
481
applications/admin/languages/nl.py
Executable file
@@ -0,0 +1,481 @@
|
||||
# coding: utf8
|
||||
{
|
||||
'!langcode!': 'nl',
|
||||
'!langname!': 'Nederlands',
|
||||
'"update" is an optional expression like "field1=\'newvalue\'". You cannot update or delete the results of a JOIN': '"update" is een optionele expressie zoals "veld1=\'nieuwewaarde\'". Je kan de resultaten van een JOIN niet updaten of verwijderen.',
|
||||
'"User Exception" debug mode. ': '"Gebruiker Exceptie" debug mode.',
|
||||
'"User Exception" debug mode. An error ticket could be issued!': '"Gebruiker Exceptie" debug mode. Een error ticket kan worden aangemaakt!',
|
||||
'%s': '%s',
|
||||
'%s %%{row} deleted': '%s %%{row} verwijderd',
|
||||
'%s %%{row} updated': '%s %%{row} geupdate',
|
||||
'%s Recent Tweets': '%s Recente Tweets',
|
||||
'%s students registered': '%s studenten geregistreerd',
|
||||
'%Y-%m-%d': '%Y/%m/%d',
|
||||
'%Y-%m-%d %H:%M:%S': '%Y/%m/%d %H:%M:%S',
|
||||
'(requires internet access)': '(vereist internettoegang)',
|
||||
'(something like "it-it")': '(zoiets als "it-it")',
|
||||
'@markmin\x01Searching: **%s** %%{file}': '@markmin: zoeken: **%s** %%{file}',
|
||||
'Abort': 'Afbreken',
|
||||
'About': 'Over',
|
||||
'about': 'over',
|
||||
'About application': 'Over applicatie',
|
||||
'Add breakpoint': 'Voeg breakpoint toe',
|
||||
'Additional code for your application': 'Additionele code voor je applicatie',
|
||||
'admin disabled because no admin password': 'admin uitgezet omdat er geen admin wachtwoord is',
|
||||
'admin disabled because not supported on google app engine': 'admin uitgezet omdat dit niet ondersteund wordt op google app engine',
|
||||
'admin disabled because too many invalid login attempts': 'admin is uitgezet omdat er te veel ongeldige login attempts zijn geweest',
|
||||
'admin disabled because unable to access password file': 'admin is uitgezet omdat er geen toegang was tot het wachtwoordbestand',
|
||||
'Admin is disabled because insecure channel': 'Admin is uitgezet vanwege onveilig kanaal',
|
||||
'Admin language': 'Admintaal',
|
||||
'administrative interface': 'administratieve interface',
|
||||
'Administrator Password:': 'Administrator Wachtwoord:',
|
||||
'and rename it:': 'en hernoem het:',
|
||||
'App does not exist or your are not authorized': 'App bestaat niet of je bent niet geautoriseerd',
|
||||
'appadmin': 'appadmin',
|
||||
'appadmin is disabled because insecure channel': 'appadmin is uitgezet vanwege een onveilig kanaal',
|
||||
'application "%s" uninstalled': 'applicatie "%s" gedeïnstalleerd',
|
||||
'application %(appname)s installed with md5sum: %(digest)s': 'applicatie %(appname)s geïnstalleerd met md5sum: %(digest)s',
|
||||
'Application cannot be generated in demo mode': 'Applicatie kan niet gegenereerd worden in demo-mode',
|
||||
'application compiled': 'applicatie gecompileerd',
|
||||
'application is compiled and cannot be designed': 'applicatie is gecompileerd en kan niet worden ontworpen',
|
||||
'Application name:': 'Applicatienaam:',
|
||||
'are not used': 'worden niet gebruikt',
|
||||
'are not used yet': 'worden nog niet gebruikt',
|
||||
'Are you sure you want to delete file "%s"?': 'Weet je zeker dat je bestand "%s" wilt verwijderen?',
|
||||
'Are you sure you want to delete plugin "%s"?': 'Weet je zeker dat je plugin "%s"? wilt verwijderen?',
|
||||
'Are you sure you want to delete this object?': 'Weet je zeker dat je dit object wilt verwijderen?',
|
||||
'Are you sure you want to uninstall application "%s"?': 'Weet je zeker dat je applicatie "%s" wilt deïnstalleren?',
|
||||
'arguments': 'argumenten',
|
||||
'at char %s': 'bij karakter %s',
|
||||
'at line %s': 'op regel %s',
|
||||
'ATTENTION:': 'LET OP:',
|
||||
'ATTENTION: Login requires a secure (HTTPS) connection or running on localhost.': 'LET OP: Login heeft beveiligde (HTTPS) verbinding nodig of moet draaien op localhost.',
|
||||
'ATTENTION: TESTING IS NOT THREAD SAFE SO DO NOT PERFORM MULTIPLE TESTS CONCURRENTLY.': 'LET OP: TESTEN IS NIET THREAD SAFE EN PROBEER NIET MEERDERE TESTEN TEGELIJK TE DOEN.',
|
||||
'ATTENTION: you cannot edit the running application!': 'LET OP: je kan de draaiende applicatie niet bewerken!',
|
||||
'Available databases and tables': 'Beschikbare databases en tabellen',
|
||||
'back': 'terug',
|
||||
'bad_resource': 'slechte_resource',
|
||||
'Basics': 'Basics',
|
||||
'Begin': 'Begin',
|
||||
'breakpoint': 'breakpoint',
|
||||
'Breakpoints': 'Breakpoints',
|
||||
'breakpoints': 'breakpoints',
|
||||
'Bulk Register': 'Bulk Registreer',
|
||||
'Bulk Student Registration': 'Bulk Studentenregistratie',
|
||||
'cache': 'cache',
|
||||
'Cache Keys': 'Cache Keys',
|
||||
'cache, errors and sessions cleaned': 'cache, errors en sessies geleegd',
|
||||
'can be a git repo': 'can een git repo zijn',
|
||||
'Cancel': 'Cancel',
|
||||
'Cannot be empty': 'Kan niet leeg zijn',
|
||||
'Cannot compile: there are errors in your app:': 'Kan niet compileren: er bevinden zich fouten in je app:',
|
||||
'cannot create file': 'kan bestand niet maken',
|
||||
'cannot upload file "%(filename)s"': 'kan bestand "%(filename)s" niet uploaden',
|
||||
'Change admin password': 'Verander admin wachtwoord',
|
||||
'check all': 'vink alles aan',
|
||||
'Check for upgrades': 'Controleer voor upgrades',
|
||||
'Check to delete': 'Vink aan om te verwijderen',
|
||||
'Checking for upgrades...': 'Controleren voor upgrades...',
|
||||
'Clean': 'Clean',
|
||||
'Clear CACHE?': 'Leeg CACHE?',
|
||||
'Clear DISK': 'Leeg DISK',
|
||||
'Clear RAM': 'Leeg RAM',
|
||||
'Click row to expand traceback': 'Klik rij om traceback uit te klappen',
|
||||
'Click row to view a ticket': 'Klik rij om ticket te bekijken',
|
||||
'code': 'code',
|
||||
'Code listing': 'Code listing',
|
||||
'collapse/expand all': 'klap in/klap alles uit',
|
||||
'Command': 'Commando',
|
||||
'Commit': 'Commit',
|
||||
'Compile': 'Compileer',
|
||||
'compiled application removed': 'Gecompileerde applicatie verwijderd',
|
||||
'Condition': 'Conditie',
|
||||
'contact_admin': 'contact_admin',
|
||||
'continue': 'ga door',
|
||||
'Controllers': 'Controllers',
|
||||
'controllers': 'controllers',
|
||||
'Count': 'Count',
|
||||
'Create': 'Maak',
|
||||
'create': 'maak',
|
||||
'create file with filename:': 'maak bestand met naam:',
|
||||
'create plural-form': 'maak meervoudsvorm',
|
||||
'Create rules': 'Maak regels',
|
||||
'created by': 'gemaakt door:',
|
||||
'Created On': 'Gemaakt Op',
|
||||
'crontab': 'crontab',
|
||||
'Current request': 'Huidige request',
|
||||
'Current response': 'Huidige response',
|
||||
'Current session': 'Huidige sessie',
|
||||
'currently running': 'draait op het moment',
|
||||
'currently saved or': 'op het moment opgeslagen of',
|
||||
'data uploaded': 'data geupload',
|
||||
'database': 'database',
|
||||
'database %s select': 'database %s select',
|
||||
'database administration': 'database administratie',
|
||||
'Date and Time': 'Datum en Tijd',
|
||||
'db': 'db',
|
||||
'Debug': 'Debug',
|
||||
'defines tables': 'definieert tabellen',
|
||||
'Delete': 'Verwijder',
|
||||
'delete': 'verwijder',
|
||||
'delete all checked': 'verwijder alle aangevinkten',
|
||||
'delete plugin': 'verwijder plugin',
|
||||
'Delete this file (you will be asked to confirm deletion)': 'Verwijder dit bestand (je zal worden gevraagd om de verwijdering te bevestigen)',
|
||||
'Delete:': 'Verwijder:',
|
||||
'deleted after first hit': 'verwijder na eerste hit',
|
||||
'Deploy': 'Deploy',
|
||||
'Deploy on Google App Engine': 'Deploy op Google App Engine (GAE)',
|
||||
'Deploy to OpenShift': 'Deploy op OpenShift',
|
||||
'Deployment form': 'Deploymentformulier',
|
||||
'design': 'design',
|
||||
'Detailed traceback description': 'Gedetailleerde traceback beschrijving',
|
||||
'details': 'details',
|
||||
'direction: ltr': 'directie: ltr',
|
||||
'directory not found': 'directory niet gevonden',
|
||||
'Disable': 'Zet uit',
|
||||
'Disabled': 'Uitgezet',
|
||||
'disabled in demo mode': 'uitgezet in demo-modus',
|
||||
'disabled in multi user mode': 'uitgezet in multi-usermodus',
|
||||
'Disk Cache Keys': 'Disk Cache Keys',
|
||||
'Disk Cleared': 'Disk Cleared',
|
||||
'docs': 'docs',
|
||||
'done!': 'gereed!',
|
||||
'Downgrade': 'Downgrade',
|
||||
'download layouts': 'download layouts',
|
||||
'download plugins': 'download plugins',
|
||||
'Edit': 'Bewerk',
|
||||
'edit all': 'bewerk alles',
|
||||
'Edit application': 'Bewerk applicatie',
|
||||
'edit controller': 'bewerk controller',
|
||||
'Edit current record': 'Bewerk huidige record',
|
||||
'edit views:': 'bewerk views:',
|
||||
'Editing file "%s"': 'Bewerk bestand "%s"',
|
||||
'Editing Language file': 'Taalbestand aan het bewerken',
|
||||
'Editing Plural Forms File': 'Meervoudsvormenbestand aan het bewerken',
|
||||
'Enable': 'Zet aan',
|
||||
'enter a value': 'geef een waarde',
|
||||
'Error': 'Error',
|
||||
'Error logs for "%(app)s"': 'Error logs voor "%(app)s"',
|
||||
'Error snapshot': 'Error snapshot',
|
||||
'Error ticket': 'Errorticket',
|
||||
'Errors': 'Errors',
|
||||
'Exception %(extype)s: %(exvalue)s': 'Exceptie %(extype)s: %(exvalue)s',
|
||||
'Exception %s': 'Exceptie %s',
|
||||
'Exception instance attributes': 'Exceptie instantie attributen',
|
||||
'Expand Abbreviation': 'Klap Afkorting uit',
|
||||
'export as csv file': 'exporteer als csv-bestand',
|
||||
'exposes': 'stelt bloot',
|
||||
'exposes:': 'stelt bloot:',
|
||||
'extends': 'extends',
|
||||
'failed to compile file because:': 'niet gelukt om bestand te compileren omdat:',
|
||||
'failed to reload module because:': 'niet gelukt om module te herladen omdat:',
|
||||
'faq': 'faq',
|
||||
'File': 'Bestand',
|
||||
'file "%(filename)s" created': 'bestand "%(filename)s" gemaakt',
|
||||
'file "%(filename)s" deleted': 'bestand "%(filename)s" verwijderd',
|
||||
'file "%(filename)s" uploaded': 'bestand "%(filename)s" geupload',
|
||||
'file "%s" of %s restored': 'bestand "%s" van %s hersteld',
|
||||
'file changed on disk': 'bestand veranderd op schijf',
|
||||
'file does not exist': 'bestand bestaat niet',
|
||||
'file not found': 'bestand niet gevonden',
|
||||
'file saved on %(time)s': 'bestand opgeslagen op %(time)s',
|
||||
'file saved on %s': 'bestand bewaard op %s',
|
||||
'Filename': 'Bestandsnaam',
|
||||
'filter': 'filter',
|
||||
'Frames': 'Frames',
|
||||
'Functions with no doctests will result in [passed] tests.': 'Functies zonder doctests zullen resulteren in [passed] tests.',
|
||||
'GAE Email': 'GAE Email',
|
||||
'GAE Output': 'GAE Output',
|
||||
'GAE Password': 'GAE Password',
|
||||
'Generate': 'Genereer',
|
||||
'Get from URL:': 'Krijg van URL:',
|
||||
'Git Pull': 'Git Pull',
|
||||
'Git Push': 'Git Push',
|
||||
'Globals##debug': 'Globals##debug',
|
||||
'Go to Matching Pair': 'Ga naar Matchende Paar',
|
||||
'go!': 'ga!',
|
||||
'Google App Engine Deployment Interface': 'Google App Engine Deployment Interface',
|
||||
'Google Application Id': 'Google Application Id',
|
||||
'Goto': 'Ga naar',
|
||||
'Help': 'Help',
|
||||
'Hide/Show Translated strings': 'Verberg/Toon Vertaalde strings',
|
||||
'Hits': 'Hits',
|
||||
'Home': 'Home',
|
||||
'honored only if the expression evaluates to true': 'wordt alleen gerespecteerd als expressie waar is',
|
||||
'If start the downgrade, be patient, it may take a while to rollback': 'Wees geduldig na het starten van de downgrade, het kan een tijd duren om de rollback uit te voeren',
|
||||
'If start the upgrade, be patient, it may take a while to download': 'Wees geduldig na het starten van de upgrade, het kan een tijd duren om de download te voltooien',
|
||||
'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.': 'Als de bovenstaande report een ticketnummer bevat indiceert dit een fout in het uitvoeren van de controller, nog voor een poging wordt gedaan om de doctests uit te voeren. Dit wordt meestal veroorzaak door een inspringfout of een fout buiten de functie-code. Een groene titel indiceert dat alle tests (wanneer gedefinieerd) geslaagd zijn. In dit geval worden testresultaten niet getoond.',
|
||||
'Import/Export': 'Import/Export',
|
||||
'In development, use the default Rocket webserver that is currently supported by this debugger.': 'Binnen ontwikkeling, gebruik de default Rocket webserver die op het moment ondersteund wordt door deze debugger.',
|
||||
'includes': 'includes',
|
||||
'index': 'index',
|
||||
'insert new': 'insert new',
|
||||
'insert new %s': 'insert new %s',
|
||||
'inspect attributes': 'inspecteer attributen',
|
||||
'Install': 'Install',
|
||||
'Installed applications': 'Geïnstalleerde applicaties',
|
||||
'Interaction at %s line %s': 'Interactie op %s regel %s',
|
||||
'Interactive console': 'Interactieve console',
|
||||
'internal error': 'interne error',
|
||||
'internal error: %s': 'interne error: %s',
|
||||
'Internal State': 'Interne State',
|
||||
'Invalid action': 'Ongeldige actie',
|
||||
'invalid circual reference': 'ongeldige cirkelreferentie',
|
||||
'invalid circular reference': 'Ongeldige circulaire referentie',
|
||||
'invalid password': 'ongeldig wachtwoord',
|
||||
'invalid password.': 'ongeldig wachtwoord.',
|
||||
'Invalid Query': 'Ongeldige Query',
|
||||
'invalid request': 'ongeldige request',
|
||||
'invalid request ': 'ongeldige request',
|
||||
'invalid table names (auth_* tables already defined)': 'ongeldige tabelnamen (auth_* tabellen zijn al gedefinieerd)',
|
||||
'invalid ticket': 'ongeldige ticket',
|
||||
'Key': 'Key',
|
||||
'Key bindings': 'Key bindings',
|
||||
'Key bindings for ZenCoding Plugin': 'Key bindings voor ZenCoding Plugin',
|
||||
'kill process': 'kill proces',
|
||||
'language file "%(filename)s" created/updated': 'taalbestand "%(filename)s" gemaakt/geupdate',
|
||||
'Language files (static strings) updated': 'Taalbestanden (statische strings) geupdate',
|
||||
'languages': 'talen',
|
||||
'Languages': 'Talen',
|
||||
'Last saved on:': 'Laatst opgeslagen op:',
|
||||
'License for': 'Licentie voor',
|
||||
'Line number': 'Regelnummer',
|
||||
'LineNo': 'RegelNr',
|
||||
'loading...': 'laden...',
|
||||
'locals': 'locals',
|
||||
'Locals##debug': 'Locals##debug',
|
||||
'Login': 'Login',
|
||||
'login': 'Login',
|
||||
'Login to the Administrative Interface': 'Login op de Administratieve Interface',
|
||||
'Logout': 'Logout',
|
||||
'Main Menu': 'Hoofdmenu',
|
||||
'Manage Admin Users/Students': 'Beheer Admin Gebruikers/Studenten',
|
||||
'Manage Students': 'Beheer Studenten',
|
||||
'Match Pair': 'Match Pair',
|
||||
'merge': 'samenvoegen',
|
||||
'Merge Lines': 'Voeg Regels Samen',
|
||||
'Minimum length is %s': 'Minimale lengte is %s',
|
||||
'Models': 'Modellen',
|
||||
'models': 'modellen',
|
||||
'Modified On': 'Verandert Op',
|
||||
'Modules': 'Modules',
|
||||
'modules': 'modules',
|
||||
'Must include at least %s %s': 'Moet ten minste bevatten %s %s',
|
||||
'Must include at least %s lower case': 'Moet ten minste bevatten %s lower case',
|
||||
'Must include at least %s of the following : %s': 'Moet ten minste bevatten %s van het volgende : %s',
|
||||
'Must include at least %s upper case': 'Moet ten minste bevatten %s upper case',
|
||||
'new application "%s" created': 'nieuwe applicatie "%s" gemaakt',
|
||||
'New Application Wizard': 'Nieuwe Applicatie Wizard',
|
||||
'New application wizard': 'Nieuwe applicatie wizard',
|
||||
'new plugin installed': 'nieuwe plugin geïnstalleerd',
|
||||
'New Record': 'Nieuw Record',
|
||||
'new record inserted': 'nieuw record ingevoegd',
|
||||
'New simple application': 'Nieuwe eenvoudige applicatie',
|
||||
'next': 'volgende',
|
||||
'next 100 rows': 'volgende 100 rijen',
|
||||
'Next Edit Point': 'Volgende Bewerkpunt',
|
||||
'NO': 'NEE',
|
||||
'No databases in this application': 'Geen databases in deze applicatie',
|
||||
'No Interaction yet': 'Nog geen interactie',
|
||||
'no match': 'geen match',
|
||||
'no permission to uninstall "%s"': 'geen permissie om "%s" te deïnstalleren',
|
||||
'No ticket_storage.txt found under /private folder': 'Geen ticket_storage.txt gevonden onder /private directory',
|
||||
'Not Authorized': 'Geen Rechten',
|
||||
'Note: If you receive an error with github status code of 128, ensure the system and account you are deploying from has a cooresponding ssh key configured in the openshift account.': 'Notitie: Bij een Github error status code 128, zorg ervoor dat het systeem en het account dat je aan het deployen bent een correspondeerde ssh key geconfigureerd heeft in het openshift account. ',
|
||||
"On production, you'll have to configure your webserver to use one process and multiple threads to use this debugger.": 'Om op productie deze debugger te gebruiken, moet je webserver configureren om een proces en meerdere threads te gebruiken.',
|
||||
'online designer': 'online designer',
|
||||
'OpenShift Deployment Interface': 'OpenShift Deployment Interface',
|
||||
'OpenShift Output': 'OpenShift Output',
|
||||
'or import from csv file': 'of importeer van csv-bestand',
|
||||
'Original/Translation': 'Oorspronkelijk/Vertaling',
|
||||
'Overwrite installed app': 'Overschrijf geïnstalleerde app',
|
||||
'Pack all': 'Pack all',
|
||||
'Pack compiled': 'Pack compiled',
|
||||
'pack plugin': 'pack plugin',
|
||||
'PAM authenticated user, cannot change password here': 'PAM geauthenticeerde gebruiker, kan wachtwoord hier niet wijzigen',
|
||||
'password changed': 'wachtwoord gewijzigd',
|
||||
'Path to appcfg.py': 'Pad naar appcfg.py',
|
||||
'Path to local openshift repo root.': 'Pad naar lokale openshift repo root.',
|
||||
'peek': 'gluur',
|
||||
'Peeking at file': 'Gluren naar bestand',
|
||||
'Please': 'Alstublieft',
|
||||
'plugin': 'plugin',
|
||||
'plugin "%(plugin)s" deleted': 'plugin "%(plugin)s" gedetecteerd',
|
||||
'Plugin "%s" in application': 'Plugin "%s" in applicatie',
|
||||
'plugin not specified': 'plugin niet gespecialiseerd',
|
||||
'plugins': 'plugins',
|
||||
'Plugins': 'Plugins',
|
||||
'Plural Form #%s': 'Meervoudsvorm #%s',
|
||||
'Plural-Forms:': 'Meervoudsvormen',
|
||||
'Powered by': 'Powered by',
|
||||
'previous 100 rows': 'vorige 100 rijen',
|
||||
'Previous Edit Point': 'Vorige Bewerkpunt',
|
||||
'Private files': 'Privébestanden',
|
||||
'private files': 'privébestanden',
|
||||
'Project Progress': 'Projectvoortgang',
|
||||
'Pull': 'Pull',
|
||||
'Push': 'Push',
|
||||
'Query:': 'Query:',
|
||||
'RAM Cache Keys': 'RAM Cache Keys',
|
||||
'Ram Cleared': 'Ram Cleared',
|
||||
'record': 'record',
|
||||
'record does not exist': 'record bestaat niet',
|
||||
'record id': 'record id',
|
||||
'refresh': 'ververs',
|
||||
'Reload routes': 'Herlaadt routes',
|
||||
'Remove compiled': 'Verwijder gecompileerde',
|
||||
'Removed Breakpoint on %s at line %s': 'Verwijder Breakpoint op %s op regel %s',
|
||||
'request': 'request',
|
||||
'requires python-git, but not installed': 'vereist python-git, maar niet geïnstalleerd',
|
||||
'resolve': 'oplossen',
|
||||
'Resolve Conflict file': 'Los Conflictbestand op',
|
||||
'response': 'antwoord',
|
||||
'restart': 'herstart',
|
||||
'restore': 'herstel',
|
||||
'return': 'keer terug',
|
||||
'revert': 'herstel',
|
||||
'Rows in table': 'Rijen in tabel',
|
||||
'Rows selected': 'Rijen geselecteerd',
|
||||
'rules are not defined': 'regels zijn niet gedefinieerd',
|
||||
'rules parsed with errors': 'regels geparsed met errors',
|
||||
'rules:': 'regels:',
|
||||
'Run tests': 'Draai testen',
|
||||
'Run tests in this file': 'Draai testen in dit bestand',
|
||||
"Run tests in this file (to run all files, you may also use the button labelled 'test')": "Draai testen in dit bestand (om alle bestanden te draaien, kun je ook de button genaamd 'test' gebruiken)",
|
||||
'Running on %s': 'Draait op %s',
|
||||
'runonce': 'runonce',
|
||||
'Save': 'Bewaar',
|
||||
'Save via Ajax': 'Bewaar via Ajax',
|
||||
'Saved file hash:': 'Opgeslagen bestandhash:',
|
||||
'search': 'zoek',
|
||||
'selected': 'Geselecteerd',
|
||||
'session': 'sessie',
|
||||
'session expired': 'sessie verlopen',
|
||||
'Set Breakpoint on %s at line %s: %s': 'Zet Breakpoint op %s op regel %s: %s',
|
||||
'shell': 'shell',
|
||||
'signup': 'signup',
|
||||
'signup_requested': 'signup_requested',
|
||||
'Singular Form': 'Enkelvoudsvorm',
|
||||
'site': 'site',
|
||||
'Site': 'Site',
|
||||
'skip to generate': 'sla over om te genereren',
|
||||
'some files could not be removed': 'sommige bestanden konden niet worden verwijderd',
|
||||
'Sorry, could not find mercurial installed': 'Sorry, mercurial is niet geïnstalleerd',
|
||||
'Start a new app': 'Start een nieuwe app',
|
||||
'Start wizard': 'Start wizard',
|
||||
'state': 'state',
|
||||
'static': 'statisch',
|
||||
'Static files': 'Statische bestanden',
|
||||
'Step': 'Stap',
|
||||
'step': 'stap',
|
||||
'stop': 'stop',
|
||||
'submit': 'submit',
|
||||
'Submit': 'Submit',
|
||||
'successful': 'succesvol',
|
||||
'table': 'tabel',
|
||||
'tags': 'tags',
|
||||
'Temporary': 'tijdelijk',
|
||||
'test': 'test',
|
||||
'Testing application': 'Applicatie Testen',
|
||||
'The "query" is a condition like "db.table1.field1==\'value\'". Something like "db.table1.field1==db.table2.field2" results in a SQL JOIN.': 'De "query" is een conditie zoals "db.tabel1.veld1==\'waarde\'". Zoiets als "db.tabel1.veld1==db.tabel2.veld2" resulteert in een SQL JOIN. ',
|
||||
'The app exists, was created by wizard, continue to overwrite!': 'De app bestaat, was gemaakt door de wizard, ga door om te overschrijven!',
|
||||
'The app exists, was NOT created by wizard, continue to overwrite!': 'De app bestaat, wat NIET gemaakt door de wizard, ga door om te overschrijven!',
|
||||
'The application logic, each URL path is mapped in one exposed function in the controller': 'De applicatie logica, elk URL pad is gemapped in een blootgestelde functie in de controller',
|
||||
'The data representation, define database tables and sets': 'De data representatie, definieer database tabellen en sets',
|
||||
'The presentations layer, views are also known as templates': 'De presentatielaag, views ook bekend als templates',
|
||||
'There are no controllers': 'Er zijn geen controllers',
|
||||
'There are no models': 'Er zijn geen modellen',
|
||||
'There are no modules': 'Er zijn geen modules',
|
||||
'There are no plugins': 'Er zijn geen plugins',
|
||||
'There are no static files': 'Er zijn geen statische bestanden',
|
||||
'There are no translators': 'Er zijn geen vertalingen',
|
||||
'There are no translators, only default language is supported': 'Er zijn geen vertalingen, alleen de standaardtaal wordt ondersteund.',
|
||||
'There are no views': 'Er zijn geen views',
|
||||
'These files are not served, they are only available from within your app': 'Deze bestanden worden niet geserveerd, ze zijn alleen beschikbaar vanuit binnen je app.',
|
||||
'These files are served without processing, your images go here': 'Deze bestanden worden geserveerd zonder verwerkingen, je afbeeldingen horen hier',
|
||||
"This debugger may not work properly if you don't have a threaded webserver or you're using multiple daemon processes.": 'Deze debugger werkt misschien niet goed, of je hebt geen threaded webserver, of je gebruikt multiple daemon processen.',
|
||||
'This is an experimental feature and it needs more testing. If you decide to downgrade you do it at your own risk': 'Dit is een experimentele feature en heeft meer tests nodig. Downgraden op eigen risico.',
|
||||
'This is an experimental feature and it needs more testing. If you decide to upgrade you do it at your own risk': 'Dit is een experimentele feature en heeft meer tests nodig. Upgraden op eigen risico.',
|
||||
'This is the %(filename)s template': 'Dit is de %(filename)s template',
|
||||
"This page can commit your changes to an openshift app repo and push them to your cloud instance. This assumes that you've already created the application instance using the web2py skeleton and have that repo somewhere on a filesystem that this web2py instance can access. This functionality requires GitPython installed and on the python path of the runtime that web2py is operating in.": 'Op deze pagina kan je veranderingen naar een openshift app repo committen en pushen naar je cloud-instantie. Dit gaat er vanuit dat je de applicatie-instantie al gemaakt hebt met de web2py skeleton en de repo ergens op een bestandssysteem hebt waar de web2py-instantie toegang tot heeft. Deze functionaliteit vereist ook een geïnstalleerde GitPython welke beschikbaar is in het python pad van de runtime waar web2py ook in opereert.',
|
||||
'This page can upload your application to the Google App Engine computing cloud. Mind that you must first create indexes locally and this is done by installing the Google appserver and running the app locally with it once, or there will be errors when selecting records. Attention: deployment may take long time, depending on the network speed. Attention: it will overwrite your app.yaml. DO NOT SUBMIT TWICE.': 'Op deze pagina kan je applicatie uploaden naar Google App Engine. Let op, dat je eerst je indexes lokaal aanmaakt. Dit kun je doen door de Google appserver te installeren en de app lokaal eenmaal te draaien, anders krijg je error wanneer je records selecteert. Attentie: deployment kan een lange tijd duren, afhankelijk van de netwerksnelheid. Attentie: het overschrijft je app.yaml. SUBMIT NIET TWEE KEER!',
|
||||
'this page to see if a breakpoint was hit and debug interaction is required.': 'deze pagina om te zien of een breakpoint geraakt is en debug-interactie nodig is',
|
||||
'This will pull changes from the remote repo for application "%s"?': 'Dit zal veranderingen van de remote repo for applicatie "%s" pullen. ',
|
||||
'This will push changes to the remote repo for application "%s".': 'Dit zal veranderingen naar de remote repo for applicatie "%s" pushen. ',
|
||||
'ticket': 'ticket',
|
||||
'Ticket': 'Ticket',
|
||||
'Ticket ID': 'Ticket ID',
|
||||
'tickets': 'tickets',
|
||||
'Time in Cache (h:m:s)': 'Tijd in Cache (u:m:s)',
|
||||
'to previous version.': 'naar vorige versie.',
|
||||
'To create a plugin, name a file/folder plugin_[name]': 'Om een plugin te maken, neem een bestand/directory plugin_[naam]',
|
||||
'To emulate a breakpoint programatically, write:': 'Om een breakpoint programmatische te emuleren, schrijf:',
|
||||
'to use the debugger!': 'om de debugger te gebruiken!',
|
||||
'toggle breakpoint': 'toggle breakpoint',
|
||||
'Traceback': 'Traceback',
|
||||
'Translation strings for the application': 'Vertaalstrings van de applicatie',
|
||||
'try something like': 'probeer zoiets als',
|
||||
'try view': 'try view',
|
||||
'Type PDB debugger command in here and hit Return (Enter) to execute it.': 'Type PDB debugger commando hier en druk op Return (Enter) om het uit te voeren.',
|
||||
'Type python statement in here and hit Return (Enter) to execute it.': 'Type python statement hier en druk op Return (Enter) om het uit te voeren.',
|
||||
'Unable to check for upgrades': 'Onmogelijk om voor upgrades te checken',
|
||||
'unable to create application "%s"': 'onmogelijk om applicatie "%s" te maken',
|
||||
'unable to create application "%s" (it may exist already)': 'onmogelijk om applicatie "%s" te maken (mogelijk bestaat deze al)',
|
||||
'unable to delete file "%(filename)s"': 'onmogelijk om bestand "%(filename)s" te verwijderen',
|
||||
'unable to delete file plugin "%(plugin)s"': 'onmogelijk om pluginbestand "%(plugin)s" te verwijderen',
|
||||
'Unable to determine the line number!': 'Onmogelijk om regelnummer te bepalen!',
|
||||
'Unable to download app because:': 'Onmogelijk om app the downloaden omdat:',
|
||||
'Unable to download because:': 'Onmogelijk om te downloaden omdat:',
|
||||
'unable to download layout': 'onmogelijk om layout te downloaden',
|
||||
'unable to download plugin: %s': 'onmogelijk om plugin te downloaden: %s',
|
||||
'unable to install application "%(appname)s"': 'onmogelijk om applicatie "%(appname)s" te installeren',
|
||||
'unable to parse csv file': 'onmogelijk om csv-bestand te parsen',
|
||||
'unable to uninstall "%s"': 'onmogelijk om te deïnstalleren "%s"',
|
||||
'unable to upgrade because "%s"': 'onmogelijk om te upgraden omdat "%s"',
|
||||
'unauthorized': 'niet geautoriseerd ',
|
||||
'uncheck all': 'vink alles uit',
|
||||
'uninstall': 'deïnstalleer',
|
||||
'Uninstall': 'Deïnstalleer',
|
||||
'Unsupported webserver working mode: %s': 'Niet ondersteunde webserver werkmodus: %s',
|
||||
'update': 'update',
|
||||
'update all languages': 'update alle talen',
|
||||
'Update:': 'Update:',
|
||||
'Upgrade': 'Upgrade',
|
||||
'upgrade now': 'upgrade now',
|
||||
'upgrade_web2py': 'upgrade_web2py',
|
||||
'upload': 'upload',
|
||||
'Upload a package:': 'Upload een package:',
|
||||
'Upload and install packed application': 'Upload en installeer packed applicatie',
|
||||
'upload file:': 'upload bestand:',
|
||||
'upload plugin file:': 'upload pluginbestand:',
|
||||
'Use (...)&(...) for AND, (...)|(...) for OR, and ~(...) for NOT to build more complex queries.': 'Gebruik (...)&(...) voor AND, (...)|(...) voor OR, en ~(...) voor NOT om meer complexe queries te maken.',
|
||||
'user': 'gebruiker',
|
||||
'Using the shell may lock the database to other users of this app.': 'Het gebruik van de shell kan database locken voor andere gebruikers van deze app.',
|
||||
'value not allowed': 'waarde is niet toegestaan',
|
||||
'variables': 'variabelen',
|
||||
'Version': 'Versie',
|
||||
'Version %s.%s.%s (%s) %s': 'Versie %s.%s.%s (%s) %s',
|
||||
'Versioning': 'Versionering',
|
||||
'view': 'view',
|
||||
'Views': 'Views',
|
||||
'views': 'views',
|
||||
'WARNING:': 'WAARSCHUWING:',
|
||||
'Web Framework': 'Web Framework',
|
||||
'web2py apps to deploy': 'web2py apps om te deployen',
|
||||
'web2py Debugger': 'web2py Debugger',
|
||||
'web2py downgrade': 'web2py downgrade',
|
||||
'web2py is up to date': 'web2py is up to date',
|
||||
'web2py online debugger': 'web2py online debugger',
|
||||
'web2py Recent Tweets': 'web2py Recente Tweets',
|
||||
'web2py upgrade': 'web2py upgrade',
|
||||
'web2py upgraded; please restart it': 'web2py geupgrade; herstart alstublieft',
|
||||
'Wrap with Abbreviation': 'Wrap met Afkorting',
|
||||
'WSGI reference name': 'WSGI reference name',
|
||||
'YES': 'JA',
|
||||
'You can also set and remove breakpoint in the edit window, using the Toggle Breakpoint button': 'Je kan ook een breakpoint zetten of verwijderen in het bewerkscherm met de Toggle Breakpoint-knop',
|
||||
'You have one more login attempt before you are locked out': 'Je hebt nog een poging om in te loggen voor je buitengesloten wordt.',
|
||||
'you must specify a name for the uploaded application': 'je moet een naam specificeren voor de geuploade applicatie',
|
||||
'You need to set up and reach a': 'Je moet het volgende opzetten en bereiken:',
|
||||
'Your application will be blocked until you click an action button (next, step, continue, etc.)': 'Je applicatie zal geblokkeerd zijn tot je een actie button aanklikt (volgende, step, ga door, etc.)',
|
||||
'Your can inspect variables using the console bellow': 'Je kan je variabelen inspecteren in de console hieronder',
|
||||
}
|
||||
@@ -83,6 +83,8 @@ td.w2p_fl,td.w2p_fw,td.w2p_fc {vertical-align:top}
|
||||
td.w2p_fl {text-align:right}
|
||||
td.w2p_fl, td.w2p_fw {padding-right:7px}
|
||||
td.w2p_fl,td.w2p_fc {padding-top:4px}
|
||||
div.w2p_export_menu {margin:5px 0}
|
||||
div.w2p_export_menu a {margin-left:5px; padding:2px 5px; background-color:#f1f1f1; border-radius:5px; -moz-border-radius:5px; -webkit-border-radius:5px;}
|
||||
|
||||
/* tr#submit_record__row {border-top:1px solid #E5E5E5} */
|
||||
#submit_record__row td {padding-top:.5em}
|
||||
@@ -218,8 +220,10 @@ div.error {
|
||||
*/
|
||||
|
||||
.web2py_console form {
|
||||
width:100%;
|
||||
display:inline;
|
||||
width: 100%;
|
||||
display: inline;
|
||||
vertical-align: middle;
|
||||
margin: 0 0 0 5px;
|
||||
}
|
||||
|
||||
.web2py_console form select {
|
||||
@@ -285,8 +289,6 @@ div.error {
|
||||
font-weight:bold;
|
||||
}
|
||||
|
||||
#w2p_query_panel {}
|
||||
|
||||
.web2py_breadcrumbs ul {
|
||||
list-style:none;
|
||||
margin-bottom:18px;
|
||||
|
||||
@@ -29,7 +29,7 @@ def file_create_form(location):
|
||||
INPUT(_type="submit",_value=T("submit")),_action=URL('create_file'))
|
||||
return form
|
||||
def deletefile(arglist):
|
||||
return A(TAG[''](IMG(_src=URL('static', 'images/delete_icon.png')), SPAN(T('Delete this file (you will be asked to confirm deletion)'))), _class='icon delete tooltip', _href=URL('delete',args=arglist,vars=dict(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)'))), _class='icon delete tooltip', _href=URL('delete',args=arglist,vars=dict(sender=request.function+'/'+app+'/'+request.args[1])))
|
||||
}}
|
||||
|
||||
{{block sectionclass}}plugin{{end}}
|
||||
|
||||
@@ -222,14 +222,15 @@ def select():
|
||||
(rows, nrows) = ([], 0)
|
||||
response.flash = DIV(T('Invalid Query'),PRE(str(e)))
|
||||
# begin handle upload csv
|
||||
if table:
|
||||
csv_table = table or request.vars.table
|
||||
if csv_table:
|
||||
formcsv = FORM(str(T('or import from csv file'))+" ",
|
||||
INPUT(_type='file',_name='csvfile'),
|
||||
INPUT(_type='hidden',_value=table,_name='table'),
|
||||
INPUT(_type='hidden',_value=csv_table,_name='table'),
|
||||
INPUT(_type='submit',_value=T('import')))
|
||||
else:
|
||||
formcsv = None
|
||||
if formcsv and formcsv.process().accepted and request.vars.csvfile:
|
||||
if formcsv and formcsv.process().accepted:
|
||||
try:
|
||||
import_csv(db[request.vars.table],
|
||||
request.vars.csvfile.file)
|
||||
|
||||
@@ -83,6 +83,8 @@ td.w2p_fl,td.w2p_fw,td.w2p_fc {vertical-align:top}
|
||||
td.w2p_fl {text-align:right}
|
||||
td.w2p_fl, td.w2p_fw {padding-right:7px}
|
||||
td.w2p_fl,td.w2p_fc {padding-top:4px}
|
||||
div.w2p_export_menu {margin:5px 0}
|
||||
div.w2p_export_menu a {margin-left:5px; padding:2px 5px; background-color:#f1f1f1; border-radius:5px; -moz-border-radius:5px; -webkit-border-radius:5px;}
|
||||
|
||||
/* tr#submit_record__row {border-top:1px solid #E5E5E5} */
|
||||
#submit_record__row td {padding-top:.5em}
|
||||
@@ -218,8 +220,10 @@ div.error {
|
||||
*/
|
||||
|
||||
.web2py_console form {
|
||||
width:100%;
|
||||
display:inline;
|
||||
width: 100%;
|
||||
display: inline;
|
||||
vertical-align: middle;
|
||||
margin: 0 0 0 5px;
|
||||
}
|
||||
|
||||
.web2py_console form select {
|
||||
@@ -285,8 +289,6 @@ div.error {
|
||||
font-weight:bold;
|
||||
}
|
||||
|
||||
#w2p_query_panel {}
|
||||
|
||||
.web2py_breadcrumbs ul {
|
||||
list-style:none;
|
||||
margin-bottom:18px;
|
||||
|
||||
@@ -222,14 +222,15 @@ def select():
|
||||
(rows, nrows) = ([], 0)
|
||||
response.flash = DIV(T('Invalid Query'),PRE(str(e)))
|
||||
# begin handle upload csv
|
||||
if table:
|
||||
csv_table = table or request.vars.table
|
||||
if csv_table:
|
||||
formcsv = FORM(str(T('or import from csv file'))+" ",
|
||||
INPUT(_type='file',_name='csvfile'),
|
||||
INPUT(_type='hidden',_value=table,_name='table'),
|
||||
INPUT(_type='hidden',_value=csv_table,_name='table'),
|
||||
INPUT(_type='submit',_value=T('import')))
|
||||
else:
|
||||
formcsv = None
|
||||
if formcsv and formcsv.process().accepted and request.vars.csvfile:
|
||||
if formcsv and formcsv.process().accepted:
|
||||
try:
|
||||
import_csv(db[request.vars.table],
|
||||
request.vars.csvfile.file)
|
||||
|
||||
376
applications/welcome/languages/nl.py
Normal file
376
applications/welcome/languages/nl.py
Normal file
@@ -0,0 +1,376 @@
|
||||
# coding: utf8
|
||||
{
|
||||
'!langcode!': 'nl',
|
||||
'!langname!': 'Nederlands',
|
||||
'%(nrows)s records found': '%(nrows)s records gevonden',
|
||||
'%d days ago': '%d dagen geleden',
|
||||
'%d weeks ago': '%d weken gelden',
|
||||
'%s %%{row} deleted': '%s rijen verwijderd',
|
||||
'%s %%{row} updated': '%s rijen geupdate',
|
||||
'%s selected': '%s geselecteerd',
|
||||
'%Y-%m-%d': '%Y-%m-%d',
|
||||
'%Y-%m-%d %H:%M:%S': '%Y-%m-%d %H:%M:%S',
|
||||
'(something like "it-it")': '(zoiets als "nl-nl")',
|
||||
'1 day ago': '1 dag geleden',
|
||||
'1 week ago': '1 week gelden',
|
||||
'<': '<',
|
||||
'<=': '<=',
|
||||
'=': '=',
|
||||
'>': '>',
|
||||
'>=': '>=',
|
||||
'A new version of web2py is available': 'Een nieuwe versie van web2py is beschikbaar',
|
||||
'A new version of web2py is available: %s': 'Een nieuwe versie van web2py is beschikbaar: %s',
|
||||
'About': 'Over',
|
||||
'about': 'over',
|
||||
'About application': 'Over applicatie',
|
||||
'Access Control': 'Toegangscontrole',
|
||||
'Add': 'Toevoegen',
|
||||
'additional code for your application': 'additionele code voor je applicatie',
|
||||
'admin disabled because no admin password': 'admin is uitgezet omdat er geen admin wachtwoord is',
|
||||
'admin disabled because not supported on google app engine': 'admin is uitgezet omdat dit niet ondersteund wordt op google app engine',
|
||||
'admin disabled because unable to access password file': 'admin is uitgezet omdat het wachtwoordbestand niet geopend kan worden',
|
||||
'Admin is disabled because insecure channel': 'Admin is uitgezet om het kanaal onveilig is',
|
||||
'Admin is disabled because unsecure channel': 'Admin is uitgezet om het kanaal onveilig is',
|
||||
'Administration': 'Administratie',
|
||||
'Administrative Interface': 'Administratieve Interface',
|
||||
'Administrator Password:': 'Administrator Wachtwoord',
|
||||
'Ajax Recipes': 'Ajax Recepten',
|
||||
'And': 'En',
|
||||
'and rename it (required):': 'en hernoem deze (vereist)',
|
||||
'and rename it:': 'en hernoem:',
|
||||
'appadmin': 'appadmin',
|
||||
'appadmin is disabled because insecure channel': 'appadmin is uitgezet vanwege een onveilig kanaal',
|
||||
'application "%s" uninstalled': 'applicatie "%s" gedeïnstalleerd',
|
||||
'application compiled': 'applicatie gecompileerd',
|
||||
'application is compiled and cannot be designed': 'applicatie is gecompileerd en kan niet worden ontworpen',
|
||||
'Are you sure you want to delete file "%s"?': 'Weet je zeker dat je bestand "%s" wilt verwijderen?',
|
||||
'Are you sure you want to delete this object?': 'Weet je zeker dat je dit object wilt verwijderen?',
|
||||
'Are you sure you want to uninstall application "%s"?': 'Weet je zeker dat je applicatie "%s" wilt deïnstalleren?',
|
||||
'ATTENTION: Login requires a secure (HTTPS) connection or running on localhost.': 'LET OP: Login vereist een beveiligde (HTTPS) connectie of moet draaien op localhost.',
|
||||
'ATTENTION: TESTING IS NOT THREAD SAFE SO DO NOT PERFORM MULTIPLE TESTS CONCURRENTLY.': 'LET OP: TESTEN IS NIET THREAD SAFE, PROBEER NIET GELIJKTIJDIG MEERDERE TESTS TE DOEN.',
|
||||
'ATTENTION: you cannot edit the running application!': 'LET OP: je kan de applicatie die nu draait niet editen!',
|
||||
'Authentication': 'Authenticatie',
|
||||
'Available databases and tables': 'Beschikbare databases en tabellen',
|
||||
'Back': 'Terug',
|
||||
'Buy this book': 'Koop dit boek',
|
||||
'Cache': 'Cache',
|
||||
'cache': 'cache',
|
||||
'Cache Keys': 'Cache Keys',
|
||||
'cache, errors and sessions cleaned': 'cache, errors en sessies geleegd',
|
||||
'Cannot be empty': 'Mag niet leeg zijn',
|
||||
'Cannot compile: there are errors in your app. Debug it, correct errors and try again.': 'Kan niet compileren: er bevinden zich fouten in je app. Debug, corrigeer de fouten en probeer opnieuw.',
|
||||
'cannot create file': 'kan bestand niet maken',
|
||||
'cannot upload file "%(filename)s"': 'kan bestand "%(filename)s" niet uploaden',
|
||||
'Change Password': 'Wijzig wachtwoord',
|
||||
'Change password': 'Wijzig Wachtwoord',
|
||||
'change password': 'wijzig wachtwoord',
|
||||
'check all': 'vink alles aan',
|
||||
'Check to delete': 'Vink aan om te verwijderen',
|
||||
'clean': 'leeg',
|
||||
'Clear': 'Leeg',
|
||||
'Clear CACHE?': 'Leeg CACHE?',
|
||||
'Clear DISK': 'Leeg DISK',
|
||||
'Clear RAM': 'Clear RAM',
|
||||
'click to check for upgrades': 'Klik om voor upgrades te controleren',
|
||||
'Client IP': 'Client IP',
|
||||
'Community': 'Community',
|
||||
'compile': 'compileren',
|
||||
'compiled application removed': 'gecompileerde applicatie verwijderd',
|
||||
'Components and Plugins': 'Components en Plugins',
|
||||
'contains': 'bevat',
|
||||
'Controller': 'Controller',
|
||||
'Controllers': 'Controllers',
|
||||
'controllers': 'controllers',
|
||||
'Copyright': 'Copyright',
|
||||
'create file with filename:': 'maak bestand met de naam:',
|
||||
'Create new application': 'Maak nieuwe applicatie:',
|
||||
'create new application:': 'maak nieuwe applicatie',
|
||||
'Created By': 'Gemaakt Door',
|
||||
'Created On': 'Gemaakt Op',
|
||||
'crontab': 'crontab',
|
||||
'Current request': 'Huidige request',
|
||||
'Current response': 'Huidige response',
|
||||
'Current session': 'Huidige sessie',
|
||||
'currently saved or': 'op het moment opgeslagen of',
|
||||
'customize me!': 'pas me aan!',
|
||||
'data uploaded': 'data geupload',
|
||||
'Database': 'Database',
|
||||
'database': 'database',
|
||||
'database %s select': 'database %s select',
|
||||
'database administration': 'database administratie',
|
||||
'Date and Time': 'Datum en Tijd',
|
||||
'db': 'db',
|
||||
'DB Model': 'DB Model',
|
||||
'defines tables': 'definieer tabellen',
|
||||
'Delete': 'Verwijder',
|
||||
'delete': 'verwijder',
|
||||
'delete all checked': 'verwijder alle aangevinkten',
|
||||
'Delete:': 'Verwijder:',
|
||||
'Demo': 'Demo',
|
||||
'Deploy on Google App Engine': 'Deploy op Google App Engine',
|
||||
'Deployment Recipes': 'Deployment Recepten',
|
||||
'Description': 'Beschrijving',
|
||||
'design': 'design',
|
||||
'DESIGN': 'DESIGN',
|
||||
'Design for': 'Design voor',
|
||||
'DISK': 'DISK',
|
||||
'Disk Cache Keys': 'Disk Cache Keys',
|
||||
'Disk Cleared': 'Disk Geleegd',
|
||||
'Documentation': 'Documentatie',
|
||||
"Don't know what to do?": 'Weet je niet wat je moet doen?',
|
||||
'done!': 'gereed!',
|
||||
'Download': 'Download',
|
||||
'E-mail': 'E-mail',
|
||||
'E-mail invalid': 'E-mail ongeldig',
|
||||
'edit': 'bewerk',
|
||||
'EDIT': 'BEWERK',
|
||||
'Edit': 'Bewerk',
|
||||
'Edit application': 'Bewerk applicatie',
|
||||
'edit controller': 'bewerk controller',
|
||||
'Edit current record': 'Bewerk huidig record',
|
||||
'Edit Profile': 'Bewerk Profiel',
|
||||
'edit profile': 'bewerk profiel',
|
||||
'Edit This App': 'Bewerk Deze App',
|
||||
'Editing file': 'Bewerk bestand',
|
||||
'Editing file "%s"': 'Bewerk bestand "%s"',
|
||||
'Email and SMS': 'E-mail en SMS',
|
||||
'enter a number between %(min)g and %(max)g': 'geef een getal tussen %(min)g en %(max)g',
|
||||
'enter an integer between %(min)g and %(max)g': 'geef een integer tussen %(min)g en %(max)g',
|
||||
'Error logs for "%(app)s"': 'Error logs voor "%(app)s"',
|
||||
'errors': 'errors',
|
||||
'Errors': 'Errors',
|
||||
'Export': 'Export',
|
||||
'export as csv file': 'exporteer als csv-bestand',
|
||||
'exposes': 'stelt bloot',
|
||||
'extends': 'extends',
|
||||
'failed to reload module': 'niet gelukt om module te herladen',
|
||||
'False': 'Onwaar',
|
||||
'FAQ': 'FAQ',
|
||||
'file "%(filename)s" created': 'bestand "%(filename)s" gemaakt',
|
||||
'file "%(filename)s" deleted': 'bestand "%(filename)s" verwijderd',
|
||||
'file "%(filename)s" uploaded': 'bestand "%(filename)s" geupload',
|
||||
'file "%(filename)s" was not deleted': 'bestand "%(filename)s" was niet verwijderd',
|
||||
'file "%s" of %s restored': 'bestand "%s" van %s hersteld',
|
||||
'file changed on disk': 'bestand aangepast op schijf',
|
||||
'file does not exist': 'bestand bestaat niet',
|
||||
'file saved on %(time)s': 'bestand bewaard op %(time)s',
|
||||
'file saved on %s': 'bestand bewaard op %s',
|
||||
'First name': 'Voornaam',
|
||||
'Forbidden': 'Verboden',
|
||||
'Forms and Validators': 'Formulieren en Validators',
|
||||
'Free Applications': 'Gratis Applicaties',
|
||||
'Functions with no doctests will result in [passed] tests.': 'Functies zonder doctests zullen resulteren in [passed] tests.',
|
||||
'Group %(group_id)s created': 'Groep %(group_id)s gemaakt',
|
||||
'Group ID': 'Groep ID',
|
||||
'Group uniquely assigned to user %(id)s': 'Groep is uniek toegekend aan gebruiker %(id)s',
|
||||
'Groups': 'Groepen',
|
||||
'Hello World': 'Hallo Wereld',
|
||||
'help': 'help',
|
||||
'Home': 'Home',
|
||||
'How did you get here?': 'Hoe ben je hier gekomen?',
|
||||
'htmledit': 'Bewerk HTML',
|
||||
'import': 'import',
|
||||
'Import/Export': 'Import/Export',
|
||||
'includes': 'includes',
|
||||
'Index': 'Index',
|
||||
'insert new': 'voeg nieuwe',
|
||||
'insert new %s': 'voeg nieuwe %s',
|
||||
'Installed applications': 'Geïnstalleerde applicaties',
|
||||
'internal error': 'interne error',
|
||||
'Internal State': 'Interne State',
|
||||
'Introduction': 'Introductie',
|
||||
'Invalid action': 'Ongeldige actie',
|
||||
'Invalid email': 'Ongeldig emailadres',
|
||||
'Invalid password': 'Ongeldig wachtwoord',
|
||||
'invalid password': 'ongeldig wachtwoord',
|
||||
'Invalid Query': 'Ongeldige Query',
|
||||
'invalid request': 'ongeldige request',
|
||||
'invalid ticket': 'ongeldige ticket',
|
||||
'Is Active': 'Is Actief',
|
||||
'Key': 'Key',
|
||||
'language file "%(filename)s" created/updated': 'taalbestand "%(filename)s" gemaakt/geupdate',
|
||||
'Language files (static strings) updated': 'Taalbestanden (statische strings) geupdate',
|
||||
'languages': 'talen',
|
||||
'Languages': 'Talen',
|
||||
'languages updated': 'talen geupdate',
|
||||
'Last name': 'Achternaam',
|
||||
'Last saved on:': 'Laatst bewaard op:',
|
||||
'Layout': 'Layout',
|
||||
'Layout Plugins': 'Layout Plugins',
|
||||
'Layouts': 'Layouts',
|
||||
'License for': 'Licentie voor',
|
||||
'Live Chat': 'Live Chat',
|
||||
'loading...': 'laden...',
|
||||
'Logged in': 'Ingelogd',
|
||||
'Logged out': 'Uitgelogd',
|
||||
'Login': 'Login',
|
||||
'login': 'login',
|
||||
'Login to the Administrative Interface': 'Inloggen op de Administratieve Interface',
|
||||
'logout': 'logout',
|
||||
'Logout': 'Logout',
|
||||
'Lost Password': 'Wachtwoord Kwijt',
|
||||
'Lost password?': 'Wachtwoord kwijt?',
|
||||
'Main Menu': 'Hoofdmenu',
|
||||
'Manage Cache': 'Beheer Cache',
|
||||
'Menu Model': 'Menu Model',
|
||||
'merge': 'samenvoegen',
|
||||
'Models': 'Modellen',
|
||||
'models': 'modellen',
|
||||
'Modified By': 'Aangepast Door',
|
||||
'Modified On': 'Aangepast Op',
|
||||
'Modules': 'Modules',
|
||||
'modules': 'modules',
|
||||
'My Sites': 'Mijn Sites',
|
||||
'Name': 'Naam',
|
||||
'New': 'Nieuw',
|
||||
'new application "%s" created': 'nieuwe applicatie "%s" gemaakt',
|
||||
'New password': 'Nieuw wachtwoord',
|
||||
'New Record': 'Nieuw Record',
|
||||
'new record inserted': 'nieuw record ingevoegd',
|
||||
'next 100 rows': 'volgende 100 rijen',
|
||||
'NO': 'NEE',
|
||||
'No databases in this application': 'Geen database in deze applicatie',
|
||||
'Object or table name': 'Object of tabelnaam',
|
||||
'Old password': 'Oude wachtwoord',
|
||||
'Online examples': 'Online voorbeelden',
|
||||
'Or': 'Of',
|
||||
'or import from csv file': 'of importeer van csv-bestand',
|
||||
'or provide application url:': 'of geef een applicatie url:',
|
||||
'Origin': 'Bron',
|
||||
'Original/Translation': 'Oorspronkelijk/Vertaling',
|
||||
'Other Plugins': 'Andere Plugins',
|
||||
'Other Recipes': 'Andere Recepten',
|
||||
'Overview': 'Overzicht',
|
||||
'pack all': 'pack all',
|
||||
'pack compiled': 'pack compiled',
|
||||
'Password': 'Wachtwoord',
|
||||
"Password fields don't match": 'Wachtwoordvelden komen niet overeen',
|
||||
'Peeking at file': 'Naar bestand aan het gluren',
|
||||
'please input your password again': 'geef alstublieft nogmaals uw wachtwoord',
|
||||
'Plugins': 'Plugins',
|
||||
'Powered by': 'Powered by',
|
||||
'Preface': 'Inleiding',
|
||||
'previous 100 rows': 'vorige 100 rijen',
|
||||
'Profile': 'Profiel',
|
||||
'Python': 'Python',
|
||||
'Query': 'Query',
|
||||
'Query:': 'Query:',
|
||||
'Quick Examples': 'Snelle Voorbeelden',
|
||||
'RAM': 'RAM',
|
||||
'RAM Cache Keys': 'RAM Cache Keys',
|
||||
'Ram Cleared': 'Ram Geleegd',
|
||||
'Recipes': 'Recepten',
|
||||
'record': 'record',
|
||||
'record does not exist': 'record bestaat niet',
|
||||
'record id': 'record id',
|
||||
'Record ID': 'Record ID',
|
||||
'register': 'registreer',
|
||||
'Register': 'Registreer',
|
||||
'Registration identifier': 'Registratie identifier',
|
||||
'Registration key': 'Registratie sleutel',
|
||||
'Registration successful': 'Registratie succesvol',
|
||||
'Remember me (for 30 days)': 'Onthoudt mij (voor 30 dagen)',
|
||||
'remove compiled': 'verwijder gecompileerde',
|
||||
'Request reset password': 'Vraag een wachtwoord reset aan',
|
||||
'Reset Password key': 'Reset Wachtwoord sleutel',
|
||||
'Resolve Conflict file': 'Los Conflictbestand op',
|
||||
'restore': 'herstel',
|
||||
'revert': 'herstel',
|
||||
'Role': 'Rol',
|
||||
'Rows in table': 'Rijen in tabel',
|
||||
'Rows selected': 'Rijen geselecteerd',
|
||||
'save': 'bewaar',
|
||||
'Save profile': 'Bewaar profiel',
|
||||
'Saved file hash:': 'Opgeslagen file hash:',
|
||||
'Search': 'Zoek',
|
||||
'Semantic': 'Semantisch',
|
||||
'Services': 'Services',
|
||||
'session expired': 'sessie verlopen',
|
||||
'shell': 'shell',
|
||||
'site': 'site',
|
||||
'Size of cache:': 'Grootte van cache:',
|
||||
'some files could not be removed': 'sommige bestanden konden niet worden verwijderd',
|
||||
'starts with': 'begint met',
|
||||
'state': 'state',
|
||||
'static': 'statisch',
|
||||
'Static files': 'Statische bestanden',
|
||||
'Statistics': 'Statistieken',
|
||||
'Stylesheet': 'Stylesheet',
|
||||
'Submit': 'Submit',
|
||||
'submit': 'submit',
|
||||
'Support': 'Support',
|
||||
'Sure you want to delete this object?': 'Weet je zeker dat je dit object wilt verwijderen?',
|
||||
'table': 'Tabel',
|
||||
'Table name': 'Tabelnaam',
|
||||
'test': 'test',
|
||||
'Testing application': 'Applicatie testen',
|
||||
'The "query" is a condition like "db.table1.field1==\'value\'". Something like "db.table1.field1==db.table2.field2" results in a SQL JOIN.': 'De "query" is een conditie zoals "db.tabel1.veld1==\'waarde\'". Zoiets als "db.tabel1.veld1==db.tabel2.veld2" resulteert in een SQL JOIN.',
|
||||
'the application logic, each URL path is mapped in one exposed function in the controller': 'the applicatie logica, elk URL pad is gemapped in een blootgestelde functie in de controller',
|
||||
'The Core': 'De Core',
|
||||
'the data representation, define database tables and sets': 'de data representatie, definieert database tabellen en sets',
|
||||
'The output of the file is a dictionary that was rendered by the view %s': 'De output van het bestand is een dictionary die gerenderd werd door de view %s',
|
||||
'the presentations layer, views are also known as templates': 'de presentatie laag, views zijn ook bekend als templates',
|
||||
'The Views': 'De Views',
|
||||
'There are no controllers': 'Er zijn geen controllers',
|
||||
'There are no models': 'Er zijn geen modellen',
|
||||
'There are no modules': 'Er zijn geen modules',
|
||||
'There are no static files': 'Er zijn geen statische bestanden',
|
||||
'There are no translators, only default language is supported': 'Er zijn geen vertalingen, alleen de standaard taal wordt ondersteund.',
|
||||
'There are no views': 'Er zijn geen views',
|
||||
'these files are served without processing, your images go here': 'Deze bestanden worden geserveerd zonder verdere verwerking, je afbeeldingen horen hier',
|
||||
'This App': 'Deze App',
|
||||
'This is a copy of the scaffolding application': 'Dit is een kopie van de steiger-applicatie',
|
||||
'This is the %(filename)s template': 'Dit is de %(filename)s template',
|
||||
'Ticket': 'Ticket',
|
||||
'Time in Cache (h:m:s)': 'Tijd in Cache (h:m:s)',
|
||||
'Timestamp': 'Timestamp (timestamp)',
|
||||
'to previous version.': 'naar vorige versie.',
|
||||
'too short': 'te kort',
|
||||
'translation strings for the application': 'vertaalstrings voor de applicatie',
|
||||
'True': 'Waar',
|
||||
'try': 'probeer',
|
||||
'try something like': 'probeer zoiets als',
|
||||
'Twitter': 'Twitter',
|
||||
'Unable to check for upgrades': 'Niet mogelijk om te controleren voor upgrades',
|
||||
'unable to create application "%s"': 'niet mogelijk om applicatie "%s" te maken',
|
||||
'unable to delete file "%(filename)s"': 'niet mogelijk om bestand "%(filename)s" te verwijderen',
|
||||
'Unable to download': 'Niet mogelijk om te downloaden',
|
||||
'Unable to download app': 'Niet mogelijk om app te downloaden',
|
||||
'unable to parse csv file': 'niet mogelijk om csv-bestand te parsen',
|
||||
'unable to uninstall "%s"': 'niet mogelijk om "%s" te deïnstalleren',
|
||||
'uncheck all': 'vink alles uit',
|
||||
'uninstall': ' deïnstalleer',
|
||||
'update': 'update',
|
||||
'update all languages': 'update alle talen',
|
||||
'Update:': 'Update:',
|
||||
'upload application:': 'upload applicatie:',
|
||||
'Upload existing application': 'Upload bestaande applicatie',
|
||||
'upload file:': 'upload bestand',
|
||||
'Use (...)&(...) for AND, (...)|(...) for OR, and ~(...) for NOT to build more complex queries.': 'Gebruik (...)&(...) voor AND, (...)|(...) voor OR, en ~(...) voor NOT om meer complexe queries te maken.',
|
||||
'User %(id)s Logged-in': 'Gebruiker %(id)s Logged-in',
|
||||
'User %(id)s Logged-out': 'Gebruiker %(id)s Logged-out',
|
||||
'User %(id)s Password changed': 'Wachtwoord van gebruiker %(id)s is veranderd',
|
||||
'User %(id)s Password reset': 'Wachtwoord van gebruiker %(id)s is gereset',
|
||||
'User %(id)s Profile updated': 'Profiel van Gebruiker %(id)s geupdate',
|
||||
'User %(id)s Registered': 'Gebruiker %(id)s Geregistreerd',
|
||||
'User ID': 'User ID',
|
||||
'value already in database or empty': 'waarde al in database of leeg',
|
||||
'Verify Password': 'Verifieer Wachtwoord',
|
||||
'versioning': 'versionering',
|
||||
'Videos': 'Videos',
|
||||
'View': 'View',
|
||||
'view': 'view',
|
||||
'Views': 'Vieuws',
|
||||
'views': 'vieuws',
|
||||
'web2py is up to date': 'web2py is up to date',
|
||||
'web2py Recent Tweets': 'web2py Recente Tweets',
|
||||
'Welcome': 'Welkom',
|
||||
'Welcome %s': 'Welkom %s',
|
||||
'Welcome to web2py': 'Welkom bij web2py',
|
||||
'Welcome to web2py!': 'Welkom bij web2py!',
|
||||
'Which called the function %s located in the file %s': 'Die functie %s aanriep en zich bevindt in het bestand %s',
|
||||
'YES': 'JA',
|
||||
'You are successfully running web2py': 'Je draait web2py succesvol',
|
||||
'You can modify this application and adapt it to your needs': 'Je kan deze applicatie aanpassen naar je eigen behoeften',
|
||||
'You visited the url %s': 'Je bezocht de url %s',
|
||||
}
|
||||
@@ -83,6 +83,8 @@ td.w2p_fl,td.w2p_fw,td.w2p_fc {vertical-align:top}
|
||||
td.w2p_fl {text-align:right}
|
||||
td.w2p_fl, td.w2p_fw {padding-right:7px}
|
||||
td.w2p_fl,td.w2p_fc {padding-top:4px}
|
||||
div.w2p_export_menu {margin:5px 0}
|
||||
div.w2p_export_menu a {margin-left:5px; padding:2px 5px; background-color:#f1f1f1; border-radius:5px; -moz-border-radius:5px; -webkit-border-radius:5px;}
|
||||
|
||||
/* tr#submit_record__row {border-top:1px solid #E5E5E5} */
|
||||
#submit_record__row td {padding-top:.5em}
|
||||
@@ -218,8 +220,10 @@ div.error {
|
||||
*/
|
||||
|
||||
.web2py_console form {
|
||||
width:100%;
|
||||
display:inline;
|
||||
width: 100%;
|
||||
display: inline;
|
||||
vertical-align: middle;
|
||||
margin: 0 0 0 5px;
|
||||
}
|
||||
|
||||
.web2py_console form select {
|
||||
@@ -285,8 +289,6 @@ div.error {
|
||||
font-weight:bold;
|
||||
}
|
||||
|
||||
#w2p_query_panel {}
|
||||
|
||||
.web2py_breadcrumbs ul {
|
||||
list-style:none;
|
||||
margin-bottom:18px;
|
||||
|
||||
@@ -126,12 +126,19 @@ EXTENSION_MAPS = {
|
||||
'xps': googledoc_viewer,
|
||||
}
|
||||
|
||||
class VimeoURLOpener(urllib.FancyURLopener):
|
||||
"Vimeo blocks the urllib user agent for some reason"
|
||||
version = "Mozilla/4.0"
|
||||
urllib._urlopener = VimeoURLOpener()
|
||||
|
||||
def oembed(url):
|
||||
for k,v in EMBED_MAPS:
|
||||
if k.match(url):
|
||||
oembed = v+'?format=json&url='+cgi.escape(url)
|
||||
try:
|
||||
return loads(urllib.urlopen(oembed).read())
|
||||
try:
|
||||
data = urllib.urlopen(oembed).read()
|
||||
print data
|
||||
return loads(data) # json!
|
||||
except:
|
||||
pass
|
||||
return {}
|
||||
@@ -143,10 +150,10 @@ def expand_one(url,cdict):
|
||||
# try ombed but first check in cache
|
||||
if cdict and url in cdict:
|
||||
r = cdict[url]
|
||||
elif cdict:
|
||||
r = cdict[url] = oembed(url)
|
||||
else:
|
||||
r = oembed(url)
|
||||
if isinstance(cdict,dict):
|
||||
cdict[url] = r
|
||||
# if oembed service
|
||||
if 'html' in r:
|
||||
html = r['html'].encode('utf8')
|
||||
|
||||
@@ -510,7 +510,7 @@ META = '\x06'
|
||||
LINK = '\x07'
|
||||
DISABLED_META = '\x08'
|
||||
LATEX = '<img src="http://chart.apis.google.com/chart?cht=tx&chl=%s" />'
|
||||
regex_URL=re.compile(r'@\{(?P<f>\w+)/(?P<args>.*?)\}')
|
||||
regex_URL=re.compile(r'@/(?P<a>\w*)/(?P<c>\w*)/(?P<f>\w*(\.\w+)?)(/(?P<args>[\w\.\-/]+))?')
|
||||
regex_env=re.compile(r'@\{(?P<a>[\w\-\.]+?)(\:(?P<b>.*?))?\}')
|
||||
regex_expand_meta = re.compile('('+META+'|'+DISABLED_META+')')
|
||||
regex_dd=re.compile(r'\$\$(?P<latex>.*?)\$\$')
|
||||
@@ -801,8 +801,9 @@ def render(text,
|
||||
# this is experimental @{function/args}
|
||||
# turns into a digitally signed URL
|
||||
def u1(match,URL=URL):
|
||||
f,args = match.group('f','args')
|
||||
return URL(f,args=args.split('/'), scheme=True, host=True)
|
||||
a,c,f,args = match.group('a','c','f','args')
|
||||
return URL(a=a or None,c=c or None,f = f or None,
|
||||
args=args.split('/'), scheme=True, host=True)
|
||||
text = regex_URL.sub(u1,text)
|
||||
|
||||
if latex == 'google':
|
||||
|
||||
1
gluon/contrib/rules/__init__.py
Normal file
1
gluon/contrib/rules/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
|
||||
14
gluon/dal.py
14
gluon/dal.py
@@ -4566,7 +4566,7 @@ class CouchDBAdapter(NoSQLAdapter):
|
||||
fieldnames = [f.name for f in (fields or self.db[tablename])]
|
||||
colnames = ['%s.%s' % (tablename,k) for k in fieldnames]
|
||||
fields = ','.join(['%s.%s' % (tablename,uid(f)) for f in fieldnames])
|
||||
fn="function(%(t)s){if(%(query)s)emit(%(order)s,[%(fields)s]);}" %\
|
||||
fn="(function(%(t)s){if(%(query)s)emit(%(order)s,[%(fields)s]);})" %\
|
||||
dict(t=tablename,
|
||||
query=self.expand(query),
|
||||
order='%s._id' % tablename,
|
||||
@@ -4880,6 +4880,10 @@ class MongoDBAdapter(NoSQLAdapter):
|
||||
# need to define all the 'sql' methods gt,lt etc....
|
||||
|
||||
def select(self,query,fields,attributes,count=False,snapshot=False):
|
||||
try:
|
||||
from pymongo.objectid import ObjectId
|
||||
except ImportError:
|
||||
from bson.objectid import ObjectId
|
||||
tablename, mongoqry_dict, mongofields_dict, \
|
||||
mongosort_list, limitby_limit, limitby_skip = \
|
||||
self._select(query,fields,attributes)
|
||||
@@ -6763,7 +6767,7 @@ def index():
|
||||
patterns += auto_table(rtable,base=tag,depth=depth-1)
|
||||
return patterns
|
||||
|
||||
if patterns=='auto':
|
||||
if patterns==DEFAULT:
|
||||
patterns=[]
|
||||
for table in db.tables:
|
||||
if not table.startswith('auth_'):
|
||||
@@ -6943,7 +6947,7 @@ def index():
|
||||
table_class = args.get('table_class',Table)
|
||||
table = table_class(self, tablename, *fields, **args)
|
||||
table._actual = True
|
||||
self[tablename] = table
|
||||
self[tablename] = table
|
||||
table._create_references() # must follow above line to handle self references
|
||||
|
||||
migrate = self._migrate_enabled and args.get('migrate',self._migrate)
|
||||
@@ -7283,7 +7287,7 @@ class Table(dict):
|
||||
if self._db and not field.type in ('text','blob') and \
|
||||
self._db._adapter.maxcharlength < field.length:
|
||||
field.length = self._db._adapter.maxcharlength
|
||||
if field.requires is DEFAULT:
|
||||
if field.requires == DEFAULT:
|
||||
field.requires = sqlhtml_validators(field)
|
||||
self.ALL = SQLALL(self)
|
||||
|
||||
@@ -8069,7 +8073,7 @@ class Field(Expression):
|
||||
length=None,
|
||||
default=DEFAULT,
|
||||
required=False,
|
||||
requires=None,
|
||||
requires=DEFAULT,
|
||||
ondelete='CASCADE',
|
||||
notnull=False,
|
||||
unique=False,
|
||||
|
||||
@@ -338,7 +338,6 @@ def check_credentials(request, other_application='admin', expiration = 60*60):
|
||||
s = get_session(request, other_application)
|
||||
return (s.authorized and s.last_time and s.last_time > dt)
|
||||
|
||||
|
||||
def fix_newlines(path):
|
||||
regex = re.compile(r'''(\r
|
||||
|\r|
|
||||
|
||||
@@ -1358,6 +1358,8 @@ class A(DIV):
|
||||
tag = 'a'
|
||||
|
||||
def xml(self):
|
||||
if not self.components and self['_href']:
|
||||
self.append(self['_href'])
|
||||
if self['delete']:
|
||||
d = "jQuery(this).closest('%s').remove();" % self['delete']
|
||||
else:
|
||||
|
||||
@@ -109,7 +109,7 @@ HEARTBEAT = 3*SECONDS
|
||||
MAXHIBERNATION = 10
|
||||
CLEAROUT = '!clear!'
|
||||
|
||||
CALLABLETYPES = (types.LambdaType, types.FunctionType,
|
||||
CALLABLETYPES = (types.LambdaType, types.FunctionType,
|
||||
types.BuiltinFunctionType,
|
||||
types.MethodType, types.BuiltinMethodType)
|
||||
|
||||
@@ -181,16 +181,13 @@ def executor(queue,task, out):
|
||||
self.out_queue = out_queue
|
||||
self.stdout = sys.stdout
|
||||
sys.stdout = self
|
||||
self.istr = ""
|
||||
def __del__(self):
|
||||
sys.stdout = self.stdout
|
||||
def flush(self):
|
||||
pass
|
||||
def write(self,data):
|
||||
self.out_queue.put(data)
|
||||
self.istr += data
|
||||
def getvalue(self):
|
||||
return self.istr
|
||||
|
||||
#stdout, sys.stdout = sys.stdout, cStringIO.StringIO()
|
||||
|
||||
stdout = LogOutput(out)
|
||||
try:
|
||||
if task.app:
|
||||
@@ -224,13 +221,11 @@ def executor(queue,task, out):
|
||||
result = eval(task.function)(
|
||||
*loads(task.args, object_hook=_decode_dict),
|
||||
**loads(task.vars, object_hook=_decode_dict))
|
||||
#stdout, sys.stdout = sys.stdout, stdout
|
||||
sys.stdout = stdout.stdout
|
||||
queue.put(TaskReport(COMPLETED, result,stdout.getvalue()))
|
||||
queue.put(TaskReport(COMPLETED, result=result))
|
||||
except BaseException,e:
|
||||
sys.stdout = stdout.stdout
|
||||
tb = traceback.format_exc()
|
||||
queue.put(TaskReport(FAILED,tb=tb, output=stdout.getvalue()))
|
||||
queue.put(TaskReport(FAILED,tb=tb))
|
||||
del stdout
|
||||
|
||||
class MetaScheduler(threading.Thread):
|
||||
def __init__(self):
|
||||
@@ -255,47 +250,62 @@ class MetaScheduler(threading.Thread):
|
||||
self.process = p
|
||||
logging.debug(' task starting')
|
||||
p.start()
|
||||
|
||||
task_output = ""
|
||||
tout = ""
|
||||
|
||||
try:
|
||||
if task.sync_output > 0:
|
||||
task_output = ""
|
||||
start = time.time()
|
||||
while p.is_alive() and (time.time()-start < task.timeout):
|
||||
p.join(timeout=task.sync_output)
|
||||
tout = ""
|
||||
while not out.empty():
|
||||
tout += out.get()
|
||||
if tout:
|
||||
logging.debug(' partial output: "%s"' % str(tout))
|
||||
if CLEAROUT in tout:
|
||||
task_output = tout[tout.rfind(CLEAROUT)+len(CLEAROUT):]
|
||||
else:
|
||||
task_output += tout
|
||||
run_timeout = task.sync_output
|
||||
else:
|
||||
run_timeout = task.timeout
|
||||
|
||||
start = time.time()
|
||||
|
||||
while p.is_alive() and (time.time()-start < task.timeout):
|
||||
if tout:
|
||||
try:
|
||||
logging.debug(' partial output saved')
|
||||
db(sr.id==task.run_id).update(output = task_output)
|
||||
db.commit()
|
||||
else:
|
||||
p.join(task.timeout)
|
||||
except:
|
||||
pass
|
||||
p.join(timeout=run_timeout)
|
||||
tout = ""
|
||||
while not out.empty():
|
||||
tout += out.get()
|
||||
if tout:
|
||||
logging.debug(' partial output: "%s"' % str(tout))
|
||||
if CLEAROUT in tout:
|
||||
task_output = tout[tout.rfind(CLEAROUT)+len(CLEAROUT):]
|
||||
else:
|
||||
task_output += tout
|
||||
except:
|
||||
p.terminate()
|
||||
p.join()
|
||||
self.have_heartbeat = False
|
||||
logging.debug(' task stopped by general exception')
|
||||
return TaskReport(STOPPED)
|
||||
if p.is_alive():
|
||||
p.terminate()
|
||||
logging.debug(' task timeout')
|
||||
try:
|
||||
tr = queue.get(timeout=2)
|
||||
tr.status = TIMEOUT
|
||||
except Queue.Empty:
|
||||
tr = TaskReport(TIMEOUT)
|
||||
return tr
|
||||
elif queue.empty():
|
||||
self.have_heartbeat = False
|
||||
logging.debug(' task stopped')
|
||||
return TaskReport(STOPPED)
|
||||
tr = TaskReport(STOPPED)
|
||||
else:
|
||||
logging.debug(' task completed or failed')
|
||||
return queue.get()
|
||||
if p.is_alive():
|
||||
p.terminate()
|
||||
logging.debug(' task timeout')
|
||||
try:
|
||||
# we try to get a traceback here
|
||||
tr = queue.get(timeout=2)
|
||||
tr.status = TIMEOUT
|
||||
tr.output = task_output
|
||||
except Queue.Empty:
|
||||
tr = TaskReport(TIMEOUT)
|
||||
elif queue.empty():
|
||||
self.have_heartbeat = False
|
||||
logging.debug(' task stopped')
|
||||
tr = TaskReport(STOPPED)
|
||||
else:
|
||||
logging.debug(' task completed or failed')
|
||||
tr = queue.get()
|
||||
tr.output = task_output
|
||||
return tr
|
||||
|
||||
def die(self):
|
||||
logging.info('die!')
|
||||
@@ -588,15 +598,11 @@ class Scheduler(MetaScheduler):
|
||||
#if it's stopped it's None as NoneType, so we record
|
||||
#the STOPPED "run" anyway
|
||||
logging.debug(' recording task report in db (%s)' % task_report.status)
|
||||
#CLEAROUT clears the output
|
||||
tout = task_report.output
|
||||
if tout and CLEAROUT in tout:
|
||||
tout = tout[tout.rfind(CLEAROUT)+len(CLEAROUT):]
|
||||
db(db.scheduler_run.id==task.run_id).update(
|
||||
status = task_report.status,
|
||||
stop_time = now,
|
||||
result = task_report.result,
|
||||
output = tout,
|
||||
output = task_report.output,
|
||||
traceback = task_report.tb)
|
||||
else:
|
||||
logging.debug(' deleting task report in db because of no result')
|
||||
|
||||
186
gluon/sqlhtml.py
186
gluon/sqlhtml.py
@@ -484,12 +484,12 @@ class UploadWidget(FormWidget):
|
||||
requires = attr["requires"]
|
||||
if requires == [] or isinstance(requires, IS_EMPTY_OR):
|
||||
inp = DIV(inp, '[',
|
||||
A(UploadWidget.GENERIC_DESCRIPTION, _href = url),
|
||||
A(current.T(UploadWidget.GENERIC_DESCRIPTION), _href = url),
|
||||
'|',
|
||||
INPUT(_type='checkbox',
|
||||
_name=field.name + cls.ID_DELETE_SUFFIX,
|
||||
_id=field.name + cls.ID_DELETE_SUFFIX),
|
||||
LABEL(cls.DELETE_FILE,
|
||||
LABEL(current.T(cls.DELETE_FILE),
|
||||
_for=field.name + cls.ID_DELETE_SUFFIX),
|
||||
']', br, image)
|
||||
else:
|
||||
@@ -1479,16 +1479,21 @@ class SQLFORM(FORM):
|
||||
operators = SELECT(*[T(option) for option in options])
|
||||
if field.type=='boolean':
|
||||
value_input = SELECT(
|
||||
OPTION(T("True"),_value="T"),OPTION(T("False"),_value="F"),
|
||||
OPTION(T("True"),_value="T"),
|
||||
OPTION(T("False"),_value="F"),
|
||||
_id="w2p_value_"+name)
|
||||
else:
|
||||
value_input = INPUT(_type='text',_id="w2p_value_"+name,_class=field.type)
|
||||
new_button = INPUT(_type="button", _value=T('New'),
|
||||
_onclick="w2p_build_query('new','"+str(field)+"')")
|
||||
and_button = INPUT(_type="button", _value=T('And'),
|
||||
_onclick="w2p_build_query('and','"+str(field)+"')")
|
||||
or_button = INPUT(_type="button", _value=T('Or'),
|
||||
_onclick="w2p_build_query('or','"+str(field)+"')")
|
||||
value_input = INPUT(_type='text',_id="w2p_value_"+name,
|
||||
_class=field.type)
|
||||
new_button = INPUT(
|
||||
_type="button", _value=T('New'),_class="btn",
|
||||
_onclick="w2p_build_query('new','"+str(field)+"')")
|
||||
and_button = INPUT(
|
||||
_type="button", _value=T('And'),_class="btn",
|
||||
_onclick="w2p_build_query('and','"+str(field)+"')")
|
||||
or_button = INPUT(
|
||||
_type="button", _value=T('Or'),_class="btn",
|
||||
_onclick="w2p_build_query('or','"+str(field)+"')")
|
||||
|
||||
criterion.extend([operators,value_input,new_button,and_button,or_button])
|
||||
criteria.append(DIV(criterion, _id='w2p_field_%s' % name,
|
||||
@@ -1512,13 +1517,7 @@ class SQLFORM(FORM):
|
||||
jQuery('#w2p_query_panel').slideUp();
|
||||
}
|
||||
""")
|
||||
return (INPUT(
|
||||
_value=T("Query"),_type="button",_id="w2p_query_trigger",
|
||||
_onclick="jQuery('#w2p_query_fields').change();jQuery('#w2p_query_panel').slideToggle();"),
|
||||
DIV(_id="w2p_query_panel",
|
||||
_class='hidden',
|
||||
*criteria),
|
||||
fadd)
|
||||
return CAT(DIV(_id="w2p_query_panel",_class='hidden',*criteria),fadd)
|
||||
|
||||
|
||||
@staticmethod
|
||||
@@ -1628,9 +1627,9 @@ class SQLFORM(FORM):
|
||||
|
||||
referrer = session.get('_web2py_grid_referrer_'+formname, url())
|
||||
if user_signature:
|
||||
if (args != request.args and \
|
||||
if (args != request.args and user_signature and \
|
||||
not URL.verify(request,user_signature=user_signature)) or \
|
||||
(not auth.user and \
|
||||
(not session.auth.user and \
|
||||
('edit' in request.args or \
|
||||
'create' in request.args or \
|
||||
'delete' in request.args)):
|
||||
@@ -1770,12 +1769,13 @@ class SQLFORM(FORM):
|
||||
return ret
|
||||
|
||||
exportManager = dict(
|
||||
csv_with_hidden_cols=(ExporterCsv,'csv, hidden cols'),
|
||||
csv=ExporterCsv,
|
||||
html=ExporterHtml,
|
||||
tsv_with_hidden_cols=(ExporterTsv,
|
||||
'tsv (Excel compatible), hidden cols'),
|
||||
tsv=(ExporterTsv, 'tsv (Excel compatible)'))
|
||||
csv_with_hidden_cols=(ExporterCSV,'CSV (hidden cols)'),
|
||||
csv=(ExporterCSV,'CSV'),
|
||||
xml=(ExporterXML, 'XML'),
|
||||
html=(ExporterHTML, 'HTML'),
|
||||
tsv_with_hidden_cols=\
|
||||
(ExporterTSV,'TSV (Excel compatible, hidden cols)'),
|
||||
tsv=(ExporterTSV, 'TSV (Excel compatible)'))
|
||||
if not exportclasses is None:
|
||||
exportManager.update(exportclasses)
|
||||
|
||||
@@ -1789,10 +1789,9 @@ class SQLFORM(FORM):
|
||||
else:
|
||||
sign, rorder = '', order
|
||||
tablename,fieldname = rorder.split('.',1)
|
||||
orderby=db[tablename][fieldname]
|
||||
if sign=='~':
|
||||
orderby=~db[tablename][fieldname]
|
||||
else:
|
||||
orderby=db[tablename][fieldname]
|
||||
orderby=~orderby
|
||||
|
||||
table_fields = [f for f in fields if f._tablename in tablenames]
|
||||
if export_type in ('csv_with_hidden_cols','tsv_with_hidden_cols'):
|
||||
@@ -1809,22 +1808,15 @@ class SQLFORM(FORM):
|
||||
else:
|
||||
rows = dbset.select(left=left,orderby=orderby,*columns)
|
||||
|
||||
if not export_type is None:
|
||||
if exportManager.has_key(export_type):
|
||||
value = exportManager[export_type]
|
||||
if hasattr(value, '__getitem__'):
|
||||
clazz = value[0]
|
||||
else:
|
||||
clazz = value
|
||||
oExp = clazz(rows)
|
||||
filename = '.'.join(('rows', oExp.file_ext))
|
||||
response.headers['Content-Type'] = oExp.content_type
|
||||
response.headers['Content-Disposition'] = \
|
||||
'attachment;filename='+filename+';'
|
||||
|
||||
raise HTTP(200, oExp.export(),
|
||||
**{'Content-Type':oExp.content_type,
|
||||
'Content-Disposition':'attachment;filename='+filename+';'})
|
||||
if exportManager.has_key(export_type):
|
||||
value = exportManager[export_type]
|
||||
clazz = value[0] if hasattr(value, '__getitem__') else value
|
||||
oExp = clazz(rows)
|
||||
filename = '.'.join(('rows', oExp.file_ext))
|
||||
response.headers['Content-Type'] = oExp.content_type
|
||||
response.headers['Content-Disposition'] = \
|
||||
'attachment;filename='+filename+';'
|
||||
raise HTTP(200, oExp.export(),**response.headers)
|
||||
|
||||
elif request.vars.records and not isinstance(
|
||||
request.vars.records,list):
|
||||
@@ -1834,6 +1826,12 @@ class SQLFORM(FORM):
|
||||
|
||||
session['_web2py_grid_referrer_'+formname] = url2(vars=request.vars)
|
||||
console = DIV(_class='web2py_console %(header)s %(cornertop)s' % ui)
|
||||
if create:
|
||||
console.append(gridbutton(
|
||||
buttonclass='buttonadd',
|
||||
buttontext='Add',
|
||||
buttonurl=url(args=['new',tablename])))
|
||||
|
||||
error = None
|
||||
if searchable:
|
||||
sfields = reduce(lambda a,b:a+b,
|
||||
@@ -1841,15 +1839,14 @@ class SQLFORM(FORM):
|
||||
if isinstance(search_widget,dict):
|
||||
search_widget = search_widget[tablename]
|
||||
if search_widget=='default':
|
||||
mq,mf,ms = SQLFORM.search_menu(sfields)
|
||||
search_menu = SQLFORM.search_menu(sfields)
|
||||
search_widget = lambda sfield, url: FORM(
|
||||
mq,
|
||||
INPUT(_name='keywords',_value=request.vars.keywords,
|
||||
_id='web2py_keywords'),
|
||||
INPUT(_type='submit',_value=T('Search')),
|
||||
INPUT(_type='submit',_value=T('Clear'),
|
||||
_id='web2py_keywords',_onfocus="jQuery('#w2p_query_fields').change();jQuery('#w2p_query_panel').slideDown();"),
|
||||
INPUT(_type='submit',_value=T('Search'),_class="btn"),
|
||||
INPUT(_type='submit',_value=T('Clear'),_class="btn",
|
||||
_onclick="jQuery('#web2py_keywords').val('');"),
|
||||
mf,ms,_method="GET",_action=url)
|
||||
search_menu,_method="GET",_action=url)
|
||||
form = search_widget and search_widget(sfields,url()) or ''
|
||||
console.append(form)
|
||||
keywords = request.vars.get('keywords','')
|
||||
@@ -1875,40 +1872,6 @@ class SQLFORM(FORM):
|
||||
nrows = 0
|
||||
error = T('Unsupported query')
|
||||
|
||||
search_actions = DIV(_class='web2py_search_actions')
|
||||
if create:
|
||||
search_actions.append(gridbutton(
|
||||
buttonclass='buttonadd',
|
||||
buttontext='Add',
|
||||
buttonurl=url(args=['new',tablename])))
|
||||
if csv and nrows:
|
||||
options =[]
|
||||
for k,v in sorted(exportManager.items()):
|
||||
if hasattr(v, "__getitem__"):
|
||||
label = v[1]
|
||||
else:
|
||||
label = k
|
||||
options.append(OPTION(T(label),_value=k))
|
||||
items = url2().split('?', 1)
|
||||
myurl = items[0]
|
||||
if len(items)>1:
|
||||
mysignature = psq(items[1]).get('_signature', [None])[-1]
|
||||
else:
|
||||
mysignature = ''
|
||||
f = FORM(BUTTON(SPAN(_class=ui.get('buttonexport')),
|
||||
"Export", _type="submit", _class=ui.get('button')),
|
||||
SELECT(options, _name="_export_type"),
|
||||
INPUT(_type="hidden", _name="order",
|
||||
_value=request.vars.order),
|
||||
INPUT(_type="hidden", _name="_signature",
|
||||
_value=mysignature),
|
||||
INPUT(_type="hidden", _name="keywords",
|
||||
_value=request.vars.keywords or ''),
|
||||
_method="GET", _action=myurl)
|
||||
search_actions.append(f)
|
||||
|
||||
console.append(search_actions)
|
||||
|
||||
order = request.vars.order or ''
|
||||
if sortable:
|
||||
if order and not order=='None':
|
||||
@@ -2035,9 +1998,9 @@ class SQLFORM(FORM):
|
||||
elif field.type=='upload':
|
||||
if value:
|
||||
if callable(upload):
|
||||
value = A('File', _href=upload(value))
|
||||
value = A(current.T('file'), _href=upload(value))
|
||||
elif upload:
|
||||
value = A('File',
|
||||
value = A(current.T('file'),
|
||||
_href='%s/%s' % (upload, value))
|
||||
else:
|
||||
value = ''
|
||||
@@ -2082,11 +2045,27 @@ class SQLFORM(FORM):
|
||||
redirect(referrer)
|
||||
else:
|
||||
htmltable = DIV(T('No records found'))
|
||||
|
||||
if csv and nrows:
|
||||
export_links =[]
|
||||
for k,v in sorted(exportManager.items()):
|
||||
label = v[1] if hasattr(v, "__getitem__") else k
|
||||
link = url2(vars=dict(
|
||||
order=request.vars.order or '',
|
||||
_export_type=k,
|
||||
keywords=request.vars.keywords or ''))
|
||||
export_links.append(A(T(label),_href=link))
|
||||
export_menu = \
|
||||
DIV(T('Export:'),_class="w2p_export_menu",*export_links)
|
||||
else:
|
||||
export_menu = None
|
||||
|
||||
res = DIV(console,
|
||||
DIV(htmltable,_class="web2py_table"),
|
||||
DIV(paginator,_class=\
|
||||
"web2py_paginator %(header)s %(cornerbottom)s" % ui),
|
||||
_class='%s %s' % (_class, ui.get('widget')))
|
||||
if export_menu: res.append(export_menu)
|
||||
res.create_form = create_form
|
||||
res.update_form = update_form
|
||||
res.view_form = view_form
|
||||
@@ -2455,9 +2434,9 @@ class SQLTABLE(TABLE):
|
||||
r = 'DATA'
|
||||
elif field.type == 'upload':
|
||||
if upload and r:
|
||||
r = A('file', _href='%s/%s' % (upload, r))
|
||||
r = A(current.T('file'), _href='%s/%s' % (upload, r))
|
||||
elif r:
|
||||
r = 'file'
|
||||
r = current.T('file')
|
||||
else:
|
||||
r = ''
|
||||
elif field.type in ['string','text']:
|
||||
@@ -2524,6 +2503,7 @@ form_factory = SQLFORM.factory # for backward compatibility, deprecated
|
||||
|
||||
|
||||
class ExportClass(object):
|
||||
label = None
|
||||
file_ext = None
|
||||
content_type = None
|
||||
|
||||
@@ -2574,8 +2554,9 @@ class ExportClass(object):
|
||||
def export(self):
|
||||
raise NotImplementedError
|
||||
|
||||
class ExporterTsv(ExportClass):
|
||||
class ExporterTSV(ExportClass):
|
||||
|
||||
label = 'TSV'
|
||||
file_ext = "csv"
|
||||
content_type = "text/tab-separated-values"
|
||||
|
||||
@@ -2607,7 +2588,8 @@ class ExporterTsv(ExportClass):
|
||||
out.truncate(0)
|
||||
return str(final.getvalue())
|
||||
|
||||
class ExporterCsv(ExportClass):
|
||||
class ExporterCSV(ExportClass):
|
||||
label = 'CSV'
|
||||
file_ext = "csv"
|
||||
content_type = "text/csv"
|
||||
|
||||
@@ -2617,7 +2599,8 @@ class ExporterCsv(ExportClass):
|
||||
def export(self):
|
||||
return str(self.rows)
|
||||
|
||||
class ExporterHtml(ExportClass):
|
||||
class ExporterHTML(ExportClass):
|
||||
label = 'HTML'
|
||||
file_ext = "html"
|
||||
content_type = "text/html"
|
||||
|
||||
@@ -2637,5 +2620,26 @@ class ExporterHtml(ExportClass):
|
||||
return str(out.getvalue())
|
||||
|
||||
|
||||
class ExporterXML(ExportClass):
|
||||
label = 'XML'
|
||||
file_ext = "xml"
|
||||
content_type = "text/xml"
|
||||
|
||||
def __init__(self, rows):
|
||||
ExportClass.__init__(self, rows)
|
||||
|
||||
def export(self):
|
||||
out = cStringIO.StringIO()
|
||||
out.write('<rows>\n')
|
||||
colnames = [a.split('.') for a in self.rows.colnames]
|
||||
for row in self.rows.records:
|
||||
out.write('<row>\n')
|
||||
for col in colnames:
|
||||
out.write('<%s>'%col+str(row[col[0]][col[1]])+'</%s>\n'%col)
|
||||
out.write('</row>\n')
|
||||
out.write('</rows>')
|
||||
return str(out.getvalue())
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
162
gluon/storage.py
162
gluon/storage.py
@@ -25,11 +25,7 @@ class List(list):
|
||||
instead of IndexOutOfBounds
|
||||
"""
|
||||
|
||||
def __call__(self, i, default=None, cast=None, otherwise=None):
|
||||
"""
|
||||
request.args(0,default=0,cast=int,otherwise='http://error_url')
|
||||
request.args(0,default=0,cast=int,otherwise=lambda:...)
|
||||
"""
|
||||
def __call__(self, i, default=None, cast=None, url_onerror=None):
|
||||
n = len(self)
|
||||
if 0<=i<n or -n<=i<0:
|
||||
value = self[i]
|
||||
@@ -40,17 +36,13 @@ class List(list):
|
||||
value = cast(value)
|
||||
except (ValueError, TypeError):
|
||||
from http import HTTP, redirect
|
||||
if otherwise is None:
|
||||
raise HTTP(404)
|
||||
elif isinstance(otherwise,str):
|
||||
redirect(otherwise)
|
||||
elif callable(otherwise):
|
||||
return otherwise()
|
||||
if url_onerror:
|
||||
redirect(url_onerror)
|
||||
else:
|
||||
raise RuntimeError, "invalid otherwise"
|
||||
raise HTTP(404)
|
||||
return value
|
||||
|
||||
class Storage(object):
|
||||
class Storage(dict):
|
||||
|
||||
"""
|
||||
A Storage object is like a dictionary except `obj.foo` can be used
|
||||
@@ -73,49 +65,37 @@ class Storage(object):
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self,d=None,**values):
|
||||
self.__dict__.update(d or {},**values)
|
||||
def __getattr__(self,key):
|
||||
return getattr(self,key) if key in self else None
|
||||
def __getitem__(self,key):
|
||||
return getattr(self,key) if key in self else None
|
||||
def __setitem__(self,key,value):
|
||||
setattr(self,key,value)
|
||||
def __delitem__(self,key):
|
||||
delattr(self,key)
|
||||
def __nonzero__(self):
|
||||
return len(self.__dict__)>0
|
||||
def pop(self,key,default=None):
|
||||
def __getattr__(self, key):
|
||||
return dict.get(self, key, None)
|
||||
|
||||
def __setattr__(self, key, value):
|
||||
if value is None:
|
||||
if key in self:
|
||||
del self[key]
|
||||
else:
|
||||
self[key] = value
|
||||
|
||||
def __delattr__(self, key):
|
||||
if key in self:
|
||||
default = getattr(self,key)
|
||||
delattr(self,key)
|
||||
return default
|
||||
def clear(self):
|
||||
self.__dict__.clear()
|
||||
del self[key]
|
||||
else:
|
||||
raise AttributeError, "missing key=%s" % key
|
||||
|
||||
def __getitem__(self, key):
|
||||
return dict.get(self, key, None)
|
||||
|
||||
def __repr__(self):
|
||||
return '<Storage %s>' % self.__dict__
|
||||
def keys(self):
|
||||
return self.__dict__.keys()
|
||||
def items(self):
|
||||
return self.__dict__.items()
|
||||
def __iter__(self):
|
||||
return self.__dict__.__iter__()
|
||||
def has_key(self,key):
|
||||
return key in self.__dict__
|
||||
def __contains__(self,key):
|
||||
return key in self.__dict__
|
||||
def update(self,*args,**kargs):
|
||||
self.__dict__.update(*args,**kargs)
|
||||
def get(self,key,default=None):
|
||||
return getattr(self,key) if key in self else default
|
||||
return '<Storage ' + dict.__repr__(self) + '>'
|
||||
|
||||
def __getstate__(self):
|
||||
return self.__dict__
|
||||
def __setstate__(self, values):
|
||||
for key, value in values.items():
|
||||
setattr(self,key,value)
|
||||
def getlist(self,key):
|
||||
"""
|
||||
Return a Storage value as a list.
|
||||
return dict(self)
|
||||
|
||||
def __setstate__(self, value):
|
||||
for (k, v) in value.items():
|
||||
self[k] = v
|
||||
|
||||
def getlist(self, key):
|
||||
"""Return a Storage value as a list.
|
||||
|
||||
If the value is a list it will be returned as-is.
|
||||
If object is None, an empty list will be returned.
|
||||
@@ -132,13 +112,17 @@ class Storage(object):
|
||||
['abc', 'def']
|
||||
>>> request.vars.getlist('z')
|
||||
[]
|
||||
|
||||
"""
|
||||
value = getattr(self,key,[])
|
||||
return value if not value else \
|
||||
value if isinstance(value,(list,tuple)) else [value]
|
||||
def getfirst(self,key,default=None):
|
||||
"""
|
||||
Return the first or only value when given a request.vars-style key.
|
||||
value = self.get(key, None)
|
||||
if isinstance(value, (list, tuple)):
|
||||
return value
|
||||
elif value is None:
|
||||
return []
|
||||
return [value]
|
||||
|
||||
def getfirst(self, key):
|
||||
"""Return the first or only value when given a request.vars-style key.
|
||||
|
||||
If the value is a list, its first item will be returned;
|
||||
otherwise, the value will be returned as-is.
|
||||
@@ -153,13 +137,15 @@ class Storage(object):
|
||||
>>> request.vars.getfirst('y')
|
||||
'abc'
|
||||
>>> request.vars.getfirst('z')
|
||||
|
||||
"""
|
||||
values = self.getlist(default)
|
||||
return values[0] if values else default
|
||||
def getlast(self,key,default=None):
|
||||
"""
|
||||
Returns the last or only single value when
|
||||
given a request.vars-style key.
|
||||
value = self.getlist(key)
|
||||
if len(value):
|
||||
return value[0]
|
||||
return None
|
||||
|
||||
def getlast(self, key):
|
||||
"""Returns the last or only single value when given a request.vars-style key.
|
||||
|
||||
If the value is a list, the last item will be returned;
|
||||
otherwise, the value will be returned as-is.
|
||||
@@ -174,9 +160,18 @@ class Storage(object):
|
||||
>>> request.vars.getlast('y')
|
||||
'def'
|
||||
>>> request.vars.getlast('z')
|
||||
|
||||
"""
|
||||
values = self.getlist(default)
|
||||
return values[0] if values else default
|
||||
value = self.getlist(key)
|
||||
if len(value):
|
||||
return value[-1]
|
||||
return None
|
||||
|
||||
def __getinitargs__(self):
|
||||
return ()
|
||||
|
||||
def __getnewargs__(self):
|
||||
return ()
|
||||
|
||||
PICKABLE = (str,int,long,float,bool,list,dict,tuple,set)
|
||||
def PickleableStorage(data):
|
||||
@@ -186,15 +181,12 @@ class StorageList(Storage):
|
||||
"""
|
||||
like Storage but missing elements default to [] instead of None
|
||||
"""
|
||||
def __getitem__(self,key):
|
||||
return self.__gteattr__(key)
|
||||
def __getattr__(self, key):
|
||||
if key in self:
|
||||
return getattr(self,key)
|
||||
return self[key]
|
||||
else:
|
||||
r = []
|
||||
setattr(self,key,r)
|
||||
return r
|
||||
self[key] = []
|
||||
return self[key]
|
||||
|
||||
def load_storage(filename):
|
||||
fp = None
|
||||
@@ -215,32 +207,35 @@ def save_storage(storage, filename):
|
||||
if fp: fp.close()
|
||||
|
||||
class Settings(Storage):
|
||||
|
||||
def __setattr__(self, key, value):
|
||||
if key != 'lock_keys' and self.lock_keys and not key in self:
|
||||
if key != 'lock_keys' and self.get('lock_keys', None)\
|
||||
and not key in self:
|
||||
raise SyntaxError, 'setting key \'%s\' does not exist' % key
|
||||
if key != 'lock_values' and self.lock_values:
|
||||
if key != 'lock_values' and self.get('lock_values', None):
|
||||
raise SyntaxError, 'setting value cannot be changed: %s' % key
|
||||
Storage.__setattr__(self,key,value)
|
||||
self[key] = value
|
||||
|
||||
|
||||
class Messages(Storage):
|
||||
|
||||
def __init__(self, T):
|
||||
self.T = T
|
||||
self['T'] = T
|
||||
|
||||
def __setattr__(self, key, value):
|
||||
if key != 'lock_keys' and self.lock_keys and not key in self:
|
||||
if key != 'lock_keys' and self.get('lock_keys', None)\
|
||||
and not key in self:
|
||||
raise SyntaxError, 'setting key \'%s\' does not exist' % key
|
||||
if key != 'lock_values' and self.lock_values:
|
||||
if key != 'lock_values' and self.get('lock_values', None):
|
||||
raise SyntaxError, 'setting value cannot be changed: %s' % key
|
||||
Storage.__setattr__(self,key,value)
|
||||
self[key] = value
|
||||
|
||||
def __getattr__(self, key):
|
||||
value = Storage.__getattr__(self,key)
|
||||
value = self[key]
|
||||
if isinstance(value, str):
|
||||
return str(self.T(value))
|
||||
return str(self['T'](value))
|
||||
return value
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
import doctest
|
||||
doctest.testmod()
|
||||
@@ -249,4 +244,3 @@ if __name__ == '__main__':
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ from email import MIMEBase, MIMEMultipart, MIMEText, Encoders, Header, message_f
|
||||
from contenttype import contenttype
|
||||
from storage import Storage, StorageList, Settings, Messages
|
||||
from utils import web2py_uuid
|
||||
from fileutils import read_file
|
||||
from fileutils import read_file, check_credentials
|
||||
from gluon import *
|
||||
from gluon.contrib.autolinks import expand_one
|
||||
|
||||
@@ -2641,8 +2641,7 @@ class Auth(object):
|
||||
return form
|
||||
|
||||
def is_impersonating(self):
|
||||
return current.session.auth and \
|
||||
'impersonator' in current.session.auth
|
||||
return self.is_logged_in() and 'impersonator' in current.session.auth
|
||||
|
||||
def impersonate(self, user_id=DEFAULT):
|
||||
"""
|
||||
@@ -4470,7 +4469,7 @@ class Wiki(object):
|
||||
def __init__(self,auth,env=None,automenu=True,render='markmin',
|
||||
manage_permissions=False,force_prefix=''):
|
||||
self.env = env or {}
|
||||
self.env['component'] = Wiki.component
|
||||
self.env['component'] = Wiki.component
|
||||
if render == 'markmin': render=self.markmin_render
|
||||
self.auth = auth
|
||||
self.automenu = automenu
|
||||
@@ -4478,6 +4477,7 @@ class Wiki(object):
|
||||
self.force_prefix = force_prefix % self.auth.user
|
||||
else:
|
||||
self.force_prefix = force_prefix
|
||||
self.host = current.request.env.http_host
|
||||
perms = self.manage_permissions = manage_permissions
|
||||
db = auth.db
|
||||
db.define_table(
|
||||
@@ -4519,6 +4519,11 @@ class Wiki(object):
|
||||
if tag: db.wiki_tag.insert(name=tag,wiki_page=page.id)
|
||||
db.wiki_page._after_insert.append(update_tags_insert)
|
||||
db.wiki_page._after_update.append(update_tags_update)
|
||||
if check_credentials(current.request) and \
|
||||
not 'wiki_editor' in auth.user_groups.values():
|
||||
group = db.auth_group(role='wiki_editor')
|
||||
gid = group.id if group else db.auth_group.insert(role='wiki_editor')
|
||||
auth.add_membership(gid)
|
||||
# WIKI ACCESS POLICY
|
||||
def not_authorized(self,page=None):
|
||||
raise HTTP(401)
|
||||
@@ -4552,8 +4557,8 @@ class Wiki(object):
|
||||
current.response.menu = self.menu(request.controller,
|
||||
request.function)
|
||||
zero = request.args(0)
|
||||
if zero=='_media':
|
||||
return self.media(request.args(1,cast=int))
|
||||
if zero and zero.isdigit():
|
||||
return self.media(int(zero))
|
||||
elif not zero or not zero.startswith('_'):
|
||||
return self.read(zero or 'index')
|
||||
elif zero=='_edit':
|
||||
@@ -4586,6 +4591,9 @@ class Wiki(object):
|
||||
if ps: return ps[0]
|
||||
return ''
|
||||
|
||||
def fix_hostname(self,body):
|
||||
return body.replace('://HOSTNAME','://%s' % self.host)
|
||||
|
||||
def read(self,slug):
|
||||
if slug in '_cloud':
|
||||
return self.cloud()
|
||||
@@ -4600,9 +4608,9 @@ class Wiki(object):
|
||||
else:
|
||||
match = self.regex_redirect.match(page.body)
|
||||
if match: redirect(match.group(1))
|
||||
return dict(content=XML(page.html))
|
||||
return dict(content=XML(self.fix_hostname(page.html)))
|
||||
elif current.request.extension == 'load':
|
||||
return page.html if page else ''
|
||||
return self.fix_hostname(page.html) if page else ''
|
||||
else:
|
||||
if not page:
|
||||
raise HTTP(404)
|
||||
@@ -4638,6 +4646,9 @@ class Wiki(object):
|
||||
db.wiki_page.slug.default = slug
|
||||
db.wiki_page.menu.default = slug
|
||||
db.wiki_page.body.default = '## %s\n\npage content' % title_guess
|
||||
vars = current.request.post_vars
|
||||
if vars.body:
|
||||
vars.body=vars.body.replace('://%s' % self.host,'://HOSTNAME')
|
||||
form = SQLFORM(db.wiki_page,page,deletable=True,showid=False).process()
|
||||
if form.deleted:
|
||||
current.session.flash = 'page deleted'
|
||||
@@ -4649,9 +4660,13 @@ class Wiki(object):
|
||||
|
||||
def editmedia(self,slug):
|
||||
auth = self.auth
|
||||
db = auth.db
|
||||
db = auth.db
|
||||
page = db.wiki_page(slug=slug)
|
||||
if not (page and self.can_edit(page)): return self.not_authorized(page)
|
||||
self.auth.db.wiki_media.id.represent = lambda id,row:\
|
||||
SPAN('@////%i/%s.%s' % \
|
||||
(id,IS_SLUG.urlify(row.title.split('.')[0]),
|
||||
row.file.split('.')[-1]))
|
||||
self.auth.db.wiki_media.wiki_page.default = page.id
|
||||
self.auth.db.wiki_media.wiki_page.writable = False
|
||||
content = SQLFORM.grid(
|
||||
@@ -4672,6 +4687,7 @@ class Wiki(object):
|
||||
return dict(content=form)
|
||||
def pages(self):
|
||||
if not self.can_manage(): return self.not_authorized()
|
||||
self.auth.db.wiki_page.id.represent = lambda id,row:SPAN('@////%s' % row.slug)
|
||||
self.auth.db.wiki_page.title.represent = lambda title,row: \
|
||||
A(title,_href=URL(args=row.slug))
|
||||
content=SQLFORM.grid(
|
||||
@@ -4691,7 +4707,7 @@ class Wiki(object):
|
||||
media = db.wiki_media(id)
|
||||
if media:
|
||||
if self.manage_permissions:
|
||||
page = db.wiki_page(media.page)
|
||||
page = db.wiki_page(media.wiki_page)
|
||||
if not self.can_read(page): return self.not_authorized(page)
|
||||
request.args = [media.file]
|
||||
return current.response.download(request,db)
|
||||
|
||||
@@ -213,14 +213,15 @@ class IS_EXPR(Validator):
|
||||
('2', 'invalid expression')
|
||||
"""
|
||||
|
||||
def __init__(self, expression, error_message='invalid expression'):
|
||||
def __init__(self, expression, error_message='invalid expression', environment=None):
|
||||
self.expression = expression
|
||||
self.error_message = error_message
|
||||
self.environment = environment or {}
|
||||
|
||||
def __call__(self, value):
|
||||
environment = {'value': value}
|
||||
exec '__ret__=' + self.expression in environment
|
||||
if environment['__ret__']:
|
||||
self.environment.update(value=value)
|
||||
exec '__ret__=' + self.expression in self.environment
|
||||
if self.environment['__ret__']:
|
||||
return (value, None)
|
||||
return (value, translate(self.error_message))
|
||||
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# when web2py is run as a windows service (web2py.exe -W)
|
||||
# when web2py is run as a windows service (web2py.py -W)
|
||||
# it does not load the command line options but it
|
||||
# expects to find conifguration settings in a file called
|
||||
# expects to find configuration settings in a file called
|
||||
#
|
||||
# web2py/options.py
|
||||
#
|
||||
@@ -14,13 +14,13 @@ import os
|
||||
|
||||
ip = '0.0.0.0'
|
||||
port = 80
|
||||
interfaces=[('0.0.0.0',80),('0.0.0.0',443,'ssl_private_key.pem','ssl_certificate.pem')]
|
||||
interfaces=[('0.0.0.0',80)] #,('0.0.0.0',443,'ssl_private_key.pem','ssl_certificate.pem')]
|
||||
password = '<recycle>' # ## <recycle> means use the previous password
|
||||
pid_filename = 'httpserver.pid'
|
||||
log_filename = 'httpserver.log'
|
||||
profiler_filename = None
|
||||
#ssl_certificate = 'ssl_certificate.pem' # ## path to certificate file
|
||||
#ssl_private_key = 'ssl_private_key.pem' # ## path to private key file
|
||||
ssl_certificate = None #'ssl_certificate.pem' # ## path to certificate file
|
||||
ssl_private_key = None #'ssl_private_key.pem' # ## path to private key file
|
||||
#numthreads = 50 # ## deprecated; remove
|
||||
minthreads = None
|
||||
maxthreads = None
|
||||
@@ -31,7 +31,3 @@ shutdown_timeout = 5
|
||||
folder = os.getcwd()
|
||||
extcron = None
|
||||
nocron = None
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -6,9 +6,11 @@ import sys
|
||||
|
||||
if '__file__' in globals():
|
||||
path = os.path.dirname(os.path.abspath(__file__))
|
||||
os.chdir(path)
|
||||
else:
|
||||
path = os.getcwd() # Seems necessary for py2exe
|
||||
elif hasattr(sys, 'frozen'):
|
||||
path = os.path.dirname(os.path.abspath(sys.executable)) # for py2exe
|
||||
else: #should never happen
|
||||
path = os.getcwd()
|
||||
os.chdir(path)
|
||||
|
||||
sys.path = [path]+[p for p in sys.path if not p==path]
|
||||
|
||||
|
||||
Reference in New Issue
Block a user