Example #1
0
def plugin_install(app, fobj, request, filename):
    """Installs a plugin:

    - Identifies file type by filename
    - Writes `fobj` contents to the `../deposit/` folder
    - Calls `w2p_unpack_plugin()` to do the job.

    Args:
        app(str): new application name
        fobj: file object containing the application to be installed
        request: the global request object
        filename: original filename of the `fobj`,
            required to determine extension

    Returns:
        name of the file where plugin is temporarily stored
        or `False` on failure

    """
    upname = apath('../deposit/%s' % filename, request)

    try:
        write_file(upname, fobj.read(), 'wb')
        path = apath(app, request)
        w2p_unpack_plugin(upname, path)
        fix_newlines(path)
        return upname
    except Exception:
        os.unlink(upname)
        return False
Example #2
0
 def __init__(self, path):
     self.path = os.path.join(path, 'cron.master')
     if not os.path.exists(self.path):
         fileutils.write_file(self.path, to_bytes(''), 'wb')
     self.master = None
     self.now = time.time()
     self.logger = getLogger(logger_name)
Example #3
0
def generate_aliases(db, name, request):
    from gluon.fileutils import write_file
    import os

    current_folder = request.folder
    file_path = os.path.join(current_folder, "models/wood/{}_aliases.py".format(name))
    tables_names = db.tables

    lines = '''# coding=utf-8
# Autocomplete helpers for DAL tables and fields.
# Generated by wood.py
# Please do not modify this module manually.

if 0:
    from gluon.dal.base import DAL, Table, Field
    from gluon.dal.objects import Rows

    class db(DAL):
'''
    for table_name in tables_names:
        lines += """
        # Table: '{0}'
        class {0}(Table):""".format(table_name)
        for field in db[table_name].fields:
            lines += "\n            {} = Field()".format(field)
        lines += "\n\n        {0} = {0}\n".format(table_name)
    lines += "\n\n        def select(orderby=None, groupby=None, limitby=None, distinct=False, left=None, cache=None, *columns): return Rows()\n"
    lines += "\n\n        def count(distinct=False): return Rows()\n"
    lines += "\n    db = db"

    write_file(file_path, lines)
Example #4
0
def unzip(filename, dir, subfolder=''):
    """Unzips filename into dir (.zip only, no .gz etc)

    Args:
        filename(str): archive
        dir(str): destination
        subfolder(str): if != '' unzips only files in subfolder

    """
    filename = abspath(filename)
    if not zipfile.is_zipfile(filename):
        raise RuntimeError('Not a valid zipfile')
    zf = zipfile.ZipFile(filename)
    if not subfolder.endswith('/'):
        subfolder += '/'
    n = len(subfolder)
    for name in sorted(zf.namelist()):
        if not name.startswith(subfolder):
            continue
        #print name[n:]
        if name.endswith('/'):
            folder = os.path.join(dir, name[n:])
            if not os.path.exists(folder):
                os.mkdir(folder)
        else:
            write_file(os.path.join(dir, name[n:]), zf.read(name), 'wb')
Example #5
0
def fix_db(filename):
    params = dict(session.app['params'])
    content = read_file(filename, 'r')
    if 'auth_user' in session.app['tables']:
        auth_user = make_table('auth_user', session.app['table_auth_user'])
        content = content.replace('sqlite://storage.sqlite',
                                  params['database_uri'])
        content = content.replace('auth.define_tables()',
                                  auth_user + 'auth.define_tables(migrate = settings.migrate)')
    content += """
mail.settings.server = settings.email_server
mail.settings.sender = settings.email_sender
mail.settings.login = settings.email_login
"""
    if params['login_method'] == 'janrain':
        content += """
from gluon.contrib.login_methods.rpx_account import RPXAccount
auth.settings.actions_disabled=['register','change_password',
    'request_reset_password']
auth.settings.login_form = RPXAccount(request,
    api_key = settings.login_config.split(':')[-1],
    domain = settings.login_config.split(':')[0],
    url = "http://%s/%s/default/user/login" % (request.env.http_host,request.application))
"""
    write_file(filename, content, 'w')
Example #6
0
 def __init__(self, path):
     self.path = os.path.join(path, 'cron.master')
     if not os.path.exists(self.path):
         fileutils.write_file(self.path, to_bytes(''), 'wb')
     self.master = None
     self.now = time.time()
     self.logger = getLogger(logger_name)
Example #7
0
def plugin_install(app, fobj, request, filename):
    """Installs a plugin:

    - Identifies file type by filename
    - Writes `fobj` contents to the `../deposit/` folder
    - Calls `w2p_unpack_plugin()` to do the job.

    Args:
        app(str): new application name
        fobj: file object containing the application to be installed
        request: the global request object
        filename: original filename of the `fobj`,
            required to determine extension

    Returns:
        name of the file where plugin is temporarily stored
        or `False` on failure

    """
    upname = apath('../deposit/%s' % filename, request)

    try:
        write_file(upname, fobj.read(), 'wb')
        path = apath(app, request)
        w2p_unpack_plugin(upname, path)
        fix_newlines(path)
        return upname
    except Exception:
        os.unlink(upname)
        return False
Example #8
0
def unzip(filename, dir, subfolder=''):
    """Unzips filename into dir (.zip only, no .gz etc)

    Args:
        filename(str): archive
        dir(str): destination
        subfolder(str): if != '' unzips only files in subfolder

    """
    filename = abspath(filename)
    if not zipfile.is_zipfile(filename):
        raise RuntimeError('Not a valid zipfile')
    zf = zipfile.ZipFile(filename)
    if not subfolder.endswith('/'):
        subfolder += '/'
    n = len(subfolder)
    for name in sorted(zf.namelist()):
        if not name.startswith(subfolder):
            continue
        #print name[n:]
        if name.endswith('/'):
            folder = os.path.join(dir, name[n:])
            if not os.path.exists(folder):
                os.mkdir(folder)
        else:
            write_file(os.path.join(dir, name[n:]), zf.read(name), 'wb')
Example #9
0
def fix_db(filename):
    params = dict(session.app['params'])
    content = read_file(filename, 'rb')
    if 'auth_user' in session.app['tables']:
        auth_user = make_table('auth_user', session.app['table_auth_user'])
        content = content.replace('sqlite://storage.sqlite',
                                  params['database_uri'])
        content = content.replace(
            'auth.define_tables()',
            auth_user + 'auth.define_tables(migrate = settings.migrate)')
    content += """
mail.settings.server = settings.email_server
mail.settings.sender = settings.email_sender
mail.settings.login = settings.email_login
"""
    if params['login_method'] == 'janrain':
        content += """
from gluon.contrib.login_methods.rpx_account import RPXAccount
auth.settings.actions_disabled=['register','change_password',
    'request_reset_password']
auth.settings.login_form = RPXAccount(request,
    api_key = settings.login_config.split(':')[-1],
    domain = settings.login_config.split(':')[0],
    url = "http://%s/%s/default/user/login" % (request.env.http_host,request.application))
"""
    write_file(filename, content, 'wb')
Example #10
0
def deploy():
    regex = re.compile('^\w+$')
    apps = sorted(file for file in os.listdir(apath(r=request))
                  if regex.match(file))
    form = SQLFORM.factory(
        Field('appcfg',
              default=GAE_APPCFG,
              label=T('Path to appcfg.py'),
              requires=EXISTS(error_message=T('file not found'))),
        Field('google_application_id',
              requires=IS_MATCH('[\w\-]+'),
              label=T('Google Application Id')),
        Field('applications',
              'list:string',
              requires=IS_IN_SET(apps, multiple=True),
              label=T('web2py apps to deploy')),
        Field('email', requires=IS_EMAIL(), label=T('GAE Email')),
        Field('password',
              'password',
              requires=IS_NOT_EMPTY(),
              label=T('GAE Password')))
    cmd = output = errors = ""
    if form.accepts(request, session):
        try:
            kill()
        except:
            pass
        ignore_apps = [
            item for item in apps if not item in form.vars.applications
        ]
        regex = re.compile('\(applications/\(.*')
        yaml = apath('../app.yaml', r=request)
        if not os.path.exists(yaml):
            example = apath('../app.example.yaml', r=request)
            shutil.copyfile(example, yaml)
        data = read_file(yaml)
        data = re.sub('application:.*',
                      'application: %s' % form.vars.google_application_id,
                      data)
        data = regex.sub('(applications/(%s)/.*)|' % '|'.join(ignore_apps),
                         data)
        write_file(yaml, data)

        path = request.env.applications_parent
        cmd = '%s --email=%s --passin update %s' % \
            (form.vars.appcfg, form.vars.email, path)
        p = cache.ram('gae_upload',
                      lambda s=subprocess, c=cmd: s.Popen(c,
                                                          shell=True,
                                                          stdin=s.PIPE,
                                                          stdout=s.PIPE,
                                                          stderr=s.PIPE,
                                                          close_fds=True),
                      -1)
        p.stdin.write(form.vars.password + '\n')
        fcntl.fcntl(p.stdout.fileno(), fcntl.F_SETFL, os.O_NONBLOCK)
        fcntl.fcntl(p.stderr.fileno(), fcntl.F_SETFL, os.O_NONBLOCK)
    return dict(form=form, command=cmd)
Example #11
0
def app_create(app, request, force=False, key=None, info=False):
    """Create a copy of welcome.w2p (scaffolding) app

    Args:
        app(str): application name
        request: the global request object

    """
    path = apath(app, request)
    if not os.path.exists(path):
        try:
            os.mkdir(path)
        except:
            if info:
                return False, traceback.format_exc(sys.exc_info)
            else:
                return False
    elif not force:
        if info:
            return False, "Application exists"
        else:
            return False
    try:
        w2p_unpack("welcome.w2p", path)
        for subfolder in [
            "models",
            "views",
            "controllers",
            "databases",
            "modules",
            "cron",
            "errors",
            "sessions",
            "cache",
            "languages",
            "static",
            "private",
            "uploads",
        ]:
            subpath = os.path.join(path, subfolder)
            if not os.path.exists(subpath):
                os.mkdir(subpath)
        db = os.path.join(path, "models", "db.py")
        if os.path.exists(db):
            data = read_file(db)
            data = data.replace("<your secret key>", "sha512:" + (key or web2py_uuid()))
            write_file(db, data)
        if info:
            return True, None
        else:
            return True
    except:
        rmtree(path)
        if info:
            return False, traceback.format_exc(sys.exc_info)
        else:
            return False
