MobileBlur

autoroutes.py at [dea6297b3d]
Login

File scripts/autoroutes.py artifact 6bf50cb4ff part of check-in dea6297b3d


#!/usr/bin/python
# -*- coding: utf-8 -*-
'''
autoroutes writes routes for you based on a simpler routing
configuration file called routes.conf. Example:

----- BEGIN routes.conf-------
127.0.0.1   /examples/default
domain1.com /app1/default
domain2.com /app2/default
domain3.com /app3/default
----- END ----------

It maps a domain (the left-hand side) to an app (one app per domain),
and shortens the URLs for the app by removing the listed path prefix. That means:

http://domain1.com/index is mapped to /app1/default/index
http://domain2.com/index is mapped to /app2/default/index

It preserves admin, appadmin, static files, favicon.ico and robots.txt:

http://domain1.com/favicon.ico  /welcome/static/favicon.ico
http://domain1.com/robots.txt   /welcome/static/robots.txt
http://domain1.com/admin/...    /admin/...
http://domain1.com/appadmin/... /app1/appadmin/...
http://domain1.com/static/...   /app1/static/...

and vice-versa.

To use, cp scripts/autoroutes.py routes.py

and either edit the config string below, or set config = "" and edit routes.conf
'''

config = '''
127.0.0.1   /examples/default
domain1.com /app1/default
domain2.com /app2/default
domain3.com /app3/defcon3
'''
if not config.strip():
    try:
        config_file = open('routes.conf','r')
        try:
            config = config_file.read()
        finally:
            config_file.close()
    except:
        config=''

def auto_in(apps):
    routes = [
        ('/robots.txt','/welcome/static/robots.txt'),
        ('/favicon.ico','/welcome/static/favicon.ico'),
        ('/admin$anything','/admin$anything'),
        ]
    for domain,path in [x.strip().split() for x in apps.split('\n') if x.strip() and not x.strip().startswith('#')]:
        if not path.startswith('/'): path = '/'+path
        if path.endswith('/'): path = path[:-1]
        app = path.split('/')[1]
        routes += [
            ('.*:https?://(.*\.)?%s:$method /' % domain,'%s' % path),
            ('.*:https?://(.*\.)?%s:$method /static/$anything' % domain,'/%s/static/$anything' % app),
            ('.*:https?://(.*\.)?%s:$method /appadmin/$anything' % domain,'/%s/appadmin/$anything' % app),
            ('.*:https?://(.*\.)?%s:$method /$anything' % domain,'%s/$anything' % path),
            ]
    return routes

def auto_out(apps):
    routes = []
    for domain,path in [x.strip().split() for x in apps.split('\n') if x.strip() and not x.strip().startswith('#')]:
        if not path.startswith('/'): path = '/'+path
        if path.endswith('/'): path = path[:-1]
        app = path.split('/')[1]
        routes += [
            ('/%s/static/$anything' % app,'/static/$anything'),
            ('/%s/appadmin/$anything' % app, '/appadmin/$anything'),
            ('%s/$anything' % path, '/$anything'),
            ]
    return routes

routes_in = auto_in(config)
routes_out = auto_out(config)

def __routes_doctest():
    '''
    Dummy function for doctesting autoroutes.py.

    Use filter_url() to test incoming or outgoing routes;
    filter_err() for error redirection.

    filter_url() accepts overrides for method and remote host:
        filter_url(url, method='get', remote='0.0.0.0', out=False)

    filter_err() accepts overrides for application and ticket:
        filter_err(status, application='app', ticket='tkt')

    >>> filter_url('http://domain1.com/favicon.ico')
    'http://domain1.com/welcome/static/favicon.ico'
    >>> filter_url('https://domain2.com/robots.txt')
    'https://domain2.com/welcome/static/robots.txt'
    >>> filter_url('http://domain3.com/fcn')
    'http://domain3.com/app3/defcon3/fcn'
    >>> filter_url('http://127.0.0.1/fcn')
    'http://127.0.0.1/examples/default/fcn'
    >>> filter_url('HTTP://DOMAIN.COM/app/ctr/fcn')
    'http://domain.com/app/ctr/fcn'
    >>> filter_url('http://domain.com/app/ctr/fcn?query')
    'http://domain.com/app/ctr/fcn?query'
    >>> filter_url('http://otherdomain.com/fcn')
    'http://otherdomain.com/fcn'
    >>> regex_filter_out('/app/ctr/fcn')
    '/app/ctr/fcn'
    >>> regex_filter_out('/app1/ctr/fcn')
    '/app1/ctr/fcn'
    >>> filter_url('https://otherdomain.com/app1/default/fcn', out=True)
    '/fcn'
    >>> filter_url('http://otherdomain.com/app2/ctr/fcn', out=True)
    '/app2/ctr/fcn'
    >>> filter_url('http://domain1.com/app1/default/fcn?query', out=True)
    '/fcn?query'
    >>> filter_url('http://domain2.com/app3/defcon3/fcn#anchor', out=True)
    '/fcn#anchor'
    '''
    pass

if __name__ == '__main__':
    try:
        import gluon.main
    except ImportError:
        import sys, os
        os.chdir(os.path.dirname(os.path.dirname(__file__)))
        sys.path.append(os.path.dirname(os.path.dirname(__file__)))
        import gluon.main
    from gluon.rewrite import regex_select, load, filter_url, regex_filter_out
    regex_select()          # use base routing parameters
    load(routes=__file__)   # load this file

    import doctest
    doctest.testmod()