Skip to content

Commit 73d6f33

Browse files
committed
Merge pull request #27 from szelga/fix_cms
fix #25
2 parents e4eede1 + 179876f commit 73d6f33

File tree

1 file changed

+81
-64
lines changed

1 file changed

+81
-64
lines changed

djangojs/urls_serializer.py

Lines changed: 81 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,12 @@
2828
RE_ESCAPE = re.compile(r'([^\\]?)\\') # Recognize escape characters
2929
RE_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

3238
def 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+
47127
def _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

Comments
 (0)