Example #12
0
 def start(self):
     """
     start the web server
     """
     try:
         signal.signal(signal.SIGTERM, lambda a, b, s=self: s.stop())
         signal.signal(signal.SIGINT, lambda a, b, s=self: s.stop())
     except:
         pass
     write_file(self.pid_filename, str(os.getpid()))
     self.server.start()
Example #13
0
 def start(self):
     """
     start the web server
     """
     try:
         signal.signal(signal.SIGTERM, lambda a, b, s=self: s.stop())
         signal.signal(signal.SIGINT, lambda a, b, s=self: s.stop())
     except:
         pass
     write_file(self.pid_filename, str(os.getpid()))
     self.server.start()
Example #14
0
def app_create(app, request, force=False, key=None, info=False):
    """
    Create a copy of welcome.w2p (scaffolding) app

    Parameters
    ----------
    app:
        application name
    request:
        the global request object

    """
    path = apath(app, request)
    if not os.path.exists(path):
        try:
            os.mkdir(path)
        except:
            if info:
                return False, traceback.format_exc(sys.exc_info)
            else:
                return False
    elif not force:
        if info:
            return False, "Application exists"
        else:
            return False
    try:
        w2p_unpack('welcome.w2p', path)
        for subfolder in [
                'models', 'views', 'controllers', 'databases', 'modules',
                'cron', 'errors', 'sessions', 'cache', 'languages', 'static',
                'private', 'uploads'
        ]:
            subpath = os.path.join(path, subfolder)
            if not os.path.exists(subpath):
                os.mkdir(subpath)
        db = os.path.join(path, 'models', 'db.py')
        if os.path.exists(db):
            data = read_file(db)
            data = data.replace('<your secret key>',
                                'sha512:' + (key or web2py_uuid()))
            write_file(db, data)
        if info:
            return True, None
        else:
            return True
    except:
        rmtree(path)
        if info:
            return False, traceback.format_exc(sys.exc_info)
        else:
            return False
Example #15
0
def compile_models(folder):
    """
    Compiles all the models in the application specified by `folder`
    """

    path = pjoin(folder, 'models')
    for file in listdir(path, '.+\.py$'):
        data = read_file(pjoin(path, file))
        filename = pjoin(folder, 'compiled', 'models', file)
        mktree(filename)
        write_file(filename, data)
        save_pyc(filename)
        os.unlink(filename)
Example #16
0
def compile_models(folder):
    """
    Compiles all the models in the application specified by `folder`
    """

    path = pjoin(folder, 'models')
    for file in listdir(path, '.+\.py$'):
        data = read_file(pjoin(path, file))
        filename = pjoin(folder, 'compiled', 'models', file)
        mktree(filename)
        write_file(filename, data)
        save_pyc(filename)
        os.unlink(filename)
Example #17
0
 def test_crondance(self):
     base = os.path.join(appdir, 'cron')
     write_file(os.path.join(base, 'crontab'), TEST_CRONTAB)
     write_file(os.path.join(base, 'test.py'), TEST_SCRIPT)
     if os.path.exists(TARGET):
         os.unlink(TARGET)
     crondance(os.getcwd(), 'hard', startup=True, apps=[test_app_name])
     # must wait for the cron task, not very reliable
     time.sleep(1)
     while subprocess_count():
         time.sleep(1)
     time.sleep(1)
     self.assertTrue(os.path.exists(TARGET))
Example #18
0
 def test_2_crondance(self):
     base = os.path.join(appdir, 'cron')
     write_file(os.path.join(base, 'crontab'), TEST_CRONTAB)
     write_file(os.path.join(base, 'test.py'), TEST_SCRIPT1)
     if os.path.exists(TARGET):
         os.unlink(TARGET)
     crondance(os.getcwd(), 'hard', startup=True, apps=[test_app_name])
     # must wait for the cron task, not very reliable
     time.sleep(1)
     while subprocess_count():
         time.sleep(1)
     time.sleep(1)
     self.assertTrue(os.path.exists(TARGET))
Example #19
0
def compile_models(folder):
    """
    Compiles all the models in the application specified by `folder`
    """
    path = pjoin(folder, 'models')
    for fname in listdir(path, REGEX_MODEL_PATH, followlinks=True):
        data = read_file(pjoin(path, fname))
        modelfile = 'models.' + fname.replace(os.sep, '.')
        filename = pjoin(folder, 'compiled', modelfile)
        mktree(filename)
        write_file(filename, data)
        save_pyc(filename)
        os.unlink(filename)
Example #20
0
def compile_models(folder):
    """
    Compiles all the models in the application specified by `folder`
    """
    path = pjoin(folder, 'models')
    for fname in listdir(path, REGEX_MODEL_PATH):
        data = read_file(pjoin(path, fname))
        modelfile = 'models.'+fname.replace(os.sep, '.')
        filename = pjoin(folder, 'compiled', modelfile)
        mktree(filename)
        write_file(filename, data)
        save_pyc(filename)
        os.unlink(filename)
Example #21
0
def app_create(app, request, force=False, key=None, info=False):
    """
    Create a copy of welcome.w2p (scaffolding) app

    Parameters
    ----------
    app:
        application name
    request:
        the global request object

    """
    path = apath(app, request)
    if not os.path.exists(path):
        try:
            os.mkdir(path)
        except:
            if info:
                return False, traceback.format_exc(sys.exc_info)
            else:
                return False
    elif not force:
        if info:
            return False, "Application exists"
        else:
            return False
    try:
        w2p_unpack('welcome.w2p', path)
        for subfolder in [
            'models', 'views', 'controllers', 'databases',
            'modules', 'cron', 'errors', 'sessions', 'cache',
            'languages', 'static', 'private', 'uploads']:
            subpath = os.path.join(path, subfolder)
            if not os.path.exists(subpath):
                os.mkdir(subpath)
        db = os.path.join(path, 'models', 'db.py')
        if os.path.exists(db):
            data = read_file(db)
            data = data.replace('<your secret key>',
                                'sha512:' + (key or web2py_uuid()))
            write_file(db, data)
        if info:
            return True, None
        else:
            return True
    except:
        rmtree(path)
        if info:
            return False, traceback.format_exc(sys.exc_info)
        else:
            return False
Example #22
0
def hg_repo(path):
    import os
    uio = ui.ui()
    uio.quiet = True
    if not os.environ.get('HGUSER') and not uio.config("ui", "username"):
        os.environ['HGUSER'] = '******'
    try:
        repo = hg.repository(ui=uio, path=path)
    except:
        repo = hg.repository(ui=uio, path=path, create=True)
    hgignore = os.path.join(path, '.hgignore')
    if not os.path.exists(hgignore):
        write_file(hgignore, _hgignore_content)
    return repo
Example #23
0
def upgrade(request, url='http://web2py.com'):
    """Upgrades web2py (src, osx, win) if a new version is posted.
    It detects whether src, osx or win is running and downloads the right one

    Args:
        request: the current request object
            (required to determine version and path)
        url: the incomplete url where to locate the latest web2py
             (actual url is url+'/examples/static/web2py_(src|osx|win).zip')

    Returns
        tuple: completed, traceback

        - completed: True on success, False on failure
          (network problem or old version)
        - traceback: None on success, raised exception details on failure

    """
    web2py_version = request.env.web2py_version
    gluon_parent = request.env.gluon_parent
    if not gluon_parent.endswith('/'):
        gluon_parent += '/'
    (check, version) = check_new_version(web2py_version,
                                         url + '/examples/default/version')
    if not check:
        return False, 'Already latest version'
    if os.path.exists(os.path.join(gluon_parent, 'web2py.exe')):
        version_type = 'win'
        destination = gluon_parent
        subfolder = 'web2py/'
    elif gluon_parent.endswith('/Contents/Resources/'):
        version_type = 'osx'
        destination = gluon_parent[:-len('/Contents/Resources/')]
        subfolder = 'web2py/web2py.app/'
    else:
        version_type = 'src'
        destination = gluon_parent
        subfolder = 'web2py/'

    full_url = url + '/examples/static/web2py_%s.zip' % version_type
    filename = abspath('web2py_%s_downloaded.zip' % version_type)
    try:
        write_file(filename, urllib.urlopen(full_url).read(), 'wb')
    except Exception as e:
        return False, e
    try:
        unzip(filename, destination, subfolder)
        return True, None
    except Exception as e:
        return False, e
Example #24
0
def compile_models(folder):
    """
    Compiles all the models in the application specified by `folder`
    """

    path = pjoin(folder, "models")
    for fname in listdir(path, ".+\.py$"):
        data = read_file(pjoin(path, fname))
        modelfile = "models." + fname.replace(os.path.sep, ".")
        filename = pjoin(folder, "compiled", modelfile)
        mktree(filename)
        write_file(filename, data)
        save_pyc(filename)
        os.unlink(filename)
