SP/web2py/scripts/autoroutes.py

151 lines
4.9 KiB
Python
Raw Normal View History

2018-10-25 15:33:07 +00:00
# -*- 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
import 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()