autoroutes.py 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. # -*- coding: utf-8 -*-
  2. '''
  3. autoroutes writes routes for you based on a simpler routing
  4. configuration file called routes.conf. Example:
  5. ----- BEGIN routes.conf-------
  6. 127.0.0.1 /examples/default
  7. domain1.com /app1/default
  8. domain2.com /app2/default
  9. domain3.com /app3/default
  10. ----- END ----------
  11. It maps a domain (the left-hand side) to an app (one app per domain),
  12. and shortens the URLs for the app by removing the listed path prefix. That means:
  13. http://domain1.com/index is mapped to /app1/default/index
  14. http://domain2.com/index is mapped to /app2/default/index
  15. It preserves admin, appadmin, static files, favicon.ico and robots.txt:
  16. http://domain1.com/favicon.ico /welcome/static/favicon.ico
  17. http://domain1.com/robots.txt /welcome/static/robots.txt
  18. http://domain1.com/admin/... /admin/...
  19. http://domain1.com/appadmin/... /app1/appadmin/...
  20. http://domain1.com/static/... /app1/static/...
  21. and vice-versa.
  22. To use, cp scripts/autoroutes.py routes.py
  23. and either edit the config string below, or set config = "" and edit routes.conf
  24. '''
  25. config = '''
  26. 127.0.0.1 /examples/default
  27. domain1.com /app1/default
  28. domain2.com /app2/default
  29. domain3.com /app3/defcon3
  30. '''
  31. if not config.strip():
  32. try:
  33. config_file = open('routes.conf', 'r')
  34. try:
  35. config = config_file.read()
  36. finally:
  37. config_file.close()
  38. except:
  39. config = ''
  40. def auto_in(apps):
  41. routes = [
  42. ('/robots.txt', '/welcome/static/robots.txt'),
  43. ('/favicon.ico', '/welcome/static/favicon.ico'),
  44. ('/admin$anything', '/admin$anything'),
  45. ]
  46. for domain, path in [x.strip().split() for x in apps.split('\n') if x.strip() and not x.strip().startswith('#')]:
  47. if not path.startswith('/'):
  48. path = '/' + path
  49. if path.endswith('/'):
  50. path = path[:-1]
  51. app = path.split('/')[1]
  52. routes += [
  53. ('.*:https?://(.*\.)?%s:$method /' % domain, '%s' % path),
  54. ('.*:https?://(.*\.)?%s:$method /static/$anything' %
  55. domain, '/%s/static/$anything' % app),
  56. ('.*:https?://(.*\.)?%s:$method /appadmin/$anything' %
  57. domain, '/%s/appadmin/$anything' % app),
  58. ('.*:https?://(.*\.)?%s:$method /$anything' %
  59. domain, '%s/$anything' % path),
  60. ]
  61. return routes
  62. def auto_out(apps):
  63. routes = []
  64. for domain, path in [x.strip().split() for x in apps.split('\n') if x.strip() and not x.strip().startswith('#')]:
  65. if not path.startswith('/'):
  66. path = '/' + path
  67. if path.endswith('/'):
  68. path = path[:-1]
  69. app = path.split('/')[1]
  70. routes += [
  71. ('/%s/static/$anything' % app, '/static/$anything'),
  72. ('/%s/appadmin/$anything' % app, '/appadmin/$anything'),
  73. ('%s/$anything' % path, '/$anything'),
  74. ]
  75. return routes
  76. routes_in = auto_in(config)
  77. routes_out = auto_out(config)
  78. def __routes_doctest():
  79. '''
  80. Dummy function for doctesting autoroutes.py.
  81. Use filter_url() to test incoming or outgoing routes;
  82. filter_err() for error redirection.
  83. filter_url() accepts overrides for method and remote host:
  84. filter_url(url, method='get', remote='0.0.0.0', out=False)
  85. filter_err() accepts overrides for application and ticket:
  86. filter_err(status, application='app', ticket='tkt')
  87. >>> filter_url('http://domain1.com/favicon.ico')
  88. 'http://domain1.com/welcome/static/favicon.ico'
  89. >>> filter_url('https://domain2.com/robots.txt')
  90. 'https://domain2.com/welcome/static/robots.txt'
  91. >>> filter_url('http://domain3.com/fcn')
  92. 'http://domain3.com/app3/defcon3/fcn'
  93. >>> filter_url('http://127.0.0.1/fcn')
  94. 'http://127.0.0.1/examples/default/fcn'
  95. >>> filter_url('HTTP://DOMAIN.COM/app/ctr/fcn')
  96. 'http://domain.com/app/ctr/fcn'
  97. >>> filter_url('http://domain.com/app/ctr/fcn?query')
  98. 'http://domain.com/app/ctr/fcn?query'
  99. >>> filter_url('http://otherdomain.com/fcn')
  100. 'http://otherdomain.com/fcn'
  101. >>> regex_filter_out('/app/ctr/fcn')
  102. '/app/ctr/fcn'
  103. >>> regex_filter_out('/app1/ctr/fcn')
  104. '/app1/ctr/fcn'
  105. >>> filter_url('https://otherdomain.com/app1/default/fcn', out=True)
  106. '/fcn'
  107. >>> filter_url('http://otherdomain.com/app2/ctr/fcn', out=True)
  108. '/app2/ctr/fcn'
  109. >>> filter_url('http://domain1.com/app1/default/fcn?query', out=True)
  110. '/fcn?query'
  111. >>> filter_url('http://domain2.com/app3/defcon3/fcn#anchor', out=True)
  112. '/fcn#anchor'
  113. '''
  114. pass
  115. if __name__ == '__main__':
  116. try:
  117. import gluon.main
  118. except ImportError:
  119. import sys
  120. import os
  121. os.chdir(os.path.dirname(os.path.dirname(__file__)))
  122. sys.path.append(os.path.dirname(os.path.dirname(__file__)))
  123. import gluon.main
  124. from gluon.rewrite import regex_select, load, filter_url, regex_filter_out
  125. regex_select() # use base routing parameters
  126. load(routes=__file__) # load this file
  127. import doctest
  128. doctest.testmod()