Example #25
0
def upgrade(request, url='http://web2py.com'):
    """Upgrades web2py (src, osx, win) if a new version is posted.
    It detects whether src, osx or win is running and downloads the right one

    Args:
        request: the current request object
            (required to determine version and path)
        url: the incomplete url where to locate the latest web2py
             (actual url is url+'/examples/static/web2py_(src|osx|win).zip')

    Returns
        tuple: completed, traceback

        - completed: True on success, False on failure
          (network problem or old version)
        - traceback: None on success, raised exception details on failure

    """
    web2py_version = request.env.web2py_version
    gluon_parent = request.env.gluon_parent
    if not gluon_parent.endswith('/'):
        gluon_parent += '/'
    (check, version) = check_new_version(web2py_version,
                                         url + '/examples/default/version')
    if not check:
        return False, 'Already latest version'
    if os.path.exists(os.path.join(gluon_parent, 'web2py.exe')):
        version_type = 'win'
        destination = gluon_parent
        subfolder = 'web2py/'
    elif gluon_parent.endswith('/Contents/Resources/'):
        version_type = 'osx'
        destination = gluon_parent[:-len('/Contents/Resources/')]
        subfolder = 'web2py/web2py.app/'
    else:
        version_type = 'src'
        destination = gluon_parent
        subfolder = 'web2py/'

    full_url = url + '/examples/static/web2py_%s.zip' % version_type
    filename = abspath('web2py_%s_downloaded.zip' % version_type)
    try:
        write_file(filename, urlopen(full_url).read(), 'wb')
    except Exception as e:
        return False, e
    try:
        unzip(filename, destination, subfolder)
        return True, None
    except Exception as e:
        return False, e
Example #26
0
    def app_with_logging(environ, responder):
        """
        a wsgi app that does logging and profiling and calls wsgibase
        """
        status_headers = []

        def responder2(s, h):
            """
            wsgi responder app
            """
            status_headers.append(s)
            status_headers.append(h)
            return responder(s, h)

        time_in = time.time()
        ret = [0]
        if not profiler_dir:
            ret[0] = wsgiapp(environ, responder2)
        else:
            import cProfile
            prof = cProfile.Profile()
            prof.enable()
            ret[0] = wsgiapp(environ, responder2)
            prof.disable()
            destfile = pjoin(profiler_dir, "req_%s.prof" % web2py_uuid())
            prof.dump_stats(destfile)

        try:
            today = datetime.datetime.today()
            line = '%s, %s, %s, %s, %s, %s, %f\n' % (
                environ['REMOTE_ADDR'],
                '%s.%03d' % (today.strftime('%Y-%m-%d %H:%M:%S'),
                             int(today.microsecond / 1000)),
                environ['REQUEST_METHOD'],
                '%s://%s:%s%s' %
                (environ['wsgi.url_scheme'], environ['HTTP_HOST'],
                 environ['SERVER_PORT'], environ['REQUEST_URI']),
                environ['SERVER_PROTOCOL'],
                (status_headers[0])[:3],
                time.time() - time_in,
            )
            if not logfilename:
                sys.stdout.write(line)
            elif isinstance(logfilename, str):
                write_file(logfilename, line, 'a')
            else:
                logfilename.write(line)
        except:
            pass
        return ret[0]
Example #27
0
def hg_repo(path):
    import os
    uio = ui.ui()
    uio.quiet = True
    if not os.environ.get('HGUSER') and not uio.config("ui", "username"):
        os.environ['HGUSER'] = '******'
    try:
        repo = hg.repository(ui=uio, path=path)
    except:
        repo = hg.repository(ui=uio, path=path, create=True)
    hgignore = os.path.join(path, '.hgignore')
    if not os.path.exists(hgignore):
        write_file(hgignore, _hgignore_content)
    return repo
Example #28
0
 def test_3_SimplePool(self):
     base = os.path.join(appdir, 'cron')
     write_file(os.path.join(base, 'test.py'), TEST_SCRIPT2)
     w2p_path = os.path.join(os.getcwd(), 'web2py.py')
     self.assertTrue(os.path.exists(w2p_path))
     launcher = SimplePool(1)
     cmd1 = [sys.executable, w2p_path,
         '--cron_job', '--no_banner', '--no_gui', '--plain',
         '-S', test_app_name, '-R', "applications/%s/cron/test.py" % test_app_name]
     self.assertTrue(launcher(cmd1))
     self.assertFalse(launcher(None))
     time.sleep(1)
     stopcron()
     time.sleep(1)
     reset()
Example #29
0
def app_install(app, fobj, request, filename, overwrite=None):
    """
    Installs an application:

    - Identifies file type by filename
    - Writes `fobj` contents to the `../deposit/` folder
    - Calls `w2p_unpack()` to do the job.

    Parameters
    ----------
    app:
        new application name
    fobj:
        file object containing the application to be installed
    request:
        the global request object
    filename:
        original filename of the `fobj`, required to determine extension

    Returns
    -------
    upname:
        name of the file where app is temporarily stored or `None` on failure
    """
    did_mkdir = False
    if filename[-4:] == '.w2p':
        extension = 'w2p'
    elif filename[-7:] == '.tar.gz':
        extension = 'tar.gz'
    else:
        extension = 'tar'
    upname = apath('../deposit/%s.%s' % (app, extension), request)

    try:
        write_file(upname, fobj.read(), 'wb')
        path = apath(app, request)
        if not overwrite:
            os.mkdir(path)
            did_mkdir = True
        w2p_unpack(upname, path)
        if extension != 'tar':
            os.unlink(upname)
        fix_newlines(path)
        return upname
    except Exception:
        if did_mkdir:
            rmtree(path)
        return False
Example #30
0
def app_install(app, fobj, request, filename, overwrite=None):
    """
    Installs an application:

    - Identifies file type by filename
    - Writes `fobj` contents to the `../deposit/` folder
    - Calls `w2p_unpack()` to do the job.

    Parameters
    ----------
    app:
        new application name
    fobj:
        file object containing the application to be installed
    request:
        the global request object
    filename:
        original filename of the `fobj`, required to determine extension

    Returns
    -------
    upname:
        name of the file where app is temporarily stored or `None` on failure
    """
    did_mkdir = False
    if filename[-4:] == '.w2p':
        extension = 'w2p'
    elif filename[-7:] == '.tar.gz':
        extension = 'tar.gz'
    else:
        extension = 'tar'
    upname = apath('../deposit/%s.%s' % (app, extension), request)

    try:
        write_file(upname, fobj.read(), 'wb')
        path = apath(app, request)
        if not overwrite:
            os.mkdir(path)
            did_mkdir = True
        w2p_unpack(upname, path)
        if extension != 'tar':
            os.unlink(upname)
        fix_newlines(path)
        return upname
    except Exception:
        if did_mkdir:
            rmtree(path)
        return False
Example #31
0
def compile_controllers(folder):
    """
    Compiles all the controllers in the application specified by `folder`
    """

    path = pjoin(folder, "controllers")
    for fname in listdir(path, ".+\.py$"):
        ### why is this here? save_pyc(pjoin(path, file))
        data = read_file(pjoin(path, fname))
        exposed = find_exposed_functions(data)
        for function in exposed:
            command = data + "\nresponse._vars=response._caller(%s)\n" % function
            filename = pjoin(folder, "compiled", "controllers.%s.%s.py" % (fname[:-3], function))
            write_file(filename, command)
            save_pyc(filename)
            os.unlink(filename)
Example #32
0
def compile_views(folder):
    """
    Compiles all the views in the application specified by `folder`
    """

    path = pjoin(folder, 'views')
    for fname in listdir(path, '^[\w/\-]+(\.\w+)*$'):
        try:
            data = parse_template(fname, path)
        except Exception, e:
            raise Exception("%s in %s" % (e, fname))
        filename = 'views.%s.py' % fname.replace(os.path.sep, '.')
        filename = pjoin(folder, 'compiled', filename)
        write_file(filename, data)
        save_pyc(filename)
        os.unlink(filename)
Example #33
0
def compile_controllers(folder):
    """
    Compiles all the controllers in the application specified by `folder`
    """
    path = pjoin(folder, 'controllers')
    for fname in listdir(path, REGEX_CONTROLLER, followlinks=True):
        data = read_file(pjoin(path, fname))
        exposed = find_exposed_functions(data)
        for function in exposed:
            command = data + "\nresponse._vars=response._caller(%s)\n" % \
                function
            filename = pjoin(folder, 'compiled',
                             'controllers.%s.%s.py' % (fname[:-3], function))
            write_file(filename, command)
            save_pyc(filename)
            os.unlink(filename)
Example #34
0
def compile_views(folder):
    """
    Compiles all the views in the application specified by `folder`
    """

    path = pjoin(folder, 'views')
    for fname in listdir(path, '^[\w/\-]+(\.\w+)*$'):
        try:
            data = parse_template(fname, path)
        except Exception, e:
            raise Exception("%s in %s" % (e, fname))
        filename = 'views.%s.py' % fname.replace(os.path.sep, '.')
        filename = pjoin(folder, 'compiled', filename)
        write_file(filename, data)
        save_pyc(filename)
        os.unlink(filename)
Example #35
0
def compile_controllers(folder):
    """
    Compiles all the controllers in the application specified by `folder`
    """
    path = pjoin(folder, 'controllers')
    for fname in listdir(path, REGEX_CONTROLLER):
        data = read_file(pjoin(path, fname))
        exposed = find_exposed_functions(data)
        for function in exposed:
            command = data + "\nresponse._vars=response._caller(%s)\n" % \
                function
            filename = pjoin(folder, 'compiled',
                             'controllers.%s.%s.py' % (fname[:-3], function))
            write_file(filename, command)
            save_pyc(filename)
            os.unlink(filename)
Example #36
0
    def app_with_logging(environ, responder):
        """
        a wsgi app that does logging and profiling and calls wsgibase
        """
        status_headers = []

        def responder2(s, h):
            """
            wsgi responder app
            """
            status_headers.append(s)
            status_headers.append(h)
            return responder(s, h)

        time_in = time.time()
        ret = [0]
        if not profiler_dir:
            ret[0] = wsgiapp(environ, responder2)
        else:
            import cProfile
            prof = cProfile.Profile()
            prof.enable()
            ret[0] = wsgiapp(environ, responder2)
            prof.disable()
            destfile = pjoin(profiler_dir, "req_%s.prof" % web2py_uuid())
            prof.dump_stats(destfile)

        try:
            line = '%s, %s, %s, %s, %s, %s, %f\n' % (
                environ['REMOTE_ADDR'],
                datetime.datetime.today().strftime('%Y-%m-%d %H:%M:%S'),
                environ['REQUEST_METHOD'],
                environ['PATH_INFO'].replace(',', '%2C'),
                environ['SERVER_PROTOCOL'],
                (status_headers[0])[:3],
                time.time() - time_in,
            )
            if not logfilename:
                sys.stdout.write(line)
            elif isinstance(logfilename, str):
                write_file(logfilename, line, 'a')
            else:
                logfilename.write(line)
        except:
            pass
        return ret[0]
