Merge github.com:web2py/web2py
This commit is contained in:
@@ -62,8 +62,8 @@ app:
|
||||
echo 'did you uncomment import_all in gluon/main.py?'
|
||||
python2.5 -c 'import compileall; compileall.compile_dir("gluon/")'
|
||||
#python web2py.py -S welcome -R __exit__.py
|
||||
#cd ../web2py_osx/site-packages/; unzip ../site-packages.zip
|
||||
find gluon -path '*.pyc' -exec cp {} ../web2py_osx/site-packages/{} \;
|
||||
cd ../web2py_osx/site-packages/; unzip ../site-packages.zip
|
||||
cd ../web2py_osx/site-packages/; zip -r ../site-packages.zip *
|
||||
mv ../web2py_osx/site-packages.zip ../web2py_osx/web2py/web2py.app/Contents/Resources/lib/python2.5
|
||||
cp README.markdown ../web2py_osx/web2py/web2py.app/Contents/Resources
|
||||
@@ -85,9 +85,9 @@ app:
|
||||
mv ../web2py_osx/web2py_osx.zip .
|
||||
win:
|
||||
echo 'did you uncomment import_all in gluon/main.py?'
|
||||
python2.5 -c 'import compileall; compileall.compile_dir("gluon/")'
|
||||
python2.7 -c 'import compileall; compileall.compile_dir("gluon/")'
|
||||
#cd ../web2py_win/library/; unzip ../library.zip
|
||||
find gluon -path '*.pyc' -exec cp {} ../web2py_win/library/{} \;
|
||||
cd ../web2py_win/library/; unzip ../library.zip
|
||||
cd ../web2py_win/library/; zip -r ../library.zip *
|
||||
mv ../web2py_win/library.zip ../web2py_win/web2py
|
||||
cp README.markdown ../web2py_win/web2py/
|
||||
|
||||
@@ -1 +1 @@
|
||||
Version 2.00.0 (2012-07-20 17:37:48) dev
|
||||
Version 2.00.0 (2012-07-27 09:32:24) dev
|
||||
|
||||
@@ -14,15 +14,24 @@ from gluon.fileutils import abspath, read_file, write_file
|
||||
from glob import glob
|
||||
import shutil
|
||||
import platform
|
||||
try:
|
||||
from git import *
|
||||
have_git = True
|
||||
except ImportError:
|
||||
have_git = False
|
||||
GIT_MISSING = 'requires python-git module, but not installed'
|
||||
|
||||
from gluon.languages import (regex_language, read_possible_languages,
|
||||
read_possible_plurals, lang_sampling,
|
||||
read_dict, write_dict, read_plural_dict,
|
||||
write_plural_dict)
|
||||
|
||||
if DEMO_MODE and request.function in ['change_password','pack','pack_plugin','upgrade_web2py','uninstall','cleanup','compile_app','remove_compiled_app','delete','delete_plugin','create_file','upload_file','update_languages','reload_routes']:
|
||||
|
||||
if DEMO_MODE and request.function in ['change_password','pack','pack_plugin','upgrade_web2py','uninstall','cleanup','compile_app','remove_compiled_app','delete','delete_plugin','create_file','upload_file','update_languages','reload_routes','git_push','git_pull']:
|
||||
session.flash = T('disabled in demo mode')
|
||||
redirect(URL('site'))
|
||||
|
||||
|
||||
if not is_manager() and request.function in ['change_password','upgrade_web2py']:
|
||||
session.flash = T('disabled in multi user mode')
|
||||
redirect(URL('site'))
|
||||
@@ -188,6 +197,23 @@ def site():
|
||||
msg = 'you must specify a name for the uploaded application'
|
||||
response.flash = T(msg)
|
||||
|
||||
elif (request.vars.appurl or '').endswith('.git') and request.vars.filename:
|
||||
if not have_git:
|
||||
session.flash = GIT_MISSING
|
||||
elif request.vars.filename:
|
||||
target = os.path.join(apath(r=request),request.vars.filename)
|
||||
if os.path.exists(target):
|
||||
session.flash = 'Application by that name already exists.'
|
||||
else:
|
||||
try:
|
||||
new_repo = Repo.clone_from(request.vars.appurl,target)
|
||||
session.flash = T('new application "%s" imported',request.vars.filename)
|
||||
except GitCommandError, err:
|
||||
session.flash = T('Invalid git repository specified.')
|
||||
else:
|
||||
session.flash = 'Application Name required for git import.'
|
||||
redirect(URL(r=request))
|
||||
|
||||
elif file_or_appurl and request.vars.filename:
|
||||
# fetch an application via URL or file upload
|
||||
f = None
|
||||
@@ -377,6 +403,32 @@ def delete():
|
||||
redirect(URL(sender, anchor=request.vars.id2))
|
||||
return dict(filename=filename, sender=sender)
|
||||
|
||||
def delete():
|
||||
""" Object delete handler """
|
||||
app = get_app()
|
||||
filename = '/'.join(request.args)
|
||||
sender = request.vars.sender
|
||||
|
||||
if isinstance(sender, list): # ## fix a problem with Vista
|
||||
sender = sender[0]
|
||||
|
||||
dialog = FORM.dialog(T('Delete'),
|
||||
{T('Cancel'):URL(sender, anchor=request.vars.id)})
|
||||
|
||||
if dialog.accepted:
|
||||
try:
|
||||
full_path = apath(filename, r=request)
|
||||
lineno = count_lines(open(full_path,'r').read())
|
||||
os.unlink(full_path)
|
||||
log_progress(app,'DELETE',filename,progress=-lineno)
|
||||
session.flash = T('file "%(filename)s" deleted',
|
||||
dict(filename=filename))
|
||||
except Exception:
|
||||
session.flash = T('unable to delete file "%(filename)s"',
|
||||
dict(filename=filename))
|
||||
redirect(URL(sender, anchor=request.vars.id2))
|
||||
return dict(dialog=dialog,filename=filename)
|
||||
|
||||
def enable():
|
||||
app = get_app()
|
||||
filename = os.path.join(apath(app, r=request),'DISABLED')
|
||||
@@ -854,6 +906,11 @@ def design():
|
||||
modules = modules=[x.replace('\\','/') for x in modules]
|
||||
modules.sort()
|
||||
|
||||
# Get all private files
|
||||
privates = listdir(apath('%s/private/' % app, r=request), '[^\.#].*')
|
||||
privates = [x.replace('\\','/') for x in privates]
|
||||
privates.sort()
|
||||
|
||||
# Get all static files
|
||||
statics = listdir(apath('%s/static/' % app, r=request), '[^\.#].*')
|
||||
statics = [x.replace('\\','/') for x in statics]
|
||||
@@ -908,6 +965,7 @@ def design():
|
||||
modules=filter_plugins(modules,plugins),
|
||||
extend=extend,
|
||||
include=include,
|
||||
privates=filter_plugins(privates,plugins),
|
||||
statics=filter_plugins(statics,plugins),
|
||||
languages=languages,
|
||||
plurals=plurals,
|
||||
@@ -924,7 +982,7 @@ def delete_plugin():
|
||||
redirect(URL('design', args=app, anchor=request.vars.id))
|
||||
elif 'delete' in request.vars:
|
||||
try:
|
||||
for folder in ['models','views','controllers','static','modules']:
|
||||
for folder in ['models','views','controllers','static','modules', 'private']:
|
||||
path=os.path.join(apath(app,r=request),folder)
|
||||
for item in os.listdir(path):
|
||||
if item.rsplit('.',1)[0] == plugin_name:
|
||||
@@ -994,6 +1052,11 @@ def plugin():
|
||||
modules = modules=[x.replace('\\','/') for x in modules]
|
||||
modules.sort()
|
||||
|
||||
# Get all private files
|
||||
privates = listdir(apath('%s/private/' % app, r=request), '[^\.#].*')
|
||||
privates = [x.replace('\\','/') for x in privates]
|
||||
privates.sort()
|
||||
|
||||
# Get all static files
|
||||
statics = listdir(apath('%s/static/' % app, r=request), '[^\.#].*')
|
||||
statics = [x.replace('\\','/') for x in statics]
|
||||
@@ -1023,6 +1086,7 @@ def plugin():
|
||||
modules=filter_plugins(modules),
|
||||
extend=extend,
|
||||
include=include,
|
||||
privates=filter_plugins(privates),
|
||||
statics=filter_plugins(statics),
|
||||
languages=languages,
|
||||
crontab=crontab)
|
||||
@@ -1142,10 +1206,11 @@ def create_file():
|
||||
# coding: utf8
|
||||
from gluon import *\n""")[1:]
|
||||
|
||||
elif path[-8:] == '/static/':
|
||||
elif (path[-8:] == '/static/') or (path[-9:] == '/private/'):
|
||||
if request.vars.plugin and not filename.startswith('plugin_%s/' % request.vars.plugin):
|
||||
filename = 'plugin_%s/%s' % (request.vars.plugin, filename)
|
||||
text = ''
|
||||
|
||||
else:
|
||||
redirect(request.vars.sender+anchor)
|
||||
|
||||
@@ -1545,3 +1610,76 @@ def bulk_register():
|
||||
redirect(URL('site'))
|
||||
return locals()
|
||||
|
||||
### Begin experimental stuff need fixes:
|
||||
# 1) should run in its own process - cannot os.chdir
|
||||
# 2) should not prompt user at console
|
||||
# 3) should give option to force commit and not reuqire manual merge
|
||||
|
||||
def git_pull():
|
||||
""" Git Pull handler """
|
||||
app = get_app()
|
||||
if not have_git:
|
||||
session.flash = GIT_MISSING
|
||||
redirect(URL('site'))
|
||||
if 'pull' in request.vars:
|
||||
try:
|
||||
repo = Repo(os.path.join(apath(r=request),app))
|
||||
origin = repo.remotes.origin
|
||||
origin.fetch()
|
||||
origin.pull()
|
||||
session.flash = T("Application updated via git pull")
|
||||
redirect(URL('site'))
|
||||
except CheckoutError, message:
|
||||
logging.error(message)
|
||||
session.flash = T("Pull failed, certain files could not be checked out. Check logs for details.")
|
||||
redirect(URL('site'))
|
||||
except UnmergedEntriesError:
|
||||
session.flash = T("Pull is not possible because you have unmerged files. Fix them up in the work tree, and then try again.")
|
||||
redirect(URL('site'))
|
||||
except AssertionError:
|
||||
session.flash = T("Pull is not possible because you have unmerged files. Fix them up in the work tree, and then try again.")
|
||||
redirect(URL('site'))
|
||||
except GitCommandError, status:
|
||||
logging.error(str(status))
|
||||
session.flash = T("Pull failed, git exited abnormally. See logs for details.")
|
||||
redirect(URL('site'))
|
||||
except Exception,e:
|
||||
logging.error("Unexpected error:", sys.exc_info()[0])
|
||||
session.flash = T("Pull failed, git exited abnormally. See logs for details.")
|
||||
redirect(URL('site'))
|
||||
elif 'cancel' in request.vars:
|
||||
redirect(URL('site'))
|
||||
return dict(app=app)
|
||||
|
||||
|
||||
def git_push():
|
||||
""" Git Push handler """
|
||||
app = get_app()
|
||||
if not have_git:
|
||||
session.flash = GIT_MISSING
|
||||
redirect(URL('site'))
|
||||
form = SQLFORM.factory(Field('changelog',requires=IS_NOT_EMPTY()))
|
||||
form.element('input[type=submit]')['_value']=T('Push')
|
||||
form.add_button(T('Cancel'),URL('site'))
|
||||
form.process()
|
||||
if form.accepted:
|
||||
try:
|
||||
repo = Repo(os.path.join(apath(r=request),app))
|
||||
index = repo.index
|
||||
os.chdir(os.path.join(apath(r=request),app))
|
||||
index.add('*')
|
||||
new_commit = index.commit(form.vars.changelog)
|
||||
origin = repo.remotes.origin
|
||||
origin.push()
|
||||
session.flash = T("Git repo updated with latest application changes.")
|
||||
redirect(URL('site'))
|
||||
except UnmergedEntriesError:
|
||||
session.flash = T("Push failed, there are unmerged entries in the cache. Resolve merge issues manually and try again.")
|
||||
redirect(URL('site'))
|
||||
except Exception, e:
|
||||
logging.error("Unexpected error:", sys.exc_info()[0])
|
||||
session.flash = T("Push failed, git exited abnormally. See logs for details.")
|
||||
redirect(URL('site'))
|
||||
os.chdir(apath(r=request))
|
||||
return dict(app=app,form=form)
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@ def deploy():
|
||||
assert repo.bare == False
|
||||
|
||||
for i in form.vars.applications:
|
||||
appsrc = os.path.join(os.getcwd(),'applications',i)
|
||||
appsrc = os.path.join(apath(r=request),i)
|
||||
appdest = os.path.join(osrepo,'wsgi',osname,'applications',i)
|
||||
dir_util.copy_tree(appsrc,appdest)
|
||||
#shutil.copytree(appsrc,appdest)
|
||||
|
||||
@@ -4,6 +4,6 @@
|
||||
|
||||
<div class="center">
|
||||
<h2>{{=T('Are you sure you want to delete file "%s"?', filename)}}</h2>
|
||||
<p>{{=FORM(INPUT(_type='submit',_name='nodelete',_value=T('Abort')),INPUT(_type='hidden',_name='sender',_value=sender), _class="inline")}}{{=FORM(INPUT(_type='submit',_name='delete',_value=T('Delete')),INPUT(_type='hidden',_name='sender',_value=sender), _class="inline")}}</p>
|
||||
<p>{{=dialog}}</p>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -57,6 +57,7 @@ def deletefile(arglist, vars={}):
|
||||
{{=button('#languages', T("languages"))}}
|
||||
{{=button('#static', T("static"))}}
|
||||
{{=button('#modules', T("modules"))}}
|
||||
{{=button('#private', T("private files"))}}
|
||||
{{=button('#plugins', T("plugins"))}}
|
||||
</span>
|
||||
</p>
|
||||
@@ -318,6 +319,57 @@ for c in controllers: controller_functions+=[c[:-3]+'/%s.html'%x for x in functi
|
||||
{{=file_upload_form('%s/modules/' % app, 'modules')}}</div>
|
||||
</div>
|
||||
|
||||
<!-- PRIVATE -->
|
||||
|
||||
<h3 id="private" onclick="collapse('private_inner');" class="component">
|
||||
{{=T("Private files")}}
|
||||
<span class="tooltip">{{=helpicon()}} <span>{{=T("These files are not served, they are only available from within your app")}}</span></span>
|
||||
</h3>
|
||||
<div id="private_inner" class="component_contents">
|
||||
<div class="controls comptools">
|
||||
</div>
|
||||
{{if not privates:}}<p><strong>{{=T("There are no private files")}}</strong></p>{{pass}}
|
||||
<ul>
|
||||
{{
|
||||
path=[]
|
||||
for file in privates+['']:
|
||||
items=file.split('/')
|
||||
file_path=items[:-1]
|
||||
filename=items[-1]
|
||||
while path!=file_path:
|
||||
if len(file_path)>=len(path) and all([v==file_path[k] for k,v in enumerate(path)]):
|
||||
path.append(file_path[len(path)])
|
||||
thispath='private__'+'__'.join(path)
|
||||
}}
|
||||
<li class="folder">
|
||||
<a href="javascript:collapse('{{=thispath}}');" class="file">{{=path[-1]}}/</a>
|
||||
<ul id="{{=thispath}}" style="display: none;" class="sublist">{{
|
||||
else:
|
||||
path = path[:-1]
|
||||
}}
|
||||
</ul></li>
|
||||
{{
|
||||
pass
|
||||
pass
|
||||
if filename:
|
||||
}}<li>
|
||||
<span class="filetools controls">
|
||||
{{=editfile('private',file, dict(id="private"))}} {{=deletefile([app,'private',file], dict(id="private",id2="private"))}}
|
||||
</span>
|
||||
<span class="file">
|
||||
{{=filename}}
|
||||
</span>
|
||||
</li>{{
|
||||
pass
|
||||
pass
|
||||
}}
|
||||
{{pass}}
|
||||
</ul>
|
||||
<div class="controls formfield">{{=file_create_form('%s/private/' % app, 'private')}}
|
||||
{{=file_upload_form('%s/private/' % app, 'private')}}</div>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- PLUGINS -->
|
||||
|
||||
<h3 id="plugins" onclick="collapse('plugins_inner');" class="component">
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
{{extend 'layout.html'}}
|
||||
|
||||
<center>
|
||||
<h2>{{=T('This will pull changes from the remote repo for application "%s"?', app)}}</h2>
|
||||
<table><tr>
|
||||
<td>{{=FORM(INPUT(_type='submit',_name='cancel',_value=T('Cancel')))}}</td>
|
||||
<td>{{=FORM(INPUT(_type='submit',_name='pull',_value=T('Pull')))}}</td>
|
||||
</tr></table>
|
||||
</center>
|
||||
@@ -0,0 +1,6 @@
|
||||
{{extend 'layout.html'}}
|
||||
|
||||
<h2>{{=T('This will push changes to the remote repo for application "%s".', app)}}</h2>
|
||||
<center>
|
||||
{{=form}}
|
||||
</center>
|
||||
@@ -34,6 +34,10 @@
|
||||
{{=button(URL('remove_compiled_app',args=a), T("Remove compiled"))}}
|
||||
{{pass}}
|
||||
{{pass}}
|
||||
{{if os.path.exists(os.path.join(apath(r=request),a,'.git')): }}
|
||||
{{=button(URL('git_pull',args=a), T("Git Pull"))}}
|
||||
{{=button(URL('git_push',args=a), T("Git Push"))}}
|
||||
{{pass}}
|
||||
{{if a!=request.application:}}
|
||||
{{=button(URL('uninstall',args=a), T("Uninstall"))}}
|
||||
{{=button_enable(URL('enable',args=a), a)}}
|
||||
@@ -117,16 +121,18 @@
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
{{=LABEL(T("Get from URL:"), _for='upload_url')}}
|
||||
{{=LABEL(T("Get from URL:"), _for='upload_url')}}
|
||||
</td>
|
||||
<td>
|
||||
<input id="appurl" name="appurl" type="text" id="upload_url"/>
|
||||
<input id="appurl" name="appurl" type="text" id="upload_url"/><br/>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td></td>
|
||||
<td>
|
||||
<input type="checkbox" name="overwrite_check" id="upload_overwrite" />
|
||||
<td>
|
||||
({{=T('can be a git repo')}})
|
||||
</td>
|
||||
<td>
|
||||
<input type="checkbox" name="overwrite_check" id="upload_overwrite" />
|
||||
{{=LABEL(T("Overwrite installed app"), _for='upload_overwrite')}}
|
||||
</td>
|
||||
</tr>
|
||||
@@ -142,13 +148,11 @@
|
||||
</div>
|
||||
<!-- DEPLOY ON GAE -->
|
||||
<div class="box">
|
||||
<h3>{{=T("Deploy on Google App Engine")}}</h3>
|
||||
<p>{{=button(URL('gae','deploy'), T('Deploy'))}}</p>
|
||||
</div><br/>
|
||||
<!-- DEPLOY ON OPENSHIFT -->
|
||||
<div class="box">
|
||||
<h3>{{=T("Deploy to OpenShift")}}</h3>
|
||||
<p>{{=button(URL('openshift','deploy'),T('Deploy'))}}</p>
|
||||
<h3>{{=T("Deploy")}}</h3>
|
||||
<p>
|
||||
{{=button(URL('gae','deploy'), T('Deploy on Google App Engine'))}}
|
||||
{{=button(URL('openshift','deploy'),T('Deploy to OpenShift'))}}
|
||||
</p>
|
||||
</div><br/>
|
||||
{{if TWITTER_HASH:}}
|
||||
<div class="box">
|
||||
|
||||
@@ -3,14 +3,18 @@
|
||||
'!langcode!': 'it',
|
||||
'!langname!': 'Italiano',
|
||||
'"update" is an optional expression like "field1=\'newvalue\'". You cannot update or delete the results of a JOIN': '"update" è un\'espressione opzionale come "campo1=\'nuovo valore\'". Non si può fare "update" o "delete" dei risultati di un JOIN ',
|
||||
'%Y-%m-%d': '%d/%m/%Y',
|
||||
'%Y-%m-%d %H:%M:%S': '%d/%m/%Y %H:%M:%S',
|
||||
'%d seconds ago': '%d seconds ago',
|
||||
'%s %%{row} deleted': '%s righe ("record") cancellate',
|
||||
'%s %%{row} updated': '%s righe ("record") modificate',
|
||||
'%s selected': '%s selezionato',
|
||||
'%Y-%m-%d': '%d/%m/%Y',
|
||||
'%Y-%m-%d %H:%M:%S': '%d/%m/%Y %H:%M:%S',
|
||||
'Administrative interface': 'Interfaccia amministrativa',
|
||||
'appadmin is disabled because insecure channel': 'Amministrazione (appadmin) disabilitata: comunicazione non sicura',
|
||||
'Available databases and tables': 'Database e tabelle disponibili',
|
||||
'cache': 'cache',
|
||||
'Cannot be empty': 'Non può essere vuoto',
|
||||
'change password': 'Cambia password',
|
||||
'Check to delete': 'Seleziona per cancellare',
|
||||
'Client IP': 'Client IP',
|
||||
'Controller': 'Controller',
|
||||
@@ -18,50 +22,79 @@
|
||||
'Current request': 'Richiesta (request) corrente',
|
||||
'Current response': 'Risposta (response) corrente',
|
||||
'Current session': 'Sessione (session) corrente',
|
||||
'DB Model': 'Modello di DB',
|
||||
'customize me!': 'Personalizzami!',
|
||||
'data uploaded': 'dati caricati',
|
||||
'Database': 'Database',
|
||||
'database': 'database',
|
||||
'database %s select': 'database %s select',
|
||||
'db': 'db',
|
||||
'DB Model': 'Modello di DB',
|
||||
'Delete': 'Delete',
|
||||
'Delete:': 'Cancella:',
|
||||
'Description': 'Descrizione',
|
||||
'design': 'progetta',
|
||||
'Documentation': 'Documentazione',
|
||||
'done!': 'fatto!',
|
||||
'E-mail': 'E-mail',
|
||||
'Edit': 'Modifica',
|
||||
'Edit This App': 'Modifica questa applicazione',
|
||||
'Edit current record': 'Modifica record corrente',
|
||||
'edit profile': 'modifica profilo',
|
||||
'Edit This App': 'Modifica questa applicazione',
|
||||
'export as csv file': 'esporta come file CSV',
|
||||
'First name': 'Nome',
|
||||
'Group ID': 'ID Gruppo',
|
||||
'hello': 'hello',
|
||||
'hello world': 'salve mondo',
|
||||
'Hello World': 'Salve Mondo',
|
||||
'Hello World in a flash!': 'Salve Mondo in un flash!',
|
||||
'Import/Export': 'Importa/Esporta',
|
||||
'Index': 'Indice',
|
||||
'insert new': 'inserisci nuovo',
|
||||
'insert new %s': 'inserisci nuovo %s',
|
||||
'Internal State': 'Stato interno',
|
||||
'Invalid Query': 'Richiesta (query) non valida',
|
||||
'Invalid email': 'Email non valida',
|
||||
'Invalid Query': 'Richiesta (query) non valida',
|
||||
'invalid request': 'richiesta non valida',
|
||||
'Last name': 'Cognome',
|
||||
'Layout': 'Layout',
|
||||
'login': 'accesso',
|
||||
'logout': 'uscita',
|
||||
'lost password?': 'dimenticato la password?',
|
||||
'Main Menu': 'Menu principale',
|
||||
'Menu Model': 'Menu Modelli',
|
||||
'Name': 'Nome',
|
||||
'New Record': 'Nuovo elemento (record)',
|
||||
'new record inserted': 'nuovo record inserito',
|
||||
'next 100 rows': 'prossime 100 righe',
|
||||
'No databases in this application': 'Nessun database presente in questa applicazione',
|
||||
'not authorized': 'non autorizzato',
|
||||
'Online examples': 'Vedere gli esempi',
|
||||
'or import from csv file': 'oppure importa da file CSV',
|
||||
'Origin': 'Origine',
|
||||
'Password': 'Password',
|
||||
'Powered by': 'Powered by',
|
||||
'previous 100 rows': '100 righe precedenti',
|
||||
'Query:': 'Richiesta (query):',
|
||||
'record': 'record',
|
||||
'record does not exist': 'il record non esiste',
|
||||
'record id': 'record id',
|
||||
'Record ID': 'Record ID',
|
||||
'register': 'registrazione',
|
||||
'Registration key': 'Chiave di Registazione',
|
||||
'Reset Password key': 'Resetta chiave Password ',
|
||||
'Role': 'Ruolo',
|
||||
'Rows in table': 'Righe nella tabella',
|
||||
'Rows selected': 'Righe selezionate',
|
||||
'state': 'stato',
|
||||
'Stylesheet': 'Foglio di stile (stylesheet)',
|
||||
'Sure you want to delete this object?': 'Vuoi veramente cancellare questo oggetto?',
|
||||
'table': 'tabella',
|
||||
'Table name': 'Nome tabella',
|
||||
'The "query" is a condition like "db.table1.field1==\'value\'". Something like "db.table1.field1==db.table2.field2" results in a SQL JOIN.': 'La richiesta (query) è una condizione come ad esempio "db.tabella1.campo1==\'valore\'". Una condizione come "db.tabella1.campo1==db.tabella2.campo2" produce un "JOIN" SQL.',
|
||||
'The output of the file is a dictionary that was rendered by the view %s': 'L\'output del file è un "dictionary" che è stato visualizzato dalla vista %s',
|
||||
'This is a copy of the scaffolding application': "Questa è una copia dell'applicazione di base (scaffold)",
|
||||
'Timestamp': 'Ora (timestamp)',
|
||||
'unable to parse csv file': 'non riesco a decodificare questo file CSV',
|
||||
'Update': 'Update',
|
||||
'Update:': 'Aggiorna:',
|
||||
'Use (...)&(...) for AND, (...)|(...) for OR, and ~(...) for NOT to build more complex queries.': 'Per costruire richieste (query) più complesse si usano (...)&(...) come "e" (AND), (...)|(...) come "o" (OR), e ~(...) come negazione (NOT).',
|
||||
@@ -73,36 +106,4 @@
|
||||
'You are successfully running web2py': 'Stai eseguendo web2py con successo',
|
||||
'You can modify this application and adapt it to your needs': 'Puoi modificare questa applicazione adattandola alle tue necessità',
|
||||
'You visited the url %s': "Hai visitato l'URL %s",
|
||||
'appadmin is disabled because insecure channel': 'Amministrazione (appadmin) disabilitata: comunicazione non sicura',
|
||||
'cache': 'cache',
|
||||
'change password': 'Cambia password',
|
||||
'customize me!': 'Personalizzami!',
|
||||
'data uploaded': 'dati caricati',
|
||||
'database': 'database',
|
||||
'database %s select': 'database %s select',
|
||||
'db': 'db',
|
||||
'design': 'progetta',
|
||||
'done!': 'fatto!',
|
||||
'edit profile': 'modifica profilo',
|
||||
'export as csv file': 'esporta come file CSV',
|
||||
'hello': 'hello',
|
||||
'hello world': 'salve mondo',
|
||||
'insert new': 'inserisci nuovo',
|
||||
'insert new %s': 'inserisci nuovo %s',
|
||||
'invalid request': 'richiesta non valida',
|
||||
'login': 'accesso',
|
||||
'logout': 'uscita',
|
||||
'lost password?': 'dimenticato la password?',
|
||||
'new record inserted': 'nuovo record inserito',
|
||||
'next 100 rows': 'prossime 100 righe',
|
||||
'not authorized': 'non autorizzato',
|
||||
'or import from csv file': 'oppure importa da file CSV',
|
||||
'previous 100 rows': '100 righe precedenti',
|
||||
'record': 'record',
|
||||
'record does not exist': 'il record non esiste',
|
||||
'record id': 'record id',
|
||||
'register': 'registrazione',
|
||||
'state': 'stato',
|
||||
'table': 'tabella',
|
||||
'unable to parse csv file': 'non riesco a decodificare questo file CSV',
|
||||
}
|
||||
|
||||
@@ -5,12 +5,16 @@
|
||||
'!langname!': 'Română',
|
||||
'"update" is an optional expression like "field1=\'newvalue\'". You cannot update or delete the results of a JOIN': '"update" (actualizează) este o expresie opțională precum "câmp1=\'valoare_nouă\'". Nu puteți actualiza sau șterge rezultatele unui JOIN',
|
||||
'%(nrows)s records found': '%(nrows)s înregistrări găsite',
|
||||
'%Y-%m-%d': '%Y-%m-%d',
|
||||
'%Y-%m-%d %H:%M:%S': '%Y-%m-%d %H:%M:%S',
|
||||
'%d days ago': '%d days ago',
|
||||
'%d weeks ago': '%d weeks ago',
|
||||
'%s %%{row} deleted': '%s linii șterse',
|
||||
'%s %%{row} updated': '%s linii actualizate',
|
||||
'%s selected': '%s selectat(e)',
|
||||
'%Y-%m-%d': '%Y-%m-%d',
|
||||
'%Y-%m-%d %H:%M:%S': '%Y-%m-%d %H:%M:%S',
|
||||
'(something like "it-it")': '(ceva ce seamănă cu "it-it")',
|
||||
'1 day ago': '1 day ago',
|
||||
'1 week ago': '1 week ago',
|
||||
'<': '<',
|
||||
'<=': '<=',
|
||||
'=': '=',
|
||||
@@ -18,13 +22,15 @@
|
||||
'>=': '>=',
|
||||
'A new version of web2py is available': 'O nouă versiune de web2py este disponibilă',
|
||||
'A new version of web2py is available: %s': 'O nouă versiune de web2py este disponibilă: %s',
|
||||
'ATTENTION: Login requires a secure (HTTPS) connection or running on localhost.': 'ATENȚIE: Nu vă puteți conecta decât utilizând o conexiune securizată (HTTPS) sau rulând aplicația pe computerul local.',
|
||||
'ATTENTION: TESTING IS NOT THREAD SAFE SO DO NOT PERFORM MULTIPLE TESTS CONCURRENTLY.': 'ATENȚIE: Nu puteți efectua mai multe teste o dată deoarece lansarea în execuție a mai multor subpocese nu este sigură.',
|
||||
'ATTENTION: you cannot edit the running application!': 'ATENȚIE: nu puteți edita o aplicație în curs de execuție!',
|
||||
'About': 'Despre',
|
||||
'about': 'despre',
|
||||
'About application': 'Despre aplicație',
|
||||
'Access Control': 'Control acces',
|
||||
'Add': 'Adaugă',
|
||||
'additional code for your application': 'cod suplimentar pentru aplicația dvs.',
|
||||
'admin disabled because no admin password': 'administrare dezactivată deoarece parola de administrator nu a fost furnizată',
|
||||
'admin disabled because not supported on google app engine': 'administrare dezactivată deoarece funcționalitatea nu e suportat pe Google App Engine',
|
||||
'admin disabled because unable to access password file': 'administrare dezactivată deoarece nu există acces la fișierul cu parole',
|
||||
'Admin is disabled because insecure channel': 'Adminstrarea este dezactivată deoarece conexiunea nu este sigură',
|
||||
'Admin is disabled because unsecure channel': 'Administrarea este dezactivată deoarece conexiunea nu este securizată',
|
||||
'Administration': 'Administrare',
|
||||
@@ -32,62 +38,118 @@
|
||||
'Administrator Password:': 'Parolă administrator:',
|
||||
'Ajax Recipes': 'Rețete Ajax',
|
||||
'And': 'Și',
|
||||
'and rename it (required):': 'și renumiți (obligatoriu):',
|
||||
'and rename it:': ' și renumiți:',
|
||||
'appadmin': 'appadmin',
|
||||
'appadmin is disabled because insecure channel': 'appadmin dezactivat deoarece conexiunea nu e sigură',
|
||||
'application "%s" uninstalled': 'aplicația "%s" a fost dezinstalată',
|
||||
'application compiled': 'aplicația a fost compilată',
|
||||
'application is compiled and cannot be designed': 'aplicația este compilată și nu poate fi editată',
|
||||
'Are you sure you want to delete file "%s"?': 'Sigur ștergeți fișierul "%s"?',
|
||||
'Are you sure you want to delete this object?': 'Sigur ștergeți acest obiect?',
|
||||
'Are you sure you want to uninstall application "%s"': 'Sigur dezinstalați aplicația "%s"',
|
||||
'Are you sure you want to uninstall application "%s"?': 'Sigur dezinstalați aplicația "%s"?',
|
||||
'ATTENTION: Login requires a secure (HTTPS) connection or running on localhost.': 'ATENȚIE: Nu vă puteți conecta decât utilizând o conexiune securizată (HTTPS) sau rulând aplicația pe computerul local.',
|
||||
'ATTENTION: TESTING IS NOT THREAD SAFE SO DO NOT PERFORM MULTIPLE TESTS CONCURRENTLY.': 'ATENȚIE: Nu puteți efectua mai multe teste o dată deoarece lansarea în execuție a mai multor subpocese nu este sigură.',
|
||||
'ATTENTION: you cannot edit the running application!': 'ATENȚIE: nu puteți edita o aplicație în curs de execuție!',
|
||||
'Authentication': 'Autentificare',
|
||||
'Available databases and tables': 'Baze de date și tabele disponibile',
|
||||
'Back': 'Înapoi',
|
||||
'Buy this book': 'Cumpără această carte',
|
||||
'cache': 'cache',
|
||||
'Cache Keys': 'Chei cache',
|
||||
'cache, errors and sessions cleaned': 'cache, erori și sesiuni golite',
|
||||
'Cannot be empty': 'Nu poate fi vid',
|
||||
'Cannot compile: there are errors in your app. Debug it, correct errors and try again.': 'Compilare imposibilă: aplicația conține erori. Debogați aplicația și încercați din nou.',
|
||||
'cannot create file': 'fișier imposibil de creat',
|
||||
'cannot upload file "%(filename)s"': 'imposibil de încărcat fișierul "%(filename)s"',
|
||||
'Change Password': 'Schimbare parolă',
|
||||
'Change password': 'Schimbare parolă',
|
||||
'change password': 'schimbare parolă',
|
||||
'check all': 'coșați tot',
|
||||
'Check to delete': 'Coșați pentru a șterge',
|
||||
'clean': 'golire',
|
||||
'Clear': 'Golește',
|
||||
'click to check for upgrades': 'Clic pentru a verifica dacă există upgrade-uri',
|
||||
'Client IP': 'IP client',
|
||||
'Community': 'Comunitate',
|
||||
'compile': 'compilare',
|
||||
'compiled application removed': 'aplicația compilată a fost ștearsă',
|
||||
'Components and Plugins': 'Componente și plugin-uri',
|
||||
'contains': 'conține',
|
||||
'Controller': 'Controlor',
|
||||
'Controllers': 'Controlori',
|
||||
'controllers': 'controlori',
|
||||
'Copyright': 'Drepturi de autor',
|
||||
'create file with filename:': 'crează fișier cu numele:',
|
||||
'Create new application': 'Creați aplicație nouă',
|
||||
'create new application:': 'crează aplicație nouă:',
|
||||
'crontab': 'crontab',
|
||||
'Current request': 'Cerere curentă',
|
||||
'Current response': 'Răspuns curent',
|
||||
'Current session': 'Sesiune curentă',
|
||||
'DB Model': 'Model bază de date',
|
||||
'DESIGN': 'DESIGN',
|
||||
'currently saved or': 'în prezent salvat sau',
|
||||
'customize me!': 'Personalizează-mă!',
|
||||
'data uploaded': 'date încărcate',
|
||||
'Database': 'Baza de date',
|
||||
'database': 'bază de date',
|
||||
'database %s select': 'selectare bază de date %s',
|
||||
'database administration': 'administrare bază de date',
|
||||
'Date and Time': 'Data și ora',
|
||||
'db': 'db',
|
||||
'DB Model': 'Model bază de date',
|
||||
'defines tables': 'definire tabele',
|
||||
'Delete': 'Șterge',
|
||||
'delete': 'șterge',
|
||||
'delete all checked': 'șterge tot ce e coșat',
|
||||
'Delete:': 'Șterge:',
|
||||
'Demo': 'Demo',
|
||||
'Deploy on Google App Engine': 'Instalare pe Google App Engine',
|
||||
'Deployment Recipes': 'Rețete de instalare',
|
||||
'Description': 'Descriere',
|
||||
'design': 'design',
|
||||
'DESIGN': 'DESIGN',
|
||||
'Design for': 'Design pentru',
|
||||
'Disk Cache Keys': 'Chei cache de disc',
|
||||
'Documentation': 'Documentație',
|
||||
"Don't know what to do?": 'Nu știți ce să faceți?',
|
||||
'done!': 'gata!',
|
||||
'Download': 'Descărcare',
|
||||
'E-mail': 'E-mail',
|
||||
'E-mail invalid': 'E-mail invalid',
|
||||
'edit': 'editare',
|
||||
'EDIT': 'EDITARE',
|
||||
'Edit': 'Editare',
|
||||
'Edit Profile': 'Editare profil',
|
||||
'Edit This App': 'Editați această aplicație',
|
||||
'Edit application': 'Editare aplicație',
|
||||
'edit controller': 'editare controlor',
|
||||
'Edit current record': 'Editare înregistrare curentă',
|
||||
'Edit Profile': 'Editare profil',
|
||||
'edit profile': 'editare profil',
|
||||
'Edit This App': 'Editați această aplicație',
|
||||
'Editing file': 'Editare fișier',
|
||||
'Editing file "%s"': 'Editare fișier "%s"',
|
||||
'Email and SMS': 'E-mail și SMS',
|
||||
'enter a number between %(min)g and %(max)g': 'introduceți un număr între %(min)g și %(max)g',
|
||||
'enter an integer between %(min)g and %(max)g': 'introduceți un întreg între %(min)g și %(max)g',
|
||||
'Error logs for "%(app)s"': 'Log erori pentru "%(app)s"',
|
||||
'errors': 'erori',
|
||||
'Errors': 'Erori',
|
||||
'Export': 'Export',
|
||||
'FAQ': 'Întrebări frecvente',
|
||||
'export as csv file': 'exportă ca fișier csv',
|
||||
'exposes': 'expune',
|
||||
'extends': 'extinde',
|
||||
'failed to reload module': 'reîncarcare modul nereușită',
|
||||
'False': 'Neadevărat',
|
||||
'FAQ': 'Întrebări frecvente',
|
||||
'file "%(filename)s" created': 'fișier "%(filename)s" creat',
|
||||
'file "%(filename)s" deleted': 'fișier "%(filename)s" șters',
|
||||
'file "%(filename)s" uploaded': 'fișier "%(filename)s" încărcat',
|
||||
'file "%(filename)s" was not deleted': 'fișierul "%(filename)s" n-a fost șters',
|
||||
'file "%s" of %s restored': 'fișier "%s" de %s restaurat',
|
||||
'file changed on disk': 'fișier modificat pe disc',
|
||||
'file does not exist': 'fișier inexistent',
|
||||
'file saved on %(time)s': 'fișier salvat %(time)s',
|
||||
'file saved on %s': 'fișier salvat pe %s',
|
||||
'First name': 'Prenume',
|
||||
'Forbidden': 'Interzis',
|
||||
'Forms and Validators': 'Formulare și validatori',
|
||||
@@ -98,19 +160,31 @@
|
||||
'Group uniquely assigned to user %(id)s': 'Grup asociat în mod unic utilizatorului %(id)s',
|
||||
'Groups': 'Grupuri',
|
||||
'Hello World': 'Salutare lume',
|
||||
'help': 'ajutor',
|
||||
'Home': 'Acasă',
|
||||
'How did you get here?': 'Cum ați ajuns aici?',
|
||||
'htmledit': 'editare html',
|
||||
'Import/Export': 'Import/Export',
|
||||
'includes': 'include',
|
||||
'Index': 'Index',
|
||||
'insert new': 'adaugă nou',
|
||||
'insert new %s': 'adaugă nou %s',
|
||||
'Installed applications': 'Aplicații instalate',
|
||||
'internal error': 'eroare internă',
|
||||
'Internal State': 'Stare internă',
|
||||
'Introduction': 'Introducere',
|
||||
'Invalid Query': 'Interogare invalidă',
|
||||
'Invalid action': 'Acțiune invalidă',
|
||||
'Invalid email': 'E-mail invalid',
|
||||
'invalid password': 'parolă invalidă',
|
||||
'Invalid password': 'Parolă invalidă',
|
||||
'Invalid Query': 'Interogare invalidă',
|
||||
'invalid request': 'cerere invalidă',
|
||||
'invalid ticket': 'tichet invalid',
|
||||
'language file "%(filename)s" created/updated': 'fișier de limbă "%(filename)s" creat/actualizat',
|
||||
'Language files (static strings) updated': 'Fișierele de limbă (șirurile statice de caractere) actualizate',
|
||||
'languages': 'limbi',
|
||||
'Languages': 'Limbi',
|
||||
'languages updated': 'limbi actualizate',
|
||||
'Last name': 'Nume',
|
||||
'Last saved on:': 'Ultima salvare:',
|
||||
'Layout': 'Șablon',
|
||||
@@ -118,39 +192,54 @@
|
||||
'Layouts': 'Șabloane',
|
||||
'License for': 'Licență pentru',
|
||||
'Live Chat': 'Chat live',
|
||||
'loading...': 'încarc...',
|
||||
'Logged in': 'Logat',
|
||||
'Logged out': 'Delogat',
|
||||
'Login': 'Autentificare',
|
||||
'login': 'autentificare',
|
||||
'Login to the Administrative Interface': 'Logare interfață de administrare',
|
||||
'logout': 'ieșire',
|
||||
'Logout': 'Ieșire',
|
||||
'Lost Password': 'Parolă pierdută',
|
||||
'Lost password?': 'Parolă pierdută?',
|
||||
'Main Menu': 'Meniu principal',
|
||||
'Menu Model': 'Model meniu',
|
||||
'merge': 'unește',
|
||||
'Models': 'Modele',
|
||||
'models': 'modele',
|
||||
'Modules': 'Module',
|
||||
'modules': 'module',
|
||||
'My Sites': 'Site-urile mele',
|
||||
'NO': 'NU',
|
||||
'Name': 'Nume',
|
||||
'New': 'Nou',
|
||||
'New Record': 'Înregistrare nouă',
|
||||
'new application "%s" created': 'aplicația nouă "%s" a fost creată',
|
||||
'New password': 'Parola nouă',
|
||||
'New Record': 'Înregistrare nouă',
|
||||
'new record inserted': 'înregistrare nouă adăugată',
|
||||
'next 100 rows': 'următoarele 100 de linii',
|
||||
'NO': 'NU',
|
||||
'No databases in this application': 'Aplicație fără bază de date',
|
||||
'Object or table name': 'Obiect sau nume de tabel',
|
||||
'Old password': 'Parola veche',
|
||||
'Online examples': 'Exemple online',
|
||||
'Or': 'Sau',
|
||||
'or import from csv file': 'sau importă din fișier csv',
|
||||
'or provide application url:': 'sau furnizează adresă url:',
|
||||
'Origin': 'Origine',
|
||||
'Original/Translation': 'Original/Traducere',
|
||||
'Other Plugins': 'Alte plugin-uri',
|
||||
'Other Recipes': 'Alte rețete',
|
||||
'Overview': 'Prezentare de ansamblu',
|
||||
'pack all': 'împachetează toate',
|
||||
'pack compiled': 'pachet compilat',
|
||||
'Password': 'Parola',
|
||||
"Password fields don't match": 'Câmpurile de parolă nu se potrivesc',
|
||||
'Peeking at file': 'Vizualizare fișier',
|
||||
'please input your password again': 'introduceți parola din nou',
|
||||
'Plugins': 'Plugin-uri',
|
||||
'Powered by': 'Pus în mișcare de',
|
||||
'Preface': 'Prefață',
|
||||
'previous 100 rows': '100 de linii anterioare',
|
||||
'Profile': 'Profil',
|
||||
'Python': 'Python',
|
||||
'Query': 'Interogare',
|
||||
@@ -158,52 +247,88 @@
|
||||
'Quick Examples': 'Exemple rapide',
|
||||
'RAM Cache Keys': 'Chei cache RAM',
|
||||
'Recipes': 'Rețete',
|
||||
'record': 'înregistrare',
|
||||
'record does not exist': 'înregistrare inexistentă',
|
||||
'record id': 'id înregistrare',
|
||||
'Record ID': 'ID înregistrare',
|
||||
'register': 'înregistrare',
|
||||
'Register': 'Înregistrare',
|
||||
'Registration identifier': 'Identificator de autentificare',
|
||||
'Registration key': 'Cheie înregistrare',
|
||||
'Registration successful': 'Autentificare reușită',
|
||||
'Remember me (for 30 days)': 'Ține-mă minte (timp de 30 de zile)',
|
||||
'remove compiled': 'șterge compilate',
|
||||
'Request reset password': 'Cerere resetare parolă',
|
||||
'Reset Password key': 'Cheie restare parolă',
|
||||
'Resolve Conflict file': 'Fișier rezolvare conflict',
|
||||
'restore': 'restaurare',
|
||||
'revert': 'revenire',
|
||||
'Role': 'Rol',
|
||||
'Rows in table': 'Linii în tabel',
|
||||
'Rows selected': 'Linii selectate',
|
||||
'save': 'salvare',
|
||||
'Save profile': 'Salvează profil',
|
||||
'Saved file hash:': 'Hash fișier salvat:',
|
||||
'Search': 'Căutare',
|
||||
'Semantic': 'Semantică',
|
||||
'Services': 'Servicii',
|
||||
'session expired': 'sesiune expirată',
|
||||
'shell': 'line de commandă',
|
||||
'site': 'site',
|
||||
'some files could not be removed': 'anumite fișiere n-au putut fi șterse',
|
||||
'starts with': 'începe cu',
|
||||
'state': 'stare',
|
||||
'static': 'static',
|
||||
'Static files': 'Fișiere statice',
|
||||
'Stylesheet': 'Foaie de stiluri',
|
||||
'Submit': 'Înregistrează',
|
||||
'Support': 'Suport',
|
||||
'Sure you want to delete this object?': 'Sigur ștergeți acest obiect?',
|
||||
'table': 'tabel',
|
||||
'Table name': 'Nume tabel',
|
||||
'test': 'test',
|
||||
'Testing application': 'Testare aplicație',
|
||||
'The "query" is a condition like "db.table1.field1==\'value\'". Something like "db.table1.field1==db.table2.field2" results in a SQL JOIN.': '"Interogarea (query)" este o condiție de tipul "db.tabel1.câmp1==\'valoare\'". Ceva de genul "db.tabel1.câmp1==db.tabel2.câmp2" generează un JOIN SQL.',
|
||||
'the application logic, each URL path is mapped in one exposed function in the controller': 'logica aplicației, fiecare rută URL este mapată într-o funcție expusă de controlor',
|
||||
'The Core': 'Nucleul',
|
||||
'The Views': 'Vederile',
|
||||
'the data representation, define database tables and sets': 'reprezentarea datelor, definește tabelele bazei de date și seturile (de date)',
|
||||
'The output of the file is a dictionary that was rendered by the view %s': 'Fișierul produce un dicționar care a fost prelucrat de vederea %s',
|
||||
'the presentations layer, views are also known as templates': 'nivelul de prezentare, vederile sunt de asemenea numite și șabloane',
|
||||
'The Views': 'Vederile',
|
||||
'There are no controllers': 'Nu există controlori',
|
||||
'There are no models': 'Nu există modele',
|
||||
'There are no modules': 'Nu există module',
|
||||
'There are no static files': 'Nu există fișiere statice',
|
||||
'There are no translators, only default language is supported': 'Nu există traduceri, doar limba implicită este suportată',
|
||||
'There are no views': 'Nu există vederi',
|
||||
'these files are served without processing, your images go here': 'aceste fișiere sunt servite fără procesare, imaginea se plasează acolo',
|
||||
'This App': 'Această aplicație',
|
||||
'This is a copy of the scaffolding application': 'Aceasta este o copie a aplicației schelet',
|
||||
'This is the %(filename)s template': 'Aceasta este șablonul fișierului %(filename)s',
|
||||
'Ticket': 'Tichet',
|
||||
'Timestamp': 'Moment în timp (timestamp)',
|
||||
'to previous version.': 'la versiunea anterioară.',
|
||||
'too short': 'prea scurt',
|
||||
'translation strings for the application': 'șiruri de caractere folosite la traducerea aplicației',
|
||||
'True': 'Adevărat',
|
||||
'try': 'încearcă',
|
||||
'try something like': 'încearcă ceva de genul',
|
||||
'Twitter': 'Twitter',
|
||||
'Unable to check for upgrades': 'Imposibil de verificat dacă există actualizări',
|
||||
'unable to create application "%s"': 'imposibil de creat aplicația "%s"',
|
||||
'unable to delete file "%(filename)s"': 'imposibil de șters fișierul "%(filename)s"',
|
||||
'Unable to download': 'Imposibil de descărcat',
|
||||
'Unable to download app': 'Imposibil de descărcat aplicația',
|
||||
'unable to parse csv file': 'imposibil de analizat fișierul csv',
|
||||
'unable to uninstall "%s"': 'imposibil de dezinstalat "%s"',
|
||||
'uncheck all': 'decoșează tot',
|
||||
'uninstall': 'dezinstalează',
|
||||
'update': 'actualizează',
|
||||
'update all languages': 'actualizează toate limbile',
|
||||
'Update:': 'Actualizare:',
|
||||
'upload application:': 'incarcă aplicația:',
|
||||
'Upload existing application': 'Încarcă aplicația existentă',
|
||||
'upload file:': 'încarcă fișier:',
|
||||
'Use (...)&(...) for AND, (...)|(...) for OR, and ~(...) for NOT to build more complex queries.': 'Folosiți (...)&(...) pentru AND, (...)|(...) pentru OR, și ~(...) pentru NOT, pentru a crea interogări complexe.',
|
||||
'User %(id)s Logged-in': 'Utilizator %(id)s autentificat',
|
||||
'User %(id)s Logged-out': 'Utilizator %(id)s delogat',
|
||||
@@ -212,10 +337,16 @@
|
||||
'User %(id)s Profile updated': 'Profil utilizator %(id)s actualizat',
|
||||
'User %(id)s Registered': 'Utilizator %(id)s înregistrat',
|
||||
'User ID': 'ID utilizator',
|
||||
'value already in database or empty': 'Valoare existentă în baza de date sau vidă',
|
||||
'Verify Password': 'Verifică parola',
|
||||
'versioning': 'versiuni',
|
||||
'Videos': 'Video-uri',
|
||||
'View': 'Vedere',
|
||||
'view': 'vedere',
|
||||
'Views': 'Vederi',
|
||||
'views': 'vederi',
|
||||
'web2py is up to date': 'web2py este la zi',
|
||||
'web2py Recent Tweets': 'Ultimele tweet-uri web2py',
|
||||
'Welcome': 'Bine ați venit',
|
||||
'Welcome %s': 'Bine ați venit %s',
|
||||
'Welcome to web2py': 'Bun venit la web2py',
|
||||
@@ -225,131 +356,4 @@
|
||||
'You are successfully running web2py': 'Rulați cu succes web2py',
|
||||
'You can modify this application and adapt it to your needs': 'Puteți modifica și adapta aplicația nevoilor dvs.',
|
||||
'You visited the url %s': 'Ați vizitat adresa %s',
|
||||
'about': 'despre',
|
||||
'additional code for your application': 'cod suplimentar pentru aplicația dvs.',
|
||||
'admin disabled because no admin password': 'administrare dezactivată deoarece parola de administrator nu a fost furnizată',
|
||||
'admin disabled because not supported on google app engine': 'administrare dezactivată deoarece funcționalitatea nu e suportat pe Google App Engine',
|
||||
'admin disabled because unable to access password file': 'administrare dezactivată deoarece nu există acces la fișierul cu parole',
|
||||
'and rename it (required):': 'și renumiți (obligatoriu):',
|
||||
'and rename it:': ' și renumiți:',
|
||||
'appadmin': 'appadmin',
|
||||
'appadmin is disabled because insecure channel': 'appadmin dezactivat deoarece conexiunea nu e sigură',
|
||||
'application "%s" uninstalled': 'aplicația "%s" a fost dezinstalată',
|
||||
'application compiled': 'aplicația a fost compilată',
|
||||
'application is compiled and cannot be designed': 'aplicația este compilată și nu poate fi editată',
|
||||
'cache': 'cache',
|
||||
'cache, errors and sessions cleaned': 'cache, erori și sesiuni golite',
|
||||
'cannot create file': 'fișier imposibil de creat',
|
||||
'cannot upload file "%(filename)s"': 'imposibil de încărcat fișierul "%(filename)s"',
|
||||
'change password': 'schimbare parolă',
|
||||
'check all': 'coșați tot',
|
||||
'clean': 'golire',
|
||||
'click to check for upgrades': 'Clic pentru a verifica dacă există upgrade-uri',
|
||||
'compile': 'compilare',
|
||||
'compiled application removed': 'aplicația compilată a fost ștearsă',
|
||||
'contains': 'conține',
|
||||
'controllers': 'controlori',
|
||||
'create file with filename:': 'crează fișier cu numele:',
|
||||
'create new application:': 'crează aplicație nouă:',
|
||||
'crontab': 'crontab',
|
||||
'currently saved or': 'în prezent salvat sau',
|
||||
'customize me!': 'Personalizează-mă!',
|
||||
'data uploaded': 'date încărcate',
|
||||
'database': 'bază de date',
|
||||
'database %s select': 'selectare bază de date %s',
|
||||
'database administration': 'administrare bază de date',
|
||||
'db': 'db',
|
||||
'defines tables': 'definire tabele',
|
||||
'delete': 'șterge',
|
||||
'delete all checked': 'șterge tot ce e coșat',
|
||||
'design': 'design',
|
||||
'done!': 'gata!',
|
||||
'edit': 'editare',
|
||||
'edit controller': 'editare controlor',
|
||||
'edit profile': 'editare profil',
|
||||
'enter a number between %(min)g and %(max)g': 'introduceți un număr între %(min)g și %(max)g',
|
||||
'enter an integer between %(min)g and %(max)g': 'introduceți un întreg între %(min)g și %(max)g',
|
||||
'errors': 'erori',
|
||||
'export as csv file': 'exportă ca fișier csv',
|
||||
'exposes': 'expune',
|
||||
'extends': 'extinde',
|
||||
'failed to reload module': 'reîncarcare modul nereușită',
|
||||
'file "%(filename)s" created': 'fișier "%(filename)s" creat',
|
||||
'file "%(filename)s" deleted': 'fișier "%(filename)s" șters',
|
||||
'file "%(filename)s" uploaded': 'fișier "%(filename)s" încărcat',
|
||||
'file "%(filename)s" was not deleted': 'fișierul "%(filename)s" n-a fost șters',
|
||||
'file "%s" of %s restored': 'fișier "%s" de %s restaurat',
|
||||
'file changed on disk': 'fișier modificat pe disc',
|
||||
'file does not exist': 'fișier inexistent',
|
||||
'file saved on %(time)s': 'fișier salvat %(time)s',
|
||||
'file saved on %s': 'fișier salvat pe %s',
|
||||
'help': 'ajutor',
|
||||
'htmledit': 'editare html',
|
||||
'includes': 'include',
|
||||
'insert new': 'adaugă nou',
|
||||
'insert new %s': 'adaugă nou %s',
|
||||
'internal error': 'eroare internă',
|
||||
'invalid password': 'parolă invalidă',
|
||||
'invalid request': 'cerere invalidă',
|
||||
'invalid ticket': 'tichet invalid',
|
||||
'language file "%(filename)s" created/updated': 'fișier de limbă "%(filename)s" creat/actualizat',
|
||||
'languages': 'limbi',
|
||||
'languages updated': 'limbi actualizate',
|
||||
'loading...': 'încarc...',
|
||||
'login': 'autentificare',
|
||||
'logout': 'ieșire',
|
||||
'merge': 'unește',
|
||||
'models': 'modele',
|
||||
'modules': 'module',
|
||||
'new application "%s" created': 'aplicația nouă "%s" a fost creată',
|
||||
'new record inserted': 'înregistrare nouă adăugată',
|
||||
'next 100 rows': 'următoarele 100 de linii',
|
||||
'or import from csv file': 'sau importă din fișier csv',
|
||||
'or provide application url:': 'sau furnizează adresă url:',
|
||||
'pack all': 'împachetează toate',
|
||||
'pack compiled': 'pachet compilat',
|
||||
'please input your password again': 'introduceți parola din nou',
|
||||
'previous 100 rows': '100 de linii anterioare',
|
||||
'record': 'înregistrare',
|
||||
'record does not exist': 'înregistrare inexistentă',
|
||||
'record id': 'id înregistrare',
|
||||
'register': 'înregistrare',
|
||||
'remove compiled': 'șterge compilate',
|
||||
'restore': 'restaurare',
|
||||
'revert': 'revenire',
|
||||
'save': 'salvare',
|
||||
'session expired': 'sesiune expirată',
|
||||
'shell': 'line de commandă',
|
||||
'site': 'site',
|
||||
'some files could not be removed': 'anumite fișiere n-au putut fi șterse',
|
||||
'starts with': 'începe cu',
|
||||
'state': 'stare',
|
||||
'static': 'static',
|
||||
'table': 'tabel',
|
||||
'test': 'test',
|
||||
'the application logic, each URL path is mapped in one exposed function in the controller': 'logica aplicației, fiecare rută URL este mapată într-o funcție expusă de controlor',
|
||||
'the data representation, define database tables and sets': 'reprezentarea datelor, definește tabelele bazei de date și seturile (de date)',
|
||||
'the presentations layer, views are also known as templates': 'nivelul de prezentare, vederile sunt de asemenea numite și șabloane',
|
||||
'these files are served without processing, your images go here': 'aceste fișiere sunt servite fără procesare, imaginea se plasează acolo',
|
||||
'to previous version.': 'la versiunea anterioară.',
|
||||
'too short': 'prea scurt',
|
||||
'translation strings for the application': 'șiruri de caractere folosite la traducerea aplicației',
|
||||
'try': 'încearcă',
|
||||
'try something like': 'încearcă ceva de genul',
|
||||
'unable to create application "%s"': 'imposibil de creat aplicația "%s"',
|
||||
'unable to delete file "%(filename)s"': 'imposibil de șters fișierul "%(filename)s"',
|
||||
'unable to parse csv file': 'imposibil de analizat fișierul csv',
|
||||
'unable to uninstall "%s"': 'imposibil de dezinstalat "%s"',
|
||||
'uncheck all': 'decoșează tot',
|
||||
'uninstall': 'dezinstalează',
|
||||
'update': 'actualizează',
|
||||
'update all languages': 'actualizează toate limbile',
|
||||
'upload application:': 'incarcă aplicația:',
|
||||
'upload file:': 'încarcă fișier:',
|
||||
'value already in database or empty': 'Valoare existentă în baza de date sau vidă',
|
||||
'versioning': 'versiuni',
|
||||
'view': 'vedere',
|
||||
'views': 'vederi',
|
||||
'web2py Recent Tweets': 'Ultimele tweet-uri web2py',
|
||||
'web2py is up to date': 'web2py este la zi',
|
||||
}
|
||||
|
||||
+9
-2
@@ -35,7 +35,7 @@ except ImportError:
|
||||
|
||||
logger = logging.getLogger("web2py.cache")
|
||||
|
||||
__all__ = ['Cache', 'lazy_lazy_cache']
|
||||
__all__ = ['Cache', 'lazy_cache']
|
||||
|
||||
|
||||
DEFAULT_TIME_EXPIRE = 300
|
||||
@@ -478,7 +478,14 @@ class Cache(object):
|
||||
return CacheAction(func,key,time_expire,self,cache_model)
|
||||
return tmp
|
||||
|
||||
def lazy_lazy_cache(key=None,time_expire=None,cache_model='ram'):
|
||||
def lazy_cache(key=None,time_expire=None,cache_model='ram'):
|
||||
"""
|
||||
can be used to cache any function including in modules,
|
||||
as long as the cached function is only called within a web2py request
|
||||
if a key is not provided, one is generated from the function name
|
||||
the time_expire defaults to None (no cache expiration)
|
||||
if cache_model is "ram" then the model is current.cache.ram, etc.
|
||||
"""
|
||||
def decorator(f,key=key,time_expire=time_expire,cache_model=cache_model):
|
||||
key = key or repr(f)
|
||||
def g(*c,**d):
|
||||
|
||||
+4
-1
@@ -33,7 +33,10 @@ def getcfs(key, filename, filter=None):
|
||||
|
||||
This is used on Google App Engine since pyc files cannot be saved.
|
||||
"""
|
||||
t = os.stat(filename).st_mtime
|
||||
try:
|
||||
t = os.stat(filename).st_mtime
|
||||
except OSError:
|
||||
return filter()
|
||||
cfs_lock.acquire()
|
||||
item = cfs.get(key, None)
|
||||
cfs_lock.release()
|
||||
|
||||
@@ -855,9 +855,9 @@ class Sheet:
|
||||
|
||||
sorted_headers = [TH(),] + \
|
||||
[TH(header[1]) for header in sorted(unsorted_headers)]
|
||||
table.insert(0, TR(*sorted_headers, _class="%s_fieldnames" % \
|
||||
attributes["_class"]))
|
||||
|
||||
table.insert(0, TR(*sorted_headers,
|
||||
**{_class:"%s_fieldnames" % \
|
||||
attributes["_class"]}))
|
||||
else:
|
||||
data = SCRIPT(""" // web2py Spreadsheets: no db data.""")
|
||||
|
||||
|
||||
@@ -3785,6 +3785,9 @@ class GoogleSQLAdapter(UseDatabaseStoredFile,MySQLAdapter):
|
||||
self.execute("SET FOREIGN_KEY_CHECKS=1;")
|
||||
self.execute("SET sql_mode='NO_BACKSLASH_ESCAPES';")
|
||||
|
||||
def execute(self,a):
|
||||
return self.log_execute(a.decode('utf8'))
|
||||
|
||||
class NoSQLAdapter(BaseAdapter):
|
||||
can_select_for_update = False
|
||||
|
||||
@@ -7109,6 +7112,9 @@ class Table(dict):
|
||||
"primarykey must be a list of fields from table '%s'" \
|
||||
% tablename
|
||||
self._primarykey = primarykey
|
||||
if len(primarykey)==1:
|
||||
self._id = [f for f in fields if isinstance(f,Field) \
|
||||
and f.name==primarykey[0]][0]
|
||||
elif not [f for f in fields if isinstance(f,Field) and f.type=='id']:
|
||||
field = Field('id', 'id')
|
||||
newfields.append(field)
|
||||
|
||||
+33
-2
@@ -472,7 +472,18 @@ class XmlComponent(object):
|
||||
|
||||
def xml(self):
|
||||
raise NotImplementedError
|
||||
|
||||
def __mul__(self,n):
|
||||
return CAT(*[self for i in range(n)])
|
||||
def __add__(self,other):
|
||||
if isinstance(self,CAT):
|
||||
components = self.components
|
||||
else:
|
||||
components = [self]
|
||||
if isinstance(other,CAT):
|
||||
components += other.components
|
||||
else:
|
||||
components += [other]
|
||||
return CAT(*components)
|
||||
|
||||
class XML(XmlComponent):
|
||||
"""
|
||||
@@ -2023,8 +2034,28 @@ class FORM(DIV):
|
||||
self.validate(**kwargs)
|
||||
return self
|
||||
|
||||
REDIRECT_JS = "window.location='%s';return false"
|
||||
|
||||
def add_button(self,value,url,_class=None):
|
||||
self[0][-1][1].append(INPUT(_type="button",_value=value,_onclick="window.location='%s';return false" % url,_class=_class))
|
||||
self[0][-1][1].append(INPUT(_type="button",_value=value,_class=_class,
|
||||
_onclick=self.REDIRECT_JS % url))
|
||||
|
||||
|
||||
@staticmethod
|
||||
def dialog(text='OK',buttons=None,hidden=None):
|
||||
if not buttons: buttons = {}
|
||||
if not hidden: hidden={}
|
||||
inputs = [INPUT(_type='button',
|
||||
_value=name,
|
||||
_onclick=FORM.REDIRECT_JS % link) \
|
||||
for name,link in buttons.items()]
|
||||
inputs += [INPUT(_type='hidden',
|
||||
_name=name,
|
||||
_value=value)
|
||||
for name,value in hidden.items()]
|
||||
form = FORM(INPUT(_type='submit',_value=text),*inputs)
|
||||
form.process()
|
||||
return form
|
||||
|
||||
class BEAUTIFY(DIV):
|
||||
|
||||
|
||||
@@ -87,6 +87,7 @@ from settings import global_settings
|
||||
from validators import CRYPT
|
||||
from cache import Cache
|
||||
from html import URL as Url
|
||||
from utils import is_valid_ip_address
|
||||
import newcron
|
||||
import rewrite
|
||||
|
||||
@@ -402,6 +403,8 @@ def wsgibase(environ, responder):
|
||||
try: local_hosts.append(socket.gethostbyname(http_host))
|
||||
except socket.gaierror: pass
|
||||
request.client = get_client(request.env)
|
||||
if not is_valid_ip_address(request.client):
|
||||
raise HTTP(400,"Bad Request")
|
||||
request.folder = abspath('applications',
|
||||
request.application) + os.sep
|
||||
x_req_with = str(request.env.http_x_requested_with).lower()
|
||||
|
||||
+7
-4
@@ -410,8 +410,11 @@ class CheckboxesWidget(OptionsWidget):
|
||||
LABEL(v,_for='%s%s' % (field.name,k))))
|
||||
opts.append(child(tds))
|
||||
|
||||
|
||||
if opts:
|
||||
opts[-1][0][0]['hideerror'] = False
|
||||
opts.append(INPUT(_class="hidden", requires=attr.get('requires', None),
|
||||
_disabled="disabled", _name=field.name,
|
||||
hideerror=False))
|
||||
return parent(*opts, **attr)
|
||||
|
||||
|
||||
@@ -1173,8 +1176,7 @@ class SQLFORM(FORM):
|
||||
row_id = '%s_%s%s' % (self.table, fieldname, SQLFORM.ID_ROW_SUFFIX)
|
||||
widget = field.widget(field, value)
|
||||
self.field_parent[row_id].components = [ widget ]
|
||||
if not field.type.startswith('list:'):
|
||||
self.field_parent[row_id]._traverse(False, hideerror)
|
||||
self.field_parent[row_id]._traverse(False, hideerror)
|
||||
self.custom.widget[ fieldname ] = widget
|
||||
self.accepted = ret
|
||||
return ret
|
||||
@@ -1241,7 +1243,8 @@ class SQLFORM(FORM):
|
||||
### do not know why this happens, it should not
|
||||
(source_file, original_filename) = \
|
||||
(cStringIO.StringIO(f), 'file.txt')
|
||||
newfilename = field.store(source_file, original_filename, field.uploadfolder)
|
||||
newfilename = field.store(source_file, original_filename,
|
||||
field.uploadfolder)
|
||||
# this line is for backward compatibility only
|
||||
self.vars['%s_newfilename' % fieldname] = newfilename
|
||||
fields[fieldname] = newfilename
|
||||
|
||||
+11
-4
@@ -881,7 +881,8 @@ class Auth(object):
|
||||
return URL(args=current.request.args,vars=current.request.vars)
|
||||
|
||||
def __init__(self, environment=None, db=None, mailer=True,
|
||||
hmac_key=None, controller='default', function='user', cas_provider=None):
|
||||
hmac_key=None, controller='default', function='user',
|
||||
cas_provider=None, signature=True):
|
||||
"""
|
||||
auth=Auth(db)
|
||||
|
||||
@@ -1133,7 +1134,10 @@ class Auth(object):
|
||||
# when user wants to be logged in for longer
|
||||
response.cookies[response.session_id_name]["expires"] = \
|
||||
auth.expiration
|
||||
|
||||
if signature:
|
||||
self.define_signature()
|
||||
else:
|
||||
self.signature = None
|
||||
|
||||
def _get_user_id(self):
|
||||
"accessor for auth.user_id"
|
||||
@@ -1332,7 +1336,8 @@ class Auth(object):
|
||||
|
||||
db = self.db
|
||||
settings = self.settings
|
||||
self.define_signature()
|
||||
if not self.signature:
|
||||
self.define_signature()
|
||||
if signature==True:
|
||||
signature_list = [self.signature]
|
||||
elif not signature:
|
||||
@@ -1622,7 +1627,7 @@ class Auth(object):
|
||||
userfield = 'email'
|
||||
passfield = self.settings.password_field
|
||||
user = self.db(table_user[userfield] == username).select().first()
|
||||
if user:
|
||||
if user and user.get(passfield,False):
|
||||
password = table_user[passfield].validate(password)[0]
|
||||
if not user.registration_key and password == user[passfield]:
|
||||
user = Storage(table_user._filter_fields(user, id=True))
|
||||
@@ -3392,6 +3397,8 @@ class Crud(object):
|
||||
query = table.id > 0
|
||||
if not fields:
|
||||
fields = [field for field in table if field.readable]
|
||||
else:
|
||||
fields = [table[f] if isinstance(f,str) else f for f in fields]
|
||||
rows = self.db(query).select(*fields,**dict(orderby=orderby,
|
||||
limitby=limitby))
|
||||
return rows
|
||||
|
||||
+21
-1
@@ -16,6 +16,7 @@ import random
|
||||
import time
|
||||
import os
|
||||
import logging
|
||||
import socket
|
||||
from contrib.pbkdf2 import pbkdf2_hex
|
||||
|
||||
logger = logging.getLogger("web2py")
|
||||
@@ -69,7 +70,7 @@ def get_digest(value):
|
||||
elif value == "sha512":
|
||||
return hashlib.sha512
|
||||
else:
|
||||
raise ValueError("Invalid digest algorithm: %s" % value)
|
||||
raise ValueError("Invalid digest algorithm: %s" % value)
|
||||
|
||||
DIGEST_ALG_BY_SIZE = {
|
||||
128/4: 'md5',
|
||||
@@ -146,6 +147,25 @@ def web2py_uuid():
|
||||
bytes = ''.join(chr(c ^ ctokens[i]) for i,c in enumerate(bytes))
|
||||
return str(uuid.UUID(bytes=bytes, version=4))
|
||||
|
||||
def is_valid_ip_address(address):
|
||||
"""
|
||||
>>> is_valid_ip_address('127.0')
|
||||
False
|
||||
>>> is_valid_ip_address('127.0.0.1')
|
||||
True
|
||||
>>> is_valid_ip_address('2001:660::1')
|
||||
True
|
||||
"""
|
||||
try:
|
||||
if address.count('.')==3:
|
||||
addr = socket.inet_aton(address)
|
||||
else:
|
||||
addr = socket.inet_pton(socket.AF_INET6, address)
|
||||
except AttributeError: # no socket.inet_pton
|
||||
return False
|
||||
except socket.error:
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
|
||||
|
||||
+30
-13
@@ -220,44 +220,54 @@ class web2pyDialog(object):
|
||||
justify=Tkinter.LEFT).grid(row=0,
|
||||
column=0,
|
||||
sticky=sticky)
|
||||
self.ip = Tkinter.Entry(self.root)
|
||||
self.ip.insert(Tkinter.END, self.options.ip)
|
||||
self.ip.grid(row=0, column=1, sticky=sticky)
|
||||
|
||||
self.ips = {}
|
||||
self.selected_ip = Tkinter.StringVar()
|
||||
row=0
|
||||
ips = [('127.0.0.1','Local')] + \
|
||||
[(ip,'Public') for ip in options.ips] + \
|
||||
[('0.0.0.0','Public')]
|
||||
for ip,legend in ips:
|
||||
self.ips[ip] = Tkinter.Radiobutton(
|
||||
self.root,text='%s (%s)' % (legend,ip),
|
||||
variable=self.selected_ip, value=ip)
|
||||
self.ips[ip].grid(row=row, column=1, sticky=sticky)
|
||||
if row==0: self.ips[ip].select()
|
||||
row+=1
|
||||
shift = row
|
||||
# Port
|
||||
Tkinter.Label(self.root,
|
||||
text='Server Port:',
|
||||
justify=Tkinter.LEFT).grid(row=1,
|
||||
justify=Tkinter.LEFT).grid(row=shift,
|
||||
column=0,
|
||||
sticky=sticky)
|
||||
|
||||
self.port_number = Tkinter.Entry(self.root)
|
||||
self.port_number.insert(Tkinter.END, self.options.port)
|
||||
self.port_number.grid(row=1, column=1, sticky=sticky)
|
||||
self.port_number.grid(row=shift, column=1, sticky=sticky)
|
||||
|
||||
# Password
|
||||
Tkinter.Label(self.root,
|
||||
text='Choose Password:',
|
||||
justify=Tkinter.LEFT).grid(row=2,
|
||||
justify=Tkinter.LEFT).grid(row=shift+1,
|
||||
column=0,
|
||||
sticky=sticky)
|
||||
|
||||
self.password = Tkinter.Entry(self.root, show='*')
|
||||
self.password.bind('<Return>', lambda e: self.start())
|
||||
self.password.focus_force()
|
||||
self.password.grid(row=2, column=1, sticky=sticky)
|
||||
self.password.grid(row=shift+1, column=1, sticky=sticky)
|
||||
|
||||
# Prepare the canvas
|
||||
self.canvas = Tkinter.Canvas(self.root,
|
||||
width=300,
|
||||
height=100,
|
||||
bg='black')
|
||||
self.canvas.grid(row=3, column=0, columnspan=2)
|
||||
self.canvas.grid(row=shift+2, column=0, columnspan=2)
|
||||
self.canvas.after(1000, self.update_canvas)
|
||||
|
||||
# Prepare the frame
|
||||
frame = Tkinter.Frame(self.root)
|
||||
frame.grid(row=4, column=0, columnspan=2)
|
||||
frame.grid(row=shift+3, column=0, columnspan=2)
|
||||
|
||||
# Start button
|
||||
self.button_start = Tkinter.Button(frame,
|
||||
@@ -359,7 +369,7 @@ class web2pyDialog(object):
|
||||
if not password:
|
||||
self.error('no password, no web admin interface')
|
||||
|
||||
ip = self.ip.get()
|
||||
ip = self.selected_ip.get()
|
||||
|
||||
regexp = '\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}'
|
||||
if ip and not re.compile(regexp).match(ip):
|
||||
@@ -416,7 +426,7 @@ class web2pyDialog(object):
|
||||
thread.start_new_thread(start_browser, (proto, ip, port))
|
||||
|
||||
self.password.configure(state='readonly')
|
||||
self.ip.configure(state='readonly')
|
||||
[ip.configure(state='disabled') for ip in self.ips.values()]
|
||||
self.port_number.configure(state='readonly')
|
||||
|
||||
if self.tb:
|
||||
@@ -435,7 +445,7 @@ class web2pyDialog(object):
|
||||
self.button_start.configure(state='normal')
|
||||
self.button_stop.configure(state='disabled')
|
||||
self.password.configure(state='normal')
|
||||
self.ip.configure(state='normal')
|
||||
[ip.configure(state='normal') for ip in self.ips.values()]
|
||||
self.port_number.configure(state='normal')
|
||||
self.server.stop()
|
||||
|
||||
@@ -790,6 +800,13 @@ def console():
|
||||
global_settings.cmd_options = options
|
||||
global_settings.cmd_args = args
|
||||
|
||||
try:
|
||||
options.ips = [
|
||||
ip for ip in socket.gethostbyname_ex(socket.getfqdn())[2]
|
||||
if ip!='127.0.0.1']
|
||||
except socket.gaierror:
|
||||
options.ips = []
|
||||
|
||||
if options.run_system_tests:
|
||||
run_system_tests()
|
||||
|
||||
|
||||
+9
-4
@@ -90,8 +90,12 @@ class Web2pyService(Service):
|
||||
cls = _winreg.QueryValue(h, 'PythonClass')
|
||||
finally:
|
||||
_winreg.CloseKey(h)
|
||||
dir = os.path.dirname(cls)
|
||||
dir = os.path.dirname(cls)
|
||||
os.chdir(dir)
|
||||
from gluon.settings import global_settings
|
||||
global_settings.gluon_parent = dir
|
||||
from gluon.custom_import import custom_import_install
|
||||
custom_import_install(dir)
|
||||
return True
|
||||
except:
|
||||
self.log("Can't change to web2py working path; server is stopped")
|
||||
@@ -149,8 +153,10 @@ class Web2pyService(Service):
|
||||
|
||||
def web2py_windows_service_handler(argv=None, opt_file='options'):
|
||||
path = os.path.dirname(__file__)
|
||||
classstring = os.path.normpath(os.path.join(up(path),
|
||||
'gluon.winservice.Web2pyService'))
|
||||
web2py_path = up(path)
|
||||
os.chdir(web2py_path)
|
||||
classstring = os.path.normpath(
|
||||
os.path.join(web2py_path,'gluon.winservice.Web2pyService'))
|
||||
if opt_file:
|
||||
Web2pyService._exe_args_ = opt_file
|
||||
win32serviceutil.HandleCommandLine(Web2pyService,
|
||||
@@ -158,7 +164,6 @@ def web2py_windows_service_handler(argv=None, opt_file='options'):
|
||||
win32serviceutil.HandleCommandLine(Web2pyService,
|
||||
serviceClassString=classstring, argv=argv)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
web2py_windows_service_handler()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user