︙ | | | ︙ | |
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
|
"return new copy of default base router"
router = Storage(
default_application = 'init',
applications = 'ALL',
default_controller = 'default',
controllers = 'DEFAULT',
default_function = 'index',
functions = None,
default_language = None,
languages = None,
root_static = ['favicon.ico', 'robots.txt'],
domains = None,
exclusive_domain = False,
map_hyphen = False,
acfe_match = r'\w+$', # legal app/ctlr/fcn/ext
|
|
|
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
|
"return new copy of default base router"
router = Storage(
default_application = 'init',
applications = 'ALL',
default_controller = 'default',
controllers = 'DEFAULT',
default_function = 'index',
functions = dict(),
default_language = None,
languages = None,
root_static = ['favicon.ico', 'robots.txt'],
domains = None,
exclusive_domain = False,
map_hyphen = False,
acfe_match = r'\w+$', # legal app/ctlr/fcn/ext
|
︙ | | | ︙ | |
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
|
for key in router.keys():
if key not in ROUTER_KEYS:
raise SyntaxError, "unknown key '%s' in router '%s'" % (key, app)
if not router.controllers:
router.controllers = set()
elif not isinstance(router.controllers, str):
router.controllers = set(router.controllers)
if router.functions:
router.functions = set(router.functions)
else:
router.functions = set()
if router.languages:
router.languages = set(router.languages)
else:
router.languages = set()
if app != 'BASE':
for base_only in ROUTER_BASE_KEYS:
router.pop(base_only, None)
if 'domain' in router:
routers.BASE.domains[router.domain] = app
if isinstance(router.controllers, str) and router.controllers == 'DEFAULT':
router.controllers = set()
if os.path.isdir(abspath('applications', app)):
cpath = abspath('applications', app, 'controllers')
for cname in os.listdir(cpath):
if os.path.isfile(abspath(cpath, cname)) and cname.endswith('.py'):
router.controllers.add(cname[:-3])
if router.controllers:
router.controllers.add('static')
router.controllers.add(router.default_controller)
if router.functions:
router.functions.add(router.default_function)
if isinstance(routers.BASE.applications, str) and routers.BASE.applications == 'ALL':
routers.BASE.applications = list(all_apps)
if routers.BASE.applications:
routers.BASE.applications = set(routers.BASE.applications)
else:
routers.BASE.applications = set()
|
<
<
<
<
>
>
>
|
>
>
>
>
>
|
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
|
for key in router.keys():
if key not in ROUTER_KEYS:
raise SyntaxError, "unknown key '%s' in router '%s'" % (key, app)
if not router.controllers:
router.controllers = set()
elif not isinstance(router.controllers, str):
router.controllers = set(router.controllers)
if router.languages:
router.languages = set(router.languages)
else:
router.languages = set()
if app != 'BASE':
for base_only in ROUTER_BASE_KEYS:
router.pop(base_only, None)
if 'domain' in router:
routers.BASE.domains[router.domain] = app
if isinstance(router.controllers, str) and router.controllers == 'DEFAULT':
router.controllers = set()
if os.path.isdir(abspath('applications', app)):
cpath = abspath('applications', app, 'controllers')
for cname in os.listdir(cpath):
if os.path.isfile(abspath(cpath, cname)) and cname.endswith('.py'):
router.controllers.add(cname[:-3])
if router.controllers:
router.controllers.add('static')
router.controllers.add(router.default_controller)
if router.functions:
if isinstance(router.functions, (set, tuple, list)):
functions = set(router.functions)
if isinstance(router.default_function, str):
functions.add(router.default_function) # legacy compatibility
router.functions = { router.default_controller: functions }
for controller in router.functions:
router.functions[controller] = set(router.functions[controller])
else:
router.functions = dict()
if isinstance(routers.BASE.applications, str) and routers.BASE.applications == 'ALL':
routers.BASE.applications = list(all_apps)
if routers.BASE.applications:
routers.BASE.applications = set(routers.BASE.applications)
else:
routers.BASE.applications = set()
|
︙ | | | ︙ | |
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
|
domains = dict()
if routers.BASE.domains:
for (domain, app) in [(d.strip(':'), a.strip('/')) for (d, a) in routers.BASE.domains.items()]:
port = None
if ':' in domain:
(domain, port) = domain.split(':')
ctlr = None
if '/' in app:
(app, ctlr) = app.split('/')
if app not in all_apps and app not in routers:
raise SyntaxError, "unknown app '%s' in domains" % app
domains[(domain, port)] = (app, ctlr)
routers.BASE.domains = domains
def regex_uri(e, regexes, tag, default=None):
"filter incoming URI against a list of regexes"
path = e['PATH_INFO']
host = e.get('HTTP_HOST', 'localhost').lower()
i = host.find(':')
|
>
|
>
>
|
|
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
|
domains = dict()
if routers.BASE.domains:
for (domain, app) in [(d.strip(':'), a.strip('/')) for (d, a) in routers.BASE.domains.items()]:
port = None
if ':' in domain:
(domain, port) = domain.split(':')
ctlr = None
fcn = None
if '/' in app:
(app, ctlr) = app.split('/', 1)
if ctlr and '/' in ctlr:
(ctlr, fcn) = ctlr.split('/')
if app not in all_apps and app not in routers:
raise SyntaxError, "unknown app '%s' in domains" % app
domains[(domain, port)] = (app, ctlr, fcn)
routers.BASE.domains = domains
def regex_uri(e, regexes, tag, default=None):
"filter incoming URI against a list of regexes"
path = e['PATH_INFO']
host = e.get('HTTP_HOST', 'localhost').lower()
i = host.find(':')
|
︙ | | | ︙ | |
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
|
self.application = None
self.language = None
self.controller = None
self.function = None
self.extension = 'html'
self.controllers = set()
self.functions = set()
self.languages = set()
self.default_language = None
self.map_hyphen = False
self.exclusive_domain = False
path = self.env['PATH_INFO']
self.query = self.env.get('QUERY_STRING', None)
|
|
|
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
|
self.application = None
self.language = None
self.controller = None
self.function = None
self.extension = 'html'
self.controllers = set()
self.functions = dict()
self.languages = set()
self.default_language = None
self.map_hyphen = False
self.exclusive_domain = False
path = self.env['PATH_INFO']
self.query = self.env.get('QUERY_STRING', None)
|
︙ | | | ︙ | |
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
|
self.args = List(self.args[prefixlen:]) # strip the prefix
def map_app(self):
"determine application name"
base = routers.BASE # base router
self.domain_application = None
self.domain_controller = None
arg0 = self.harg0
if base.applications and arg0 in base.applications:
self.application = arg0
elif (self.host, self.port) in base.domains:
(self.application, self.domain_controller) = base.domains[(self.host, self.port)]
self.env['domain_application'] = self.application
self.env['domain_controller'] = self.domain_controller
elif (self.host, None) in base.domains:
(self.application, self.domain_controller) = base.domains[(self.host, None)]
self.env['domain_application'] = self.application
self.env['domain_controller'] = self.domain_controller
elif arg0 and not base.applications:
self.application = arg0
else:
self.application = base.default_application or ''
self.pop_arg_if(self.application == arg0)
if not base._acfe_match.match(self.application):
|
>
<
<
|
|
>
|
>
>
>
|
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
|
self.args = List(self.args[prefixlen:]) # strip the prefix
def map_app(self):
"determine application name"
base = routers.BASE # base router
self.domain_application = None
self.domain_controller = None
self.domain_function = None
arg0 = self.harg0
if (self.host, self.port) in base.domains:
(self.application, self.domain_controller, self.domain_function) = base.domains[(self.host, self.port)]
self.env['domain_application'] = self.application
self.env['domain_controller'] = self.domain_controller
self.env['domain_function'] = self.domain_function
elif (self.host, None) in base.domains:
(self.application, self.domain_controller, self.domain_function) = base.domains[(self.host, None)]
self.env['domain_application'] = self.application
self.env['domain_controller'] = self.domain_controller
self.env['domain_function'] = self.domain_function
elif base.applications and arg0 in base.applications:
self.application = arg0
elif arg0 and not base.applications:
self.application = arg0
else:
self.application = base.default_application or ''
self.pop_arg_if(self.application == arg0)
if not base._acfe_match.match(self.application):
|
︙ | | | ︙ | |
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
|
'static', file)
logger.debug("route: static=%s" % static_file)
return static_file
def map_function(self):
"handle function.extension"
arg0 = self.harg0 # map hyphens
if not arg0 or self.functions and arg0 not in self.functions and self.controller == self.default_controller:
self.function = self.router.default_function or ""
self.pop_arg_if(arg0 and self.function == arg0)
else:
func_ext = arg0.split('.')
if len(func_ext) > 1:
self.function = func_ext[0]
self.extension = func_ext[-1]
else:
|
|
>
>
>
|
>
>
>
|
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
|
'static', file)
logger.debug("route: static=%s" % static_file)
return static_file
def map_function(self):
"handle function.extension"
arg0 = self.harg0 # map hyphens
functions = self.functions.get(self.controller, set())
if isinstance(self.router.default_function, dict):
default_function = self.router.default_function.get(self.controller, None)
else:
default_function = self.router.default_function # str or None
default_function = self.domain_function or default_function
if not arg0 or functions and arg0 not in functions:
self.function = default_function or ""
self.pop_arg_if(arg0 and self.function == arg0)
else:
func_ext = arg0.split('.')
if len(func_ext) > 1:
self.function = func_ext[0]
self.extension = func_ext[-1]
else:
|
︙ | | | ︙ | |
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
|
self.other = other
self.scheme = scheme
self.host = host
self.port = port
self.applications = routers.BASE.applications
self.controllers = self.router.controllers
self.functions = self.router.functions
self.languages = self.router.languages
self.default_language = self.router.default_language
self.exclusive_domain = self.router.exclusive_domain
self.map_hyphen = self.router.map_hyphen
self.map_static = self.router.map_static
self.path_prefix = routers.BASE.path_prefix
self.domain_application = request and self.request.env.domain_application
self.domain_controller = request and self.request.env.domain_controller
self.default_function = self.router.default_function
if (self.router.exclusive_domain and self.domain_application and self.domain_application != self.application and not self.host):
raise SyntaxError, 'cross-domain conflict: must specify host'
lang = request and request.uri_language
if lang and self.languages and lang in self.languages:
self.language = lang
|
|
>
>
>
|
|
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
|
self.other = other
self.scheme = scheme
self.host = host
self.port = port
self.applications = routers.BASE.applications
self.controllers = self.router.controllers
self.functions = self.router.functions.get(self.controller, set())
self.languages = self.router.languages
self.default_language = self.router.default_language
self.exclusive_domain = self.router.exclusive_domain
self.map_hyphen = self.router.map_hyphen
self.map_static = self.router.map_static
self.path_prefix = routers.BASE.path_prefix
self.domain_application = request and self.request.env.domain_application
self.domain_controller = request and self.request.env.domain_controller
if isinstance(self.router.default_function, dict):
self.default_function = self.router.default_function.get(self.controller, None)
else:
self.default_function = self.router.default_function
if (self.router.exclusive_domain and self.domain_application and self.domain_application != self.application and not self.host):
raise SyntaxError, 'cross-domain conflict: must specify host'
lang = request and request.uri_language
if lang and self.languages and lang in self.languages:
self.language = lang
|
︙ | | | ︙ | |
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
|
def omit_acf(self):
"omit what we can of a/c/f"
router = self.router
# Handle the easy no-args case of tail-defaults: /a/c /a /
#
if not self.args and self.function == router.default_function:
self.omit_function = True
if self.controller == router.default_controller:
self.omit_controller = True
if self.application == self.default_application:
self.omit_application = True
# omit default application
# (which might be the domain default application)
#
default_application = self.domain_application or self.default_application
if self.application == default_application:
self.omit_application = True
# omit controller if default controller
#
default_controller = ((self.application == self.domain_application) and self.domain_controller) or router.default_controller or ''
if self.controller == default_controller:
self.omit_controller = True
# omit function if default controller/function
#
if self.functions and self.function == self.default_function and self.omit_controller:
self.omit_function = True
# prohibit ambiguous cases
#
# because we presume the lang string to be unambiguous, its presence protects application omission
#
if self.omit_language:
|
|
|
|
|
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
|
def omit_acf(self):
"omit what we can of a/c/f"
router = self.router
# Handle the easy no-args case of tail-defaults: /a/c /a /
#
if not self.args and self.function == self.default_function:
self.omit_function = True
if self.controller == router.default_controller:
self.omit_controller = True
if self.application == self.default_application:
self.omit_application = True
# omit default application
# (which might be the domain default application)
#
default_application = self.domain_application or self.default_application
if self.application == default_application:
self.omit_application = True
# omit controller if default controller
#
default_controller = ((self.application == self.domain_application) and self.domain_controller) or router.default_controller or ''
if self.controller == default_controller:
self.omit_controller = True
# omit function if possible
#
if self.functions and self.function in self.functions and self.function == self.default_function:
self.omit_function = True
# prohibit ambiguous cases
#
# because we presume the lang string to be unambiguous, its presence protects application omission
#
if self.omit_language:
|
︙ | | | ︙ | |
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
|
We would also like to be able to strip the default application or application/controller
from URLs with function/args present, thus:
/da/c/f/args => /c/f/args
/da/dc/f/args => /f/args
We use [applications] and [controllers] and [functions] to suppress ambiguous omissions.
We assume that language names do not collide with a/c/f names.
'''
map = MapUrlOut(request, env, application, controller, function, args, other, scheme, host, port)
return map.acf()
def get_effective_router(appname):
"return a private copy of the effective router for the specified application"
if not routers or appname not in routers:
return None
return Storage(routers[appname]) # return a copy
|
|
>
>
|
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
|
We would also like to be able to strip the default application or application/controller
from URLs with function/args present, thus:
/da/c/f/args => /c/f/args
/da/dc/f/args => /f/args
We use [applications] and [controllers] and {functions} to suppress ambiguous omissions.
We assume that language names do not collide with a/c/f names.
'''
map = MapUrlOut(request, env, application, controller, function, args, other, scheme, host, port)
return map.acf()
def get_effective_router(appname):
"return a private copy of the effective router for the specified application"
if not routers or appname not in routers:
return None
return Storage(routers[appname]) # return a copy
|