Example #37
0
    def app_with_logging(environ, responder):
        """
        a wsgi app that does logging and profiling and calls wsgibase
        """
        status_headers = []

        def responder2(s, h):
            """
            wsgi responder app
            """
            status_headers.append(s)
            status_headers.append(h)
            return responder(s, h)

        time_in = time.time()
        ret = [0]
        if not profiler_dir:
            ret[0] = wsgiapp(environ, responder2)
        else:
            import cProfile
            prof = cProfile.Profile()
            prof.enable()
            ret[0] = wsgiapp(environ, responder2)
            prof.disable()
            destfile = pjoin(profiler_dir, "req_%s.prof" % web2py_uuid())
            prof.dump_stats(destfile)

        try:
            line = '%s, %s, %s, %s, %s, %s, %f\n' % (
                environ['REMOTE_ADDR'],
                datetime.datetime.today().strftime('%Y-%m-%d %H:%M:%S'),
                environ['REQUEST_METHOD'],
                environ['PATH_INFO'].replace(',', '%2C'),
                environ['SERVER_PROTOCOL'],
                (status_headers[0])[:3],
                time.time() - time_in,
            )
            if not logfilename:
                sys.stdout.write(line)
            elif isinstance(logfilename, str):
                write_file(logfilename, line, 'a')
            else:
                logfilename.write(line)
        except:
            pass
        return ret[0]
Example #38
0
def deploy():
    regex = re.compile('^\w+$')
    apps = sorted(
        file for file in os.listdir(apath(r=request)) if regex.match(file))
    form = SQLFORM.factory(
        Field('appcfg', default=GAE_APPCFG, label=T('Path to appcfg.py'),
              requires=EXISTS(error_message=T('file not found'))),
        Field('google_application_id', requires=IS_MATCH(
            '[\w\-]+'), label=T('Google Application Id')),
        Field('applications', 'list:string',
              requires=IS_IN_SET(apps, multiple=True),
              label=T('web2py apps to deploy')),
        Field('email', requires=IS_EMAIL(), label=T('GAE Email')),
        Field('password', 'password', requires=IS_NOT_EMPTY(), label=T('GAE Password')))
    cmd = output = errors = ""
    if form.accepts(request, session):
        try:
            kill()
        except:
            pass
        ignore_apps = [item for item in apps
                       if not item in form.vars.applications]
        regex = re.compile('\(applications/\(.*')
        yaml = apath('../app.yaml', r=request)
        if not os.path.exists(yaml):
            example = apath('../app.example.yaml', r=request)
            shutil.copyfile(example, yaml)
        data = read_file(yaml)
        data = re.sub('application:.*', 'application: %s' %
                      form.vars.google_application_id, data)
        data = regex.sub(
            '(applications/(%s)/.*)|' % '|'.join(ignore_apps), data)
        write_file(yaml, data)

        path = request.env.applications_parent
        cmd = '%s --email=%s --passin update %s' % \
            (form.vars.appcfg, form.vars.email, path)
        p = cache.ram('gae_upload',
                      lambda s=subprocess, c=cmd: s.Popen(c, shell=True,
                                                          stdin=s.PIPE,
                                                          stdout=s.PIPE,
                                                          stderr=s.PIPE, close_fds=True), -1)
        p.stdin.write(form.vars.password + '\n')
        fcntl.fcntl(p.stdout.fileno(), fcntl.F_SETFL, os.O_NONBLOCK)
        fcntl.fcntl(p.stderr.fileno(), fcntl.F_SETFL, os.O_NONBLOCK)
    return dict(form=form, command=cmd)
Example #39
0
def compile_controllers(folder):
    """
    Compiles all the controllers in the application specified by `folder`
    """

    path = pjoin(folder, 'controllers')
    for fname in listdir(path, '.+\.py$'):
        ### why is this here? save_pyc(pjoin(path, file))
        data = read_file(pjoin(path, fname))
        exposed = regex_expose.findall(data)
        for function in exposed:
            command = data + "\nresponse._vars=response._caller(%s)\n" % \
                function
            filename = pjoin(folder, 'compiled',
                             'controllers.%s.%s.py' % (fname[:-3], function))
            write_file(filename, command)
            save_pyc(filename)
            os.unlink(filename)
Example #40
0
def compile_controllers(folder):
    """
    Compiles all the controllers in the application specified by `folder`
    """

    path = pjoin(folder, 'controllers')
    for file in listdir(path, '.+\.py$'):
        ### why is this here? save_pyc(pjoin(path, file))
        data = read_file(pjoin(path, file))
        exposed = regex_expose.findall(data)
        for function in exposed:
            command = data + "\nresponse._vars=response._caller(%s)\n" % \
                function
            filename = pjoin(folder, 'compiled', ('controllers/'
                                     + file[:-3]).replace('/', '_')
                             + '_' + function + '.py')
            write_file(filename, command)
            save_pyc(filename)
            os.unlink(filename)
Example #41
0
def app_install(app, fobj, request, filename, overwrite=None):
    """Installs an application:

    - Identifies file type by filename
    - Writes `fobj` contents to the `../deposit/` folder
    - Calls `w2p_unpack()` to do the job.

    Args:
        app(str): new application name
        fobj(obj): file object containing the application to be installed
        request: the global request object
        filename(str): original filename of the `fobj`,
            required to determine extension
        overwrite(bool): force overwrite of existing application

    Returns:
        name of the file where app is temporarily stored or `None` on failure

    """
    did_mkdir = False
    if filename[-4:] == ".w2p":
        extension = "w2p"
    elif filename[-7:] == ".tar.gz":
        extension = "tar.gz"
    else:
        extension = "tar"
    upname = apath("../deposit/%s.%s" % (app, extension), request)

    try:
        write_file(upname, fobj.read(), "wb")
        path = apath(app, request)
        if not overwrite:
            os.mkdir(path)
            did_mkdir = True
        w2p_unpack(upname, path)
        if extension != "tar":
            os.unlink(upname)
        fix_newlines(path)
        return upname
    except Exception:
        if did_mkdir:
            rmtree(path)
        return False
Example #42
0
def compile_views(folder, skip_failed_views=False):
    """
    Compiles all the views in the application specified by `folder`
    """

    path = pjoin(folder, 'views')
    failed_views = []
    for fname in listdir(path, '^[\w/\-]+(\.\w+)*$'):
        try:
            data = parse_template(fname, path)
        except Exception, e:
            if skip_failed_views:
                failed_views.append(fname)
            else:
                raise Exception("%s in %s" % (e, fname))
        else:
            filename = ('views/%s.py' % fname).replace('/', '_').replace('\\', '_')
            filename = pjoin(folder, 'compiled', filename)
            write_file(filename, data)
            save_pyc(filename)
            os.unlink(filename)
Example #43
0
def compile_views(folder, skip_failed_views=False):
    """
    Compiles all the views in the application specified by `folder`
    """

    path = pjoin(folder, 'views')
    failed_views = [] 
    for fname in listdir(path, '^[\w/\-]+(\.\w+)*$'):
        try:
            data = parse_template(fname, path)
        except Exception, e:
            if skip_failed_views:                                                                            
                failed_views.append(file)                                                                    
            else:                                                                                            
                raise Exception("%s in %s" % (e, file))                                                      
        else:                                                                                                
            filename = ('views/%s.py' % file).replace('/', '_').replace('\\', '_')                           
            filename = pjoin(folder, 'compiled', filename)                                                   
            write_file(filename, data)                                                                       
            save_pyc(filename)                                                                               
            os.unlink(filename)                                                                              
Example #44
0
def fix_db(filename):
    params = dict(session.app["params"])
    content = read_file(filename, "rb")
    if "auth_user" in session.app["tables"]:
        auth_user = make_table("auth_user", session.app["table_auth_user"])
        content = content.replace("sqlite://storage.sqlite", params["database_uri"])
        content = content.replace("auth.define_tables()", auth_user + "auth.define_tables(migrate = settings.migrate)")
    content += """
mail.settings.server = settings.email_server
mail.settings.sender = settings.email_sender
mail.settings.login = settings.email_login
"""
    if params["login_method"] == "janrain":
        content += """
from gluon.contrib.login_methods.rpx_account import RPXAccount
auth.settings.actions_disabled=['register','change_password','request_reset_password']
auth.settings.login_form = RPXAccount(request,
    api_key = settings.login_config.split(':')[-1],
    domain = settings.login_config.split(':')[0],
    url = "http://%s/%s/default/user/login" % (request.env.http_host,request.application))
"""
    write_file(filename, content, "wb")
Example #45
0
def compile_views(folder, skip_failed_views=False):
    """
    Compiles all the views in the application specified by `folder`
    """
    path = pjoin(folder, 'views')
    failed_views = []
    for fname in listdir(path, REGEX_VIEW_PATH):
        try:
            data = parse_template(fname, path)
        except Exception as e:
            if skip_failed_views:
                failed_views.append(fname)
            else:
                # FIXME: should raise something more specific than Exception
                raise Exception("%s in %s" % (e, fname))
        else:
            filename = 'views.%s.py' % fname.replace(os.sep, '.')
            filename = pjoin(folder, 'compiled', filename)
            write_file(filename, data)
            save_pyc(filename)
            os.unlink(filename)
    return failed_views or None
