some cleanup and better use of die() function, thanks paolo

This commit is contained in:
mdipierro
2019-04-09 21:49:04 -07:00
parent 59700b8d06
commit b96c54cef9
5 changed files with 96 additions and 87 deletions

View File

@@ -1,5 +1,5 @@
## 2.18.1-2.18.5 ## 2.18.1-2.18.5
- pydal 19.02 - pydal 19.04
- made template its own module (Yet Another Template Language) - made template its own module (Yet Another Template Language)
- improved python 3.4-3.7 support - improved python 3.4-3.7 support
- better regular expressions - better regular expressions

View File

@@ -193,6 +193,13 @@ def exec_pythonrc():
return dict() return dict()
def die(msg, exit_status=1, error_preamble=True):
if error_preamble:
msg = "%s: error: %s" % (sys.argv[0], msg)
print(msg, file=sys.stderr)
sys.exit(exit_status)
def run( def run(
appname, appname,
plain=False, plain=False,
@@ -212,7 +219,7 @@ def run(
(a, c, f, args, vars) = parse_path_info(appname, av=True) (a, c, f, args, vars) = parse_path_info(appname, av=True)
errmsg = 'invalid application name: %s' % appname errmsg = 'invalid application name: %s' % appname
if not a: if not a:
die(errmsg) die(errmsg, error_preamble=False)
adir = os.path.join('applications', a) adir = os.path.join('applications', a)
if not os.path.exists(adir): if not os.path.exists(adir):
@@ -258,7 +265,7 @@ def run(
elif os.path.isfile(pyfile): elif os.path.isfile(pyfile):
execfile(pyfile, _env) execfile(pyfile, _env)
else: else:
die(errmsg) die(errmsg, error_preamble=False)
if f: if f:
exec('print( %s())' % f, _env) exec('print( %s())' % f, _env)
@@ -358,11 +365,6 @@ def parse_path_info(path_info, av=False):
return (None, None, None) return (None, None, None)
def die(msg):
print(msg, file=sys.stderr)
sys.exit(1)
def test(testpath, import_models=True, verbose=False): def test(testpath, import_models=True, verbose=False):
""" """
Run doctests in web2py environment. testpath is formatted like: Run doctests in web2py environment. testpath is formatted like:

View File

@@ -24,12 +24,9 @@ from gluon import main, newcron
from gluon.fileutils import read_file, write_file, create_welcome_w2p from gluon.fileutils import read_file, write_file, create_welcome_w2p
from gluon.settings import global_settings from gluon.settings import global_settings
from gluon.shell import run, test from gluon.shell import die, run, test
from gluon.utils import is_valid_ip_address, is_loopback_ip_address, getipaddrinfo from gluon.utils import is_valid_ip_address, is_loopback_ip_address, getipaddrinfo
if PY2:
input = raw_input
ProgramName = 'web2py Web Framework' ProgramName = 'web2py Web Framework'
ProgramAuthor = 'Created by Massimo Di Pierro, Copyright 2007-' + str( ProgramAuthor = 'Created by Massimo Di Pierro, Copyright 2007-' + str(
@@ -63,8 +60,7 @@ def run_system_tests(options):
try: try:
import coverage import coverage
except: except:
sys.stderr.write('Coverage was not installed\n') die('Coverage not installed')
sys.exit(1)
if not PY2: if not PY2:
sys.stderr.write('Experimental ') sys.stderr.write('Experimental ')
sys.stderr.write("Python %s\n" % sys.version) sys.stderr.write("Python %s\n" % sys.version)
@@ -342,7 +338,7 @@ class web2pyDialog(object):
try: try:
from multiprocessing import Process from multiprocessing import Process
except: except:
sys.stderr.write('Sorry, -K only supported for python 2.6-2.7\n') sys.stderr.write('Sorry, -K only supported for Python 2.6+\n')
return return
code = "from gluon.globals import current;current._scheduler.loop()" code = "from gluon.globals import current;current._scheduler.loop()"
print('starting scheduler from widget for "%s"...' % app) print('starting scheduler from widget for "%s"...' % app)
@@ -597,14 +593,15 @@ web2py will attempt to run a GUI to ask for it
'Note: This value is ignored when using the --interfaces option') 'Note: This value is ignored when using the --interfaces option')
parser.add_option('-p', '--port', parser.add_option('-p', '--port',
default='8000', default=8000,
type='int', type='int', help=\
help='port of server (%default)') 'port of server (%default); ' \
'Note: This value is ignored when using the --interfaces option')
parser.add_option('-G', '--GAE', dest='gae', parser.add_option('-G', '--GAE', dest='gae',
default=None, default=None,
metavar='APP_NAME', help=\ metavar='APP_NAME', help=\
"will create app.yaml and gaehandler.py") 'will create app.yaml and gaehandler.py and exit')
parser.add_option('-a', '--password', parser.add_option('-a', '--password',
default='<ask>', default='<ask>',
@@ -836,34 +833,21 @@ web2py will attempt to run a GUI to ask for it
k = len(sys.argv) k = len(sys.argv)
sys.argv, other_args = sys.argv[:k], sys.argv[k + 1:] sys.argv, other_args = sys.argv[:k], sys.argv[k + 1:]
(options, args) = parser.parse_args() (options, args) = parser.parse_args()
# TODO: warn or error if args (should be no unparsed arguments)
options.args = other_args options.args = other_args
if options.config.endswith('.py'): if options.config.endswith('.py'):
options.config = options.config[:-3] options.config = options.config[:-3]
if options.config:
# TODO: process --config here; now is done in start function, too late # import options from options.config file
try:
copy_options = copy.deepcopy(options) # FIXME: avoid __import__
copy_options.password = '******' options2 = __import__(options.config)
global_settings.cmd_options = copy_options except:
global_settings.cmd_args = args die("cannot import config file %s" % options.config)
for key in dir(options2):
if options.gae: if hasattr(options, key):
if not os.path.exists('app.yaml'): setattr(options, key, getattr(options2, key))
name = options.gae
# for backward compatibility
if name == 'configure':
name = input("Your GAE app name: ")
content = open(os.path.join('examples', 'app.example.yaml'), 'rb').read()
open('app.yaml', 'wb').write(content.replace("yourappname", name))
else:
print("app.yaml alreday exists in the web2py folder")
if not os.path.exists('gaehandler.py'):
content = open(os.path.join('handlers', 'gaehandler.py'), 'rb').read()
open('gaehandler.py', 'wb').write(content)
else:
print("gaehandler.py alreday exists in the web2py folder")
sys.exit(0)
try: try:
options.ips = list(set( # no duplicates options.ips = list(set( # no duplicates
@@ -872,29 +856,15 @@ web2py will attempt to run a GUI to ask for it
except socket.gaierror: except socket.gaierror:
options.ips = [] options.ips = []
# FIXME: this should be done after create_welcome_w2p
if options.run_system_tests:
# run system test and exit
run_system_tests(options)
if options.quiet:
capture = StringIO()
sys.stdout = capture
logger.setLevel(logging.CRITICAL + 1)
else:
logger.setLevel(options.debuglevel)
if options.cronjob: if options.cronjob:
global_settings.cronjob = True # tell the world global_settings.cronjob = True # tell the world
options.plain = True # cronjobs use a plain shell options.plain = True # cronjobs use a plain shell
options.nobanner = True options.nobanner = True
options.nogui = True options.nogui = True
options.folder = os.path.abspath(options.folder)
# accept --interfaces in the form # accept --interfaces in the form
# "ip1:port1:key1:cert1:ca_cert1;[ip2]:port2;ip3:port3:key3:cert3" # "ip1:port1:key1:cert1:ca_cert1;[ip2]:port2;ip3:port3:key3:cert3"
# (no spaces; optional key:cert indicate SSL) # (no spaces; optional key:cert:ca_cert indicate SSL)
if isinstance(options.interfaces, str): if isinstance(options.interfaces, str):
interfaces = options.interfaces.split(';') interfaces = options.interfaces.split(';')
options.interfaces = [] options.interfaces = []
@@ -925,13 +895,11 @@ web2py will attempt to run a GUI to ask for it
if options.numthreads is not None and options.minthreads is None: if options.numthreads is not None and options.minthreads is None:
options.minthreads = options.numthreads # legacy options.minthreads = options.numthreads # legacy
create_welcome_w2p() copy_options = copy.deepcopy(options)
copy_options.password = '******'
global_settings.cmd_options = copy_options
# FIXME: do we still really need this? # FIXME: do we still really need this?
if not options.cronjob: global_settings.cmd_args = args
# If we have the applications package or if we should upgrade
if not os.path.exists('applications/__init__.py'):
write_file('applications/__init__.py', '')
return options, args return options, args
@@ -959,7 +927,7 @@ def start_schedulers(options):
try: try:
from multiprocessing import Process from multiprocessing import Process
except: except:
sys.stderr.write('Sorry, -K only supported for python 2.6-2.7\n') sys.stderr.write('Sorry, -K only supported for Python 2.6+\n')
return return
processes = [] processes = []
apps = [(app.strip(), None) for app in options.scheduler.split(',')] apps = [(app.strip(), None) for app in options.scheduler.split(',')]
@@ -1013,19 +981,37 @@ def start(cron=True):
# get command line arguments # get command line arguments
(options, args) = console() (options, args) = console()
# FIXME: this should be anticipated in console() if options.gae:
if options.config: # write app.yaml, gaehandler.py, and exit
# import options from options.config file if not os.path.exists('app.yaml'):
try: name = options.gae
options2 = __import__(options.config) # for backward compatibility
except: if name == 'configure':
sys.stderr.write("Cannot import config file %s\n" % options.config) if PY2: input = raw_input
sys.exit(1) name = input("Your GAE app name: ")
for key in dir(options2): content = open(os.path.join('examples', 'app.example.yaml'), 'rb').read()
# FIXME: better import condition, not all options attributes open('app.yaml', 'wb').write(content.replace("yourappname", name))
# should be sourced from config file else:
if hasattr(options, key): print("app.yaml alreday exists in the web2py folder")
setattr(options, key, getattr(options2, key)) if not os.path.exists('gaehandler.py'):
content = open(os.path.join('handlers', 'gaehandler.py'), 'rb').read()
open('gaehandler.py', 'wb').write(content)
else:
print("gaehandler.py alreday exists in the web2py folder")
return
create_welcome_w2p()
if options.run_system_tests:
# run system test and exit
run_system_tests(options)
if options.quiet:
capture = StringIO()
sys.stdout = capture
logger.setLevel(logging.CRITICAL + 1)
else:
logger.setLevel(options.debuglevel)
if not options.nobanner: if not options.nobanner:
# banner # banner
@@ -1089,8 +1075,7 @@ def start(cron=True):
# FIXME: this check should be done first # FIXME: this check should be done first
if options.taskbar and os.name != 'nt': if options.taskbar and os.name != 'nt':
sys.stderr.write('Error: taskbar not supported on this platform\n') die('taskbar not supported on this platform')
sys.exit(1)
root = None root = None
@@ -1153,7 +1138,7 @@ end tell
# interfaces option overrides the IP (and related) options. # interfaces option overrides the IP (and related) options.
if not options.interfaces: if not options.interfaces:
ip = options.ip ip = options.ip
port = int(options.port) port = options.port
else: else:
first_if = options.interfaces[0] first_if = options.interfaces[0]
ip = first_if[0] ip = first_if[0]

View File

@@ -1,28 +1,49 @@
#!/usr/bin/env python #!/usr/bin/env python
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from __future__ import print_function
import os import os
import sys import sys
from multiprocessing import freeze_support from multiprocessing import freeze_support
# import gluon.import_all ##### This should be uncommented for py2exe.py
if hasattr(sys, 'frozen'): if hasattr(sys, 'frozen'):
path = os.path.dirname(os.path.abspath(sys.executable)) # for py2exe # py2exe
path = os.path.dirname(os.path.abspath(sys.executable))
elif '__file__' in globals(): elif '__file__' in globals():
path = os.path.dirname(os.path.abspath(__file__)) path = os.path.dirname(os.path.abspath(__file__))
else: # should never happen else:
# should never happen
path = os.getcwd() path = os.getcwd()
# process -f (--folder) option
if '-f' in sys.argv:
fi = sys.argv.index('-f')
elif '--folder' in sys.argv:
fi = sys.argv.index('--folder')
else:
fi = None
if fi and fi < len(sys.argv):
fi += 1
folder = sys.argv[fi]
if not os.path.isdir(os.path.join(folder, 'gluon')):
print("%s: error: bad folder %s" % (sys.argv[0], folder), file=sys.stderr)
sys.exit(1)
path = sys.argv[fi] = os.path.abspath(folder)
os.chdir(path) os.chdir(path)
sys.path = [path] + [p for p in sys.path if not p == path] sys.path = [path] + [p for p in sys.path if not p == path]
# important that this import is after the os.chdir # important that this import is after the os.chdir
# import gluon.import_all # NOTE: should this be uncommented for py2exe.py ?
import gluon.widget import gluon.widget
# Start Web2py and Web2py cron service!
if __name__ == '__main__': if __name__ == '__main__':
freeze_support() freeze_support()
# support for sub-process coverage,
# see https://coverage.readthedocs.io/en/coverage-4.3.4/subprocess.html
if 'COVERAGE_PROCESS_START' in os.environ: if 'COVERAGE_PROCESS_START' in os.environ:
try: try:
import coverage import coverage
@@ -30,4 +51,5 @@ if __name__ == '__main__':
except: except:
print('Coverage is not available') print('Coverage is not available')
pass pass
gluon.widget.start(cron=True) # start services
gluon.widget.start()