2828RE_ESCAPE = re .compile (r'([^\\]?)\\' ) # Recognize escape characters
2929RE_START_END = re .compile (r'[\$\^]' ) # Recognize start and end charaters
3030
31+ try : # check for django-cms
32+ from cms .appresolver import AppRegexURLResolver
33+ CMS_APP_RESOLVER = True
34+ except :
35+ CMS_APP_RESOLVER = False # we can live without it
36+
3137
3238def urls_as_dict ():
3339 '''
@@ -44,6 +50,80 @@ def urls_as_json():
4450 return json .dumps (urls_as_dict (), cls = DjangoJSONEncoder )
4551
4652
53+ def _get_urls_for_pattern (pattern , prefix = '' , namespace = None ):
54+ urls = {}
55+
56+ if issubclass (pattern .__class__ , RegexURLPattern ):
57+ if settings .JS_URLS_UNNAMED :
58+ mod_name , obj_name = pattern .callback .__module__ , pattern .callback .__name__
59+ try :
60+ module = __import__ (mod_name , fromlist = [obj_name ])
61+ obj = getattr (module , obj_name )
62+ func_name = "{0}.{1}" .format (mod_name , obj_name ) if isinstance (obj , types .FunctionType ) else None
63+ pattern_name = pattern .name or func_name
64+ except :
65+ pattern_name = pattern .name
66+ else :
67+ pattern_name = pattern .name
68+
69+ if pattern_name :
70+ if settings .JS_URLS and pattern_name not in settings .JS_URLS :
71+ return {}
72+ if settings .JS_URLS_EXCLUDE and pattern_name in settings .JS_URLS_EXCLUDE :
73+ return {}
74+ if namespace :
75+ pattern_name = ':' .join ((namespace , pattern_name ))
76+ full_url = prefix + pattern .regex .pattern
77+ for char in ['^' , '$' ]:
78+ full_url = full_url .replace (char , '' )
79+ # remove optionnal non capturing groups
80+ opt_grp_matches = RE_OPT_GRP .findall (full_url )
81+ if opt_grp_matches :
82+ for match in opt_grp_matches :
83+ full_url = full_url .replace (match , '' )
84+ # remove optionnal characters
85+ opt_matches = RE_OPT .findall (full_url )
86+ if opt_matches :
87+ for match in opt_matches :
88+ full_url = full_url .replace (match , '' )
89+ # handle kwargs, args
90+ kwarg_matches = RE_KWARG .findall (full_url )
91+ if kwarg_matches :
92+ for el in kwarg_matches :
93+ # prepare the output for JS resolver
94+ full_url = full_url .replace (el [0 ], "<%s>" % el [1 ])
95+ # after processing all kwargs try args
96+ args_matches = RE_ARG .findall (full_url )
97+ if args_matches :
98+ for el in args_matches :
99+ full_url = full_url .replace (el , "<>" ) # replace by a empty parameter name
100+ # Unescape charaters
101+ full_url = RE_ESCAPE .sub (r'\1' , full_url )
102+ urls [pattern_name ] = "/" + full_url
103+ elif (CMS_APP_RESOLVER ) and (issubclass (pattern .__class__ , AppRegexURLResolver )): # hack for django-cms
104+ for p in pattern .url_patterns :
105+ urls .update (_get_urls_for_pattern (p , prefix = prefix , namespace = namespace ))
106+ elif issubclass (pattern .__class__ , RegexURLResolver ):
107+ if pattern .urlconf_name :
108+ if pattern .namespace and not pattern .app_name :
109+ # Namespace without app_name
110+ nss = [pattern .namespace ]
111+ else :
112+ # Add urls twice: for app and instance namespace
113+ nss = set ((pattern .namespace , pattern .app_name ))
114+ for ns in nss :
115+ namespaces = [nsp for nsp in (namespace , ns ) if nsp ]
116+ namespaces = ':' .join (namespaces )
117+ if settings .JS_URLS_NAMESPACES and namespaces and namespaces not in settings .JS_URLS_NAMESPACES :
118+ continue
119+ if settings .JS_URLS_NAMESPACES_EXCLUDE and namespaces in settings .JS_URLS_NAMESPACES_EXCLUDE :
120+ continue
121+ new_prefix = '%s%s' % (prefix , pattern .regex .pattern )
122+ urls .update (_get_urls (pattern .urlconf_name , new_prefix , namespaces ))
123+
124+ return urls
125+
126+
47127def _get_urls (module , prefix = '' , namespace = None ):
48128 urls = {}
49129 if isinstance (module , (six .text_type , six .string_types )):
@@ -61,69 +141,6 @@ def _get_urls(module, prefix='', namespace=None):
61141 raise TypeError ('Unsupported type: %s' % type (module ))
62142
63143 for pattern in patterns :
64- if issubclass (pattern .__class__ , RegexURLPattern ):
65- if settings .JS_URLS_UNNAMED :
66- mod_name , obj_name = pattern .callback .__module__ , pattern .callback .__name__
67- try :
68- module = __import__ (mod_name , fromlist = [obj_name ])
69- obj = getattr (module , obj_name )
70- func_name = "{0}.{1}" .format (mod_name , obj_name ) if isinstance (obj , types .FunctionType ) else None
71- pattern_name = pattern .name or func_name
72- except :
73- pattern_name = pattern .name
74- else :
75- pattern_name = pattern .name
144+ urls .update (_get_urls_for_pattern (pattern , prefix = prefix , namespace = namespace ))
76145
77- if pattern_name :
78- if settings .JS_URLS and pattern_name not in settings .JS_URLS :
79- continue
80- if settings .JS_URLS_EXCLUDE and pattern_name in settings .JS_URLS_EXCLUDE :
81- continue
82- if namespace :
83- pattern_name = ':' .join ((namespace , pattern_name ))
84- full_url = prefix + pattern .regex .pattern
85- for char in ['^' , '$' ]:
86- full_url = full_url .replace (char , '' )
87- # remove optionnal non capturing groups
88- opt_grp_matches = RE_OPT_GRP .findall (full_url )
89- if opt_grp_matches :
90- for match in opt_grp_matches :
91- full_url = full_url .replace (match , '' )
92- # remove optionnal characters
93- opt_matches = RE_OPT .findall (full_url )
94- if opt_matches :
95- for match in opt_matches :
96- full_url = full_url .replace (match , '' )
97- # handle kwargs, args
98- kwarg_matches = RE_KWARG .findall (full_url )
99- if kwarg_matches :
100- for el in kwarg_matches :
101- # prepare the output for JS resolver
102- full_url = full_url .replace (el [0 ], "<%s>" % el [1 ])
103- # after processing all kwargs try args
104- args_matches = RE_ARG .findall (full_url )
105- if args_matches :
106- for el in args_matches :
107- full_url = full_url .replace (el , "<>" ) # replace by a empty parameter name
108- # Unescape charaters
109- full_url = RE_ESCAPE .sub (r'\1' , full_url )
110-
111- urls [pattern_name ] = "/" + full_url
112- elif issubclass (pattern .__class__ , RegexURLResolver ):
113- if pattern .urlconf_name :
114- if pattern .namespace and not pattern .app_name :
115- # Namespace without app_name
116- nss = [pattern .namespace ]
117- else :
118- # Add urls twice: for app and instance namespace
119- nss = set ((pattern .namespace , pattern .app_name ))
120- for ns in nss :
121- namespaces = [nsp for nsp in (namespace , ns ) if nsp ]
122- namespaces = ':' .join (namespaces )
123- if settings .JS_URLS_NAMESPACES and namespaces and namespaces not in settings .JS_URLS_NAMESPACES :
124- continue
125- if settings .JS_URLS_NAMESPACES_EXCLUDE and namespaces in settings .JS_URLS_NAMESPACES_EXCLUDE :
126- continue
127- new_prefix = '%s%s' % (prefix , pattern .regex .pattern )
128- urls .update (_get_urls (pattern .urlconf_name , new_prefix , namespaces ))
129146 return urls
0 commit comments