Example #46
0
def compile_views(folder, skip_failed_views=False):
    """
    Compiles all the views in the application specified by `folder`
    """
    path = pjoin(folder, 'views')
    failed_views = []
    for fname in listdir(path, REGEX_VIEW_PATH, followlinks=True):
        try:
            data = parse_template(fname, path)
        except Exception as e:
            if skip_failed_views:
                failed_views.append(fname)
            else:
                # FIXME: should raise something more specific than Exception
                raise Exception("%s in %s" % (e, fname))
        else:
            filename = 'views.%s.py' % fname.replace(os.sep, '.')
            filename = pjoin(folder, 'compiled', filename)
            write_file(filename, data)
            save_pyc(filename)
            os.unlink(filename)
    return failed_views or None
Example #47
0
 def __init__(self, path):
     self.path = os.path.join(path, 'cron.master')
     if not os.path.exists(self.path):
         fileutils.write_file(self.path, '', 'wb')
     self.master = None
     self.now = time.time()
Example #48
0
def run(
    appname,
    plain=False,
    import_models=False,
    startfile=None,
    bpython=False,
    python_code=False,
    cronjob=False):
    """
    Start interactive shell or run Python script (startfile) in web2py
    controller environment. appname is formatted like:

    a      web2py application name
    a/c    exec the controller c into the application environment
    """

    (a, c, f, args, vars) = parse_path_info(appname, av=True)
    errmsg = 'invalid application name: %s' % appname
    if not a:
        die(errmsg)
    adir = os.path.join('applications', a)

    if not os.path.exists(adir):
        if sys.stdin and not sys.stdin.name == '/dev/null':
            confirm = raw_input(
                'application %s does not exist, create (y/n)?' % a)
        else:
            logging.warn('application does not exist and will not be created')
            return
        if confirm.lower() in ['y', 'yes']:

            os.mkdir(adir)
            w2p_unpack('welcome.w2p', adir)
            for subfolder in ['models', 'views', 'controllers', 'databases',
                              'modules', 'cron', 'errors', 'sessions',
                              'languages', 'static', 'private', 'uploads']:
                subpath = os.path.join(adir, subfolder)
                if not os.path.exists(subpath):
                    os.mkdir(subpath)
            db = os.path.join(adir, 'models/db.py')
            if os.path.exists(db):
                data = fileutils.read_file(db)
                data = data.replace(
                    '<your secret key>', 'sha512:' + web2py_uuid())
                fileutils.write_file(db, data)

    if c:
        import_models = True
    extra_request = {}
    if args:
        extra_request['args'] = args
    if vars:
        extra_request['vars'] = vars
    _env = env(a, c=c, f=f, import_models=import_models, extra_request=extra_request)
    if c:
        pyfile = os.path.join('applications', a, 'controllers', c + '.py')
        pycfile = os.path.join('applications', a, 'compiled',
                                 "controllers_%s_%s.pyc" % (c, f))
        if ((cronjob and os.path.isfile(pycfile))
            or not os.path.isfile(pyfile)):
            exec read_pyc(pycfile) in _env
        elif os.path.isfile(pyfile):
            execfile(pyfile, _env)
        else:
            die(errmsg)

    if f:
        exec ('print %s()' % f, _env)
        return

    _env.update(exec_pythonrc())
    if startfile:
        try:
            ccode = None
            if startfile.endswith('.pyc'):
                ccode = read_pyc(startfile)
                exec ccode in _env
            else:
                execfile(startfile, _env)

            if import_models:
                BaseAdapter.close_all_instances('commit')
        except Exception, e:
            print traceback.format_exc()
            if import_models:
                BaseAdapter.close_all_instances('rollback')
Example #49
0
def run(appname,
        plain=False,
        import_models=False,
        startfile=None,
        bpython=False,
        python_code=False,
        cronjob=False):
    """
    Start interactive shell or run Python script (startfile) in web2py
    controller environment. appname is formatted like:

    - a : web2py application name
    - a/c : exec the controller c into the application environment
    """

    (a, c, f, args, vars) = parse_path_info(appname, av=True)
    errmsg = 'invalid application name: %s' % appname
    if not a:
        die(errmsg)
    adir = os.path.join('applications', a)

    if not os.path.exists(adir):
        if sys.stdin and not sys.stdin.name == '/dev/null':
            confirm = raw_input(
                'application %s does not exist, create (y/n)?' % a)
        else:
            logging.warn('application does not exist and will not be created')
            return
        if confirm.lower() in ['y', 'yes']:

            os.mkdir(adir)
            w2p_unpack('welcome.w2p', adir)
            for subfolder in [
                    'models', 'views', 'controllers', 'databases', 'modules',
                    'cron', 'errors', 'sessions', 'languages', 'static',
                    'private', 'uploads'
            ]:
                subpath = os.path.join(adir, subfolder)
                if not os.path.exists(subpath):
                    os.mkdir(subpath)
            db = os.path.join(adir, 'models/db.py')
            if os.path.exists(db):
                data = fileutils.read_file(db)
                data = data.replace('<your secret key>',
                                    'sha512:' + web2py_uuid())
                fileutils.write_file(db, data)

    if c:
        import_models = True
    extra_request = {}
    if args:
        extra_request['args'] = args
    if vars:
        extra_request['vars'] = vars
    _env = env(a,
               c=c,
               f=f,
               import_models=import_models,
               extra_request=extra_request)
    if c:
        pyfile = os.path.join('applications', a, 'controllers', c + '.py')
        pycfile = os.path.join('applications', a, 'compiled',
                               "controllers_%s_%s.pyc" % (c, f))
        if ((cronjob and os.path.isfile(pycfile))
                or not os.path.isfile(pyfile)):
            exec read_pyc(pycfile) in _env
        elif os.path.isfile(pyfile):
            execfile(pyfile, _env)
        else:
            die(errmsg)

    if f:
        exec('print %s()' % f, _env)
        return

    _env.update(exec_pythonrc())
    if startfile:
        try:
            ccode = None
            if startfile.endswith('.pyc'):
                ccode = read_pyc(startfile)
                exec ccode in _env
            else:
                execfile(startfile, _env)

            if import_models:
                BaseAdapter.close_all_instances('commit')
        except Exception, e:
            print traceback.format_exc()
            if import_models:
                BaseAdapter.close_all_instances('rollback')
Example #50
0
def run(
    appname,
    plain=False,
    import_models=False,
    startfile=None,
    bpython=False,
    python_code=False,
    cronjob=False):
    """
    Start interactive shell or run Python script (startfile) in web2py
    controller environment. appname is formatted like:

    - a : web2py application name
    - a/c : exec the controller c into the application environment
    """

    (a, c, f, args, vars) = parse_path_info(appname, av=True)
    errmsg = 'invalid application name: %s' % appname
    if not a:
        die(errmsg)
    adir = os.path.join('applications', a)

    if not os.path.exists(adir):
        if sys.stdin and not sys.stdin.name == '/dev/null':
            confirm = raw_input(
                'application %s does not exist, create (y/n)?' % a)
        else:
            logging.warn('application does not exist and will not be created')
            return
        if confirm.lower() in ['y', 'yes']:

            os.mkdir(adir)
            w2p_unpack('welcome.w2p', adir)
            for subfolder in ['models', 'views', 'controllers', 'databases',
                              'modules', 'cron', 'errors', 'sessions',
                              'languages', 'static', 'private', 'uploads']:
                subpath = os.path.join(adir, subfolder)
                if not os.path.exists(subpath):
                    os.mkdir(subpath)
            db = os.path.join(adir, 'models/db.py')
            if os.path.exists(db):
                data = fileutils.read_file(db)
                data = data.replace(
                    '<your secret key>', 'sha512:' + web2py_uuid())
                fileutils.write_file(db, data)

    if c:
        import_models = True
    extra_request = {}
    if args:
        extra_request['args'] = args
    if vars:
        extra_request['vars'] = vars
    _env = env(a, c=c, f=f, import_models=import_models, extra_request=extra_request)
    if c:
        pyfile = os.path.join('applications', a, 'controllers', c + '.py')
        pycfile = os.path.join('applications', a, 'compiled',
                                 "controllers_%s_%s.pyc" % (c, f))
        if ((cronjob and os.path.isfile(pycfile))
            or not os.path.isfile(pyfile)):
            exec(read_pyc(pycfile), _env)
        elif os.path.isfile(pyfile):
            execfile(pyfile, _env)
        else:
            die(errmsg)

    if f:
        exec('print %s()' % f, _env)
        return

    _env.update(exec_pythonrc())
    if startfile:
        try:
            ccode = None
            if startfile.endswith('.pyc'):
                ccode = read_pyc(startfile)
                exec(ccode, _env)
            else:
                execfile(startfile, _env)

            if import_models:
                BaseAdapter.close_all_instances('commit')
        except Exception as e:
            print(traceback.format_exc())
            if import_models:
                BaseAdapter.close_all_instances('rollback')
    elif python_code:
        try:
            exec(python_code, _env)
            if import_models:
                BaseAdapter.close_all_instances('commit')
        except Exception as e:
            print(traceback.format_exc())
            if import_models:
                BaseAdapter.close_all_instances('rollback')
    else:
        if not plain:
            if bpython:
                try:
                    import bpython
                    bpython.embed(locals_=_env)
                    return
                except:
                    logger.warning(
                        'import bpython error; trying ipython...')
            else:
                try:
                    import IPython
                    if IPython.__version__ > '1.0.0':
                        IPython.start_ipython(user_ns=_env)
                        return
                    elif IPython.__version__ == '1.0.0':
                        from IPython.terminal.embed import InteractiveShellEmbed
                        shell = InteractiveShellEmbed(user_ns=_env)
                        shell()
                        return
                    elif IPython.__version__ >= '0.11':
                        from IPython.frontend.terminal.embed import InteractiveShellEmbed
                        shell = InteractiveShellEmbed(user_ns=_env)
                        shell()
                        return
                    else:
                        # following 2 lines fix a problem with
                        # IPython; thanks Michael Toomim
                        if '__builtins__' in _env:
                            del _env['__builtins__']
                        shell = IPython.Shell.IPShell(argv=[], user_ns=_env)
                        shell.mainloop()
                        return
                except:
                    logger.warning(
                        'import IPython error; use default python shell')
        enable_autocomplete_and_history(adir, _env)
        code.interact(local=_env)
Example #51
0
def run(appname,
        plain=False,
        import_models=False,
        startfile=None,
        bpython=False,
        python_code=False,
        cronjob=False):
    """
    Start interactive shell or run Python script (startfile) in web2py
    controller environment. appname is formatted like:

    - a : web2py application name
    - a/c : exec the controller c into the application environment
    """

    (a, c, f, args, vars) = parse_path_info(appname, av=True)
    errmsg = 'invalid application name: %s' % appname
    if not a:
        die(errmsg)
    adir = os.path.join('applications', a)

    if not os.path.exists(adir):
        if sys.stdin and not sys.stdin.name == '/dev/null':
            confirm = raw_input(
                'application %s does not exist, create (y/n)?' % a)
        else:
            logging.warn('application does not exist and will not be created')
            return
        if confirm.lower() in ['y', 'yes']:

            os.mkdir(adir)
            w2p_unpack('welcome.w2p', adir)
            for subfolder in [
                    'models', 'views', 'controllers', 'databases', 'modules',
                    'cron', 'errors', 'sessions', 'languages', 'static',
                    'private', 'uploads'
            ]:
                subpath = os.path.join(adir, subfolder)
                if not os.path.exists(subpath):
                    os.mkdir(subpath)
            db = os.path.join(adir, 'models/db.py')
            if os.path.exists(db):
                data = fileutils.read_file(db)
                data = data.replace('<your secret key>',
                                    'sha512:' + web2py_uuid())
                fileutils.write_file(db, data)

    if c:
        import_models = True
    extra_request = {}
    if args:
        extra_request['args'] = args
    if vars:
        extra_request['vars'] = vars
    _env = env(a,
               c=c,
               f=f,
               import_models=import_models,
               extra_request=extra_request)
    if c:
        pyfile = os.path.join('applications', a, 'controllers', c + '.py')
        pycfile = os.path.join('applications', a, 'compiled',
                               "controllers_%s_%s.pyc" % (c, f))
        if ((cronjob and os.path.isfile(pycfile))
                or not os.path.isfile(pyfile)):
            exec(read_pyc(pycfile), _env)
        elif os.path.isfile(pyfile):
            execfile(pyfile, _env)
        else:
            die(errmsg)

    if f:
        exec('print( %s())' % f, _env)
        return

    _env.update(exec_pythonrc())
    if startfile:
        try:
            ccode = None
            if startfile.endswith('.pyc'):
                ccode = read_pyc(startfile)
                exec(ccode, _env)
            else:
                execfile(startfile, _env)

            if import_models:
                BaseAdapter.close_all_instances('commit')
        except Exception as e:
            print(traceback.format_exc())
            if import_models:
                BaseAdapter.close_all_instances('rollback')
    elif python_code:
        try:
            exec(python_code, _env)
            if import_models:
                BaseAdapter.close_all_instances('commit')
        except Exception as e:
            print(traceback.format_exc())
            if import_models:
                BaseAdapter.close_all_instances('rollback')
    else:
        if not plain:
            if bpython:
                try:
                    import bpython
                    bpython.embed(locals_=_env)
                    return
                except:
                    logger.warning('import bpython error; trying ipython...')
            else:
                try:
                    import IPython
                    if IPython.__version__ > '1.0.0':
                        IPython.start_ipython(user_ns=_env)
                        return
                    elif IPython.__version__ == '1.0.0':
                        from IPython.terminal.embed import InteractiveShellEmbed
                        shell = InteractiveShellEmbed(user_ns=_env)
                        shell()
                        return
                    elif IPython.__version__ >= '0.11':
                        from IPython.frontend.terminal.embed import InteractiveShellEmbed
                        shell = InteractiveShellEmbed(user_ns=_env)
                        shell()
                        return
                    else:
                        # following 2 lines fix a problem with
                        # IPython; thanks Michael Toomim
                        if '__builtins__' in _env:
                            del _env['__builtins__']
                        shell = IPython.Shell.IPShell(argv=[], user_ns=_env)
                        shell.mainloop()
                        return
                except:
                    logger.warning(
                        'import IPython error; use default python shell')
        enable_autocomplete_and_history(adir, _env)
        code.interact(local=_env)
Example #52
0
def run(appname, plain=False, import_models=False, startfile=None, bpython=False, python_code=False, cronjob=False):
    """
    Start interactive shell or run Python script (startfile) in web2py
    controller environment. appname is formatted like:

    a      web2py application name
    a/c    exec the controller c into the application environment
    """

    (a, c, f, args, vars) = parse_path_info(appname, av=True)
    errmsg = "invalid application name: %s" % appname
    if not a:
        die(errmsg)
    adir = os.path.join("applications", a)

    if not os.path.exists(adir):
        if sys.stdin and not sys.stdin.name == "/dev/null":
            confirm = raw_input("application %s does not exist, create (y/n)?" % a)
        else:
            logging.warn("application does not exist and will not be created")
            return
        if confirm.lower() in ["y", "yes"]:

            os.mkdir(adir)
            w2p_unpack("welcome.w2p", adir)
            for subfolder in [
                "models",
                "views",
                "controllers",
                "databases",
                "modules",
                "cron",
                "errors",
                "sessions",
                "languages",
                "static",
                "private",
                "uploads",
            ]:
                subpath = os.path.join(adir, subfolder)
                if not os.path.exists(subpath):
                    os.mkdir(subpath)
            db = os.path.join(adir, "models/db.py")
            if os.path.exists(db):
                data = fileutils.read_file(db)
                data = data.replace("<your secret key>", "sha512:" + web2py_uuid())
                fileutils.write_file(db, data)

    if c:
        import_models = True
    extra_request = {}
    if args:
        extra_request["args"] = args
    if vars:
        extra_request["vars"] = vars
    _env = env(a, c=c, f=f, import_models=import_models, extra_request=extra_request)
    if c:
        pyfile = os.path.join("applications", a, "controllers", c + ".py")
        pycfile = os.path.join("applications", a, "compiled", "controllers_%s_%s.pyc" % (c, f))
        if (cronjob and os.path.isfile(pycfile)) or not os.path.isfile(pyfile):
            exec read_pyc(pycfile) in _env
        elif os.path.isfile(pyfile):
            execfile(pyfile, _env)
        else:
            die(errmsg)

    if f:
        exec ("print %s()" % f, _env)
        return

    _env.update(exec_pythonrc())
    if startfile:
        try:
            ccode = None
            if startfile.endswith(".pyc"):
                ccode = read_pyc(startfile)
                exec ccode in _env
            else:
                execfile(startfile, _env)

            if import_models:
                BaseAdapter.close_all_instances("commit")
        except Exception, e:
            print traceback.format_exc()
            if import_models:
                BaseAdapter.close_all_instances("rollback")
Example #53
0
def console():
    """ Defines the behavior of the console web2py execution """
    import optparse
    import textwrap

    usage = "python web2py.py"

    description = """\
    web2py Web Framework startup script.
    ATTENTION: unless a password is specified (-a 'passwd') web2py will
    attempt to run a GUI. In this case command line options are ignored."""

    description = textwrap.dedent(description)

    parser = optparse.OptionParser(usage, None, optparse.Option,
                                   ProgramVersion)

    parser.description = description

    msg = ('IP address of the server (e.g., 127.0.0.1 or ::1); '
           'Note: This value is ignored when using the \'interfaces\' option.')
    parser.add_option('-i', '--ip', default='127.0.0.1', dest='ip', help=msg)

    parser.add_option('-p',
                      '--port',
                      default='8000',
                      dest='port',
                      type='int',
                      help='port of server (8000)')

    parser.add_option(
        '-G',
        '--GAE',
        default=None,
        dest='gae',
        help="'-G configure' will create app.yaml and gaehandler.py")

    msg = ('password to be used for administration '
           '(use -a "<recycle>" to reuse the last password))')
    parser.add_option('-a',
                      '--password',
                      default='<ask>',
                      dest='password',
                      help=msg)

    parser.add_option('-c',
                      '--ssl_certificate',
                      default='',
                      dest='ssl_certificate',
                      help='file that contains ssl certificate')

    parser.add_option('-k',
                      '--ssl_private_key',
                      default='',
                      dest='ssl_private_key',
                      help='file that contains ssl private key')

    msg = ('Use this file containing the CA certificate to validate X509 '
           'certificates from clients')
    parser.add_option('--ca-cert',
                      action='store',
                      dest='ssl_ca_certificate',
                      default=None,
                      help=msg)

    parser.add_option('-d',
                      '--pid_filename',
                      default='httpserver.pid',
                      dest='pid_filename',
                      help='file to store the pid of the server')

    parser.add_option('-l',
                      '--log_filename',
                      default='httpserver.log',
                      dest='log_filename',
                      help='file to log connections')

    parser.add_option('-n',
                      '--numthreads',
                      default=None,
                      type='int',
                      dest='numthreads',
                      help='number of threads (deprecated)')

    parser.add_option('--minthreads',
                      default=None,
                      type='int',
                      dest='minthreads',
                      help='minimum number of server threads')

    parser.add_option('--maxthreads',
                      default=None,
                      type='int',
                      dest='maxthreads',
                      help='maximum number of server threads')

    parser.add_option('-s',
                      '--server_name',
                      default=socket.gethostname(),
                      dest='server_name',
                      help='server name for the web server')

    msg = 'max number of queued requests when server unavailable'
    parser.add_option('-q',
                      '--request_queue_size',
                      default='5',
                      type='int',
                      dest='request_queue_size',
                      help=msg)

    parser.add_option('-o',
                      '--timeout',
                      default='10',
                      type='int',
                      dest='timeout',
                      help='timeout for individual request (10 seconds)')

    parser.add_option('-z',
                      '--shutdown_timeout',
                      default='5',
                      type='int',
                      dest='shutdown_timeout',
                      help='timeout on shutdown of server (5 seconds)')

    parser.add_option('--socket-timeout',
                      default=5,
                      type='int',
                      dest='socket_timeout',
                      help='timeout for socket (5 second)')

    parser.add_option('-f',
                      '--folder',
                      default=os.getcwd(),
                      dest='folder',
                      help='folder from which to run web2py')

    parser.add_option('-v',
                      '--verbose',
                      action='store_true',
                      dest='verbose',
                      default=False,
                      help='increase --test verbosity')

    parser.add_option('-Q',
                      '--quiet',
                      action='store_true',
                      dest='quiet',
                      default=False,
                      help='disable all output')

    parser.add_option('-e',
                      '--errors_to_console',
                      action='store_true',
                      dest='print_errors',
                      default=False,
                      help='log all errors to console')

    msg = ('set debug output level (0-100, 0 means all, 100 means none; '
           'default is 30)')
    parser.add_option('-D',
                      '--debug',
                      dest='debuglevel',
                      default=30,
                      type='int',
                      help=msg)

    msg = ('run web2py in interactive shell or IPython (if installed) with '
           'specified appname (if app does not exist it will be created). '
           'APPNAME like a/c/f (c,f optional)')
    parser.add_option('-S',
                      '--shell',
                      dest='shell',
                      metavar='APPNAME',
                      help=msg)

    msg = ('run web2py in interactive shell or bpython (if installed) with '
           'specified appname (if app does not exist it will be created).\n'
           'Use combined with --shell')
    parser.add_option('-B',
                      '--bpython',
                      action='store_true',
                      default=False,
                      dest='bpython',
                      help=msg)

    msg = 'only use plain python shell; should be used with --shell option'
    parser.add_option('-P',
                      '--plain',
                      action='store_true',
                      default=False,
                      dest='plain',
                      help=msg)

    msg = ('auto import model files; default is False; should be used '
           'with --shell option')
    parser.add_option('-M',
                      '--import_models',
                      action='store_true',
                      default=False,
                      dest='import_models',
                      help=msg)

    msg = ('run PYTHON_FILE in web2py environment; '
           'should be used with --shell option')
    parser.add_option('-R',
                      '--run',
                      dest='run',
                      metavar='PYTHON_FILE',
                      default='',
                      help=msg)

    msg = ('run scheduled tasks for the specified apps: expects a list of '
           'app names as -K app1,app2,app3 '
           'or a list of app:groups as -K app1:group1:group2,app2:group1 '
           'to override specific group_names. (only strings, no spaces '
           'allowed. Requires a scheduler defined in the models')
    parser.add_option('-K',
                      '--scheduler',
                      dest='scheduler',
                      default=None,
                      help=msg)

    msg = 'run schedulers alongside webserver, needs -K app1 and -a too'
    parser.add_option('-X',
                      '--with-scheduler',
                      action='store_true',
                      default=False,
                      dest='with_scheduler',
                      help=msg)

    msg = ('run doctests in web2py environment; '
           'TEST_PATH like a/c/f (c,f optional)')
    parser.add_option('-T',
                      '--test',
                      dest='test',
                      metavar='TEST_PATH',
                      default=None,
                      help=msg)

    msg = 'trigger a cron run manually; usually invoked from a system crontab'
    parser.add_option('-C',
                      '--cron',
                      action='store_true',
                      dest='extcron',
                      default=False,
                      help=msg)

    msg = 'triggers the use of softcron'
    parser.add_option('--softcron',
                      action='store_true',
                      dest='softcron',
                      default=False,
                      help=msg)

    parser.add_option('-Y',
                      '--run-cron',
                      action='store_true',
                      dest='runcron',
                      default=False,
                      help='start the background cron process')

    parser.add_option('-J',
                      '--cronjob',
                      action='store_true',
                      dest='cronjob',
                      default=False,
                      help='identify cron-initiated command')

    parser.add_option('-L',
                      '--config',
                      dest='config',
                      default='',
                      help='config file')

    parser.add_option('-F',
                      '--profiler',
                      dest='profiler_dir',
                      default=None,
                      help='profiler dir')

    parser.add_option('-t',
                      '--taskbar',
                      action='store_true',
                      dest='taskbar',
                      default=False,
                      help='use web2py gui and run in taskbar (system tray)')

    parser.add_option('',
                      '--nogui',
                      action='store_true',
                      default=False,
                      dest='nogui',
                      help='text-only, no GUI')

    msg = ('should be followed by a list of arguments to be passed to script, '
           'to be used with -S, -A must be the last option')
    parser.add_option('-A',
                      '--args',
                      action='store',
                      dest='args',
                      default=None,
                      help=msg)

    parser.add_option('--no-banner',
                      action='store_true',
                      default=False,
                      dest='nobanner',
                      help='Do not print header banner')

    msg = ('listen on multiple addresses: '
           '"ip1:port1:key1:cert1:ca_cert1;ip2:port2:key2:cert2:ca_cert2;..." '
           '(:key:cert:ca_cert optional; no spaces; IPv6 addresses must be in '
           'square [] brackets)')
    parser.add_option('--interfaces',
                      action='store',
                      dest='interfaces',
                      default=None,
                      help=msg)

    msg = 'runs web2py tests'
    parser.add_option('--run_system_tests',
                      action='store_true',
                      dest='run_system_tests',
                      default=False,
                      help=msg)

    msg = ('adds coverage reporting (needs --run_system_tests), '
           'python 2.7 and the coverage module installed. '
           'You can alter the default path setting the environmental '
           'var "COVERAGE_PROCESS_START". '
           'By default it takes gluon/tests/coverage.ini')
    parser.add_option('--with_coverage',
                      action='store_true',
                      dest='with_coverage',
                      default=False,
                      help=msg)

    if '-A' in sys.argv:
        k = sys.argv.index('-A')
    elif '--args' in sys.argv:
        k = sys.argv.index('--args')
    else:
        k = len(sys.argv)
    sys.argv, other_args = sys.argv[:k], sys.argv[k + 1:]
    (options, args) = parser.parse_args()
    options.args = [options.run] + other_args

    copy_options = copy.deepcopy(options)
    copy_options.password = '******'
    global_settings.cmd_options = copy_options
    global_settings.cmd_args = args

    if options.gae:
        if not os.path.exists('app.yaml'):
            name = raw_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:
        options.ips = list(
            set(  # no duplicates
                [
                    addrinfo[4][0]
                    for addrinfo in getipaddrinfo(socket.getfqdn())
                    if not is_loopback_ip_address(addrinfo=addrinfo)
                ]))
    except socket.gaierror:
        options.ips = []

    if options.run_system_tests:
        run_system_tests(options)

    if options.quiet:
        capture = StringIO()
        sys.stdout = capture
        logger.setLevel(logging.CRITICAL + 1)
    else:
        logger.setLevel(options.debuglevel)

    if options.config[-3:] == '.py':
        options.config = options.config[:-3]

    if options.cronjob:
        global_settings.cronjob = True  # tell the world
        options.plain = True  # cronjobs use a plain shell
        options.nobanner = True
        options.nogui = True

    options.folder = os.path.abspath(options.folder)

    #  accept --interfaces in the form
    #  "ip1:port1:key1:cert1:ca_cert1;[ip2]:port2;ip3:port3:key3:cert3"
    #  (no spaces; optional key:cert indicate SSL)
    if isinstance(options.interfaces, str):
        interfaces = options.interfaces.split(';')
        options.interfaces = []
        for interface in interfaces:
            if interface.startswith('['):  # IPv6
                ip, if_remainder = interface.split(']', 1)
                ip = ip[1:]
                if_remainder = if_remainder[1:].split(':')
                if_remainder[0] = int(if_remainder[0])  # numeric port
                options.interfaces.append(tuple([ip] + if_remainder))
            else:  # IPv4
                interface = interface.split(':')
                interface[1] = int(interface[1])  # numeric port
                options.interfaces.append(tuple(interface))

    #  accepts --scheduler in the form
    #  "app:group1,group2,app2:group1"
    scheduler = []
    options.scheduler_groups = None
    if isinstance(options.scheduler, str):
        if ':' in options.scheduler:
            for opt in options.scheduler.split(','):
                scheduler.append(opt.split(':'))
            options.scheduler = ','.join([app[0] for app in scheduler])
            options.scheduler_groups = scheduler

    if options.numthreads is not None and options.minthreads is None:
        options.minthreads = options.numthreads  # legacy

    create_welcome_w2p()

    if not options.cronjob:
        # 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
Example #54
0
def console():
    """ Defines the behavior of the console web2py execution """
    import optparse
    import textwrap

    usage = "python web2py.py"

    description = """\
    web2py Web Framework startup script.
    ATTENTION: unless a password is specified (-a 'passwd') web2py will
    attempt to run a GUI. In this case command line options are ignored."""

    description = textwrap.dedent(description)

    parser = optparse.OptionParser(
        usage, None, optparse.Option, ProgramVersion)

    parser.description = description

    msg = ('IP address of the server (e.g., 127.0.0.1 or ::1); '
           'Note: This value is ignored when using the \'interfaces\' option.')
    parser.add_option('-i',
                      '--ip',
                      default='127.0.0.1',
                      dest='ip',
                      help=msg)

    parser.add_option('-p',
                      '--port',
                      default='8000',
                      dest='port',
                      type='int',
                      help='port of server (8000)')

    msg = ('password to be used for administration '
           '(use -a "<recycle>" to reuse the last password))')
    parser.add_option('-a',
                      '--password',
                      default='<ask>',
                      dest='password',
                      help=msg)

    parser.add_option('-c',
                      '--ssl_certificate',
                      default='',
                      dest='ssl_certificate',
                      help='file that contains ssl certificate')

    parser.add_option('-k',
                      '--ssl_private_key',
                      default='',
                      dest='ssl_private_key',
                      help='file that contains ssl private key')

    msg = ('Use this file containing the CA certificate to validate X509 '
           'certificates from clients')
    parser.add_option('--ca-cert',
                      action='store',
                      dest='ssl_ca_certificate',
                      default=None,
                      help=msg)

    parser.add_option('-d',
                      '--pid_filename',
                      default='httpserver.pid',
                      dest='pid_filename',
                      help='file to store the pid of the server')

    parser.add_option('-l',
                      '--log_filename',
                      default='httpserver.log',
                      dest='log_filename',
                      help='file to log connections')

    parser.add_option('-n',
                      '--numthreads',
                      default=None,
                      type='int',
                      dest='numthreads',
                      help='number of threads (deprecated)')

    parser.add_option('--minthreads',
                      default=None,
                      type='int',
                      dest='minthreads',
                      help='minimum number of server threads')

    parser.add_option('--maxthreads',
                      default=None,
                      type='int',
                      dest='maxthreads',
                      help='maximum number of server threads')

    parser.add_option('-s',
                      '--server_name',
                      default=socket.gethostname(),
                      dest='server_name',
                      help='server name for the web server')

    msg = 'max number of queued requests when server unavailable'
    parser.add_option('-q',
                      '--request_queue_size',
                      default='5',
                      type='int',
                      dest='request_queue_size',
                      help=msg)

    parser.add_option('-o',
                      '--timeout',
                      default='10',
                      type='int',
                      dest='timeout',
                      help='timeout for individual request (10 seconds)')

    parser.add_option('-z',
                      '--shutdown_timeout',
                      default='5',
                      type='int',
                      dest='shutdown_timeout',
                      help='timeout on shutdown of server (5 seconds)')

    parser.add_option('--socket-timeout',
                      default=5,
                      type='int',
                      dest='socket_timeout',
                      help='timeout for socket (5 second)')

    parser.add_option('-f',
                      '--folder',
                      default=os.getcwd(),
                      dest='folder',
                      help='folder from which to run web2py')

    parser.add_option('-v',
                      '--verbose',
                      action='store_true',
                      dest='verbose',
                      default=False,
                      help='increase --test verbosity')

    parser.add_option('-Q',
                      '--quiet',
                      action='store_true',
                      dest='quiet',
                      default=False,
                      help='disable all output')

    msg = ('set debug output level (0-100, 0 means all, 100 means none; '
           'default is 30)')
    parser.add_option('-D',
                      '--debug',
                      dest='debuglevel',
                      default=30,
                      type='int',
                      help=msg)

    msg = ('run web2py in interactive shell or IPython (if installed) with '
           'specified appname (if app does not exist it will be created). '
           'APPNAME like a/c/f (c,f optional)')
    parser.add_option('-S',
                      '--shell',
                      dest='shell',
                      metavar='APPNAME',
                      help=msg)

    msg = ('run web2py in interactive shell or bpython (if installed) with '
           'specified appname (if app does not exist it will be created).\n'
           'Use combined with --shell')
    parser.add_option('-B',
                      '--bpython',
                      action='store_true',
                      default=False,
                      dest='bpython',
                      help=msg)

    msg = 'only use plain python shell; should be used with --shell option'
    parser.add_option('-P',
                      '--plain',
                      action='store_true',
                      default=False,
                      dest='plain',
                      help=msg)

    msg = ('auto import model files; default is False; should be used '
           'with --shell option')
    parser.add_option('-M',
                      '--import_models',
                      action='store_true',
                      default=False,
                      dest='import_models',
                      help=msg)

    msg = ('run PYTHON_FILE in web2py environment; '
           'should be used with --shell option')
    parser.add_option('-R',
                      '--run',
                      dest='run',
                      metavar='PYTHON_FILE',
                      default='',
                      help=msg)

    msg = ('run scheduled tasks for the specified apps: expects a list of '
           'app names as -K app1,app2,app3 '
           'or a list of app:groups as -K app1:group1:group2,app2:group1 '
           'to override specific group_names. (only strings, no spaces '
           'allowed. Requires a scheduler defined in the models')
    parser.add_option('-K',
                      '--scheduler',
                      dest='scheduler',
                      default=None,
                      help=msg)

    msg = 'run schedulers alongside webserver, needs -K app1 and -a too'
    parser.add_option('-X',
                      '--with-scheduler',
                      action='store_true',
                      default=False,
                      dest='with_scheduler',
                      help=msg)

    msg = ('run doctests in web2py environment; '
           'TEST_PATH like a/c/f (c,f optional)')
    parser.add_option('-T',
                      '--test',
                      dest='test',
                      metavar='TEST_PATH',
                      default=None,
                      help=msg)

    parser.add_option('-W',
                      '--winservice',
                      dest='winservice',
                      default='',
                      help='-W install|start|stop as Windows service')

    msg = 'trigger a cron run manually; usually invoked from a system crontab'
    parser.add_option('-C',
                      '--cron',
                      action='store_true',
                      dest='extcron',
                      default=False,
                      help=msg)

    msg = 'triggers the use of softcron'
    parser.add_option('--softcron',
                      action='store_true',
                      dest='softcron',
                      default=False,
                      help=msg)

    parser.add_option('-Y',
                      '--run-cron',
                      action='store_true',
                      dest='runcron',
                      default=False,
                      help='start the background cron process')

    parser.add_option('-J',
                      '--cronjob',
                      action='store_true',
                      dest='cronjob',
                      default=False,
                      help='identify cron-initiated command')

    parser.add_option('-L',
                      '--config',
                      dest='config',
                      default='',
                      help='config file')

    parser.add_option('-F',
                      '--profiler',
                      dest='profiler_dir',
                      default=None,
                      help='profiler dir')

    parser.add_option('-t',
                      '--taskbar',
                      action='store_true',
                      dest='taskbar',
                      default=False,
                      help='use web2py gui and run in taskbar (system tray)')

    parser.add_option('',
                      '--nogui',
                      action='store_true',
                      default=False,
                      dest='nogui',
                      help='text-only, no GUI')

    msg = ('should be followed by a list of arguments to be passed to script, '
           'to be used with -S, -A must be the last option')
    parser.add_option('-A',
                      '--args',
                      action='store',
                      dest='args',
                      default=None,
                      help=msg)

    parser.add_option('--no-banner',
                      action='store_true',
                      default=False,
                      dest='nobanner',
                      help='Do not print header banner')

    msg = ('listen on multiple addresses: '
           '"ip1:port1:key1:cert1:ca_cert1;ip2:port2:key2:cert2:ca_cert2;..." '
           '(:key:cert:ca_cert optional; no spaces; IPv6 addresses must be in '
           'square [] brackets)')
    parser.add_option('--interfaces',
                      action='store',
                      dest='interfaces',
                      default=None,
                      help=msg)

    msg = 'runs web2py tests'
    parser.add_option('--run_system_tests',
                      action='store_true',
                      dest='run_system_tests',
                      default=False,
                      help=msg)

    msg = ('adds coverage reporting (needs --run_system_tests), '
           'python 2.7 and the coverage module installed. '
           'You can alter the default path setting the environmental '
           'var "COVERAGE_PROCESS_START". '
           'By default it takes gluon/tests/coverage.ini')
    parser.add_option('--with_coverage',
                      action='store_true',
                      dest='with_coverage',
                      default=False,
                      help=msg)

    if '-A' in sys.argv:
        k = sys.argv.index('-A')
    elif '--args' in sys.argv:
        k = sys.argv.index('--args')
    else:
        k = len(sys.argv)
    sys.argv, other_args = sys.argv[:k], sys.argv[k + 1:]
    (options, args) = parser.parse_args()
    options.args = [options.run] + other_args
    global_settings.cmd_options = options
    global_settings.cmd_args = args

    try:
        options.ips = list(set( # no duplicates
            [addrinfo[4][0] for addrinfo in getipaddrinfo(socket.getfqdn())
             if not is_loopback_ip_address(addrinfo=addrinfo)]))
    except socket.gaierror:
        options.ips = []

    if options.run_system_tests:
        run_system_tests(options)

    if options.quiet:
        capture = cStringIO.StringIO()
        sys.stdout = capture
        logger.setLevel(logging.CRITICAL + 1)
    else:
        logger.setLevel(options.debuglevel)

    if options.config[-3:] == '.py':
        options.config = options.config[:-3]

    if options.cronjob:
        global_settings.cronjob = True  # tell the world
        options.plain = True    # cronjobs use a plain shell
        options.nobanner = True
        options.nogui = True

    options.folder = os.path.abspath(options.folder)

    #  accept --interfaces in the form
    #  "ip1:port1:key1:cert1:ca_cert1;[ip2]:port2;ip3:port3:key3:cert3"
    #  (no spaces; optional key:cert indicate SSL)
    if isinstance(options.interfaces, str):
        interfaces = options.interfaces.split(';')
        options.interfaces = []
        for interface in interfaces:
            if interface.startswith('['):  # IPv6
                ip, if_remainder = interface.split(']', 1)
                ip = ip[1:]
                if_remainder = if_remainder[1:].split(':')
                if_remainder[0] = int(if_remainder[0])  # numeric port
                options.interfaces.append(tuple([ip] + if_remainder))
            else:  # IPv4
                interface = interface.split(':')
                interface[1] = int(interface[1])  # numeric port
                options.interfaces.append(tuple(interface))

    #  accepts --scheduler in the form
    #  "app:group1,group2,app2:group1"
    scheduler = []
    options.scheduler_groups = None
    if isinstance(options.scheduler, str):
        if ':' in options.scheduler:
            for opt in options.scheduler.split(','):
                scheduler.append(opt.split(':'))
            options.scheduler = ','.join([app[0] for app in scheduler])
            options.scheduler_groups = scheduler

    if options.numthreads is not None and options.minthreads is None:
        options.minthreads = options.numthreads  # legacy

    create_welcome_w2p()

    if not options.cronjob:
        # 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