Skip to content

Commit

Permalink
Merge 89b3e86 into 4c41997
Browse files Browse the repository at this point in the history
  • Loading branch information
szelga committed Jul 23, 2013
2 parents 4c41997 + 89b3e86 commit d342515
Showing 1 changed file with 79 additions and 65 deletions.
144 changes: 79 additions & 65 deletions djangojs/urls_serializer.py
Expand Up @@ -28,6 +28,11 @@
RE_ESCAPE = re.compile(r'([^\\]?)\\') # Recognize escape characters
RE_START_END = re.compile(r'[\$\^]') # Recognize start and end charaters

try: # check for django-cms
from cms.appresolver import AppRegexURLResolver
CMS_APP_RESOLVER = True
except:
CMS_APP_RESOLVER = False # we can live without it

def urls_as_dict():
'''
Expand All @@ -43,6 +48,78 @@ def urls_as_json():
'''
return json.dumps(urls_as_dict(), cls=DjangoJSONEncoder)

def _get_urls_for_pattern(pattern, prefix='', namespace=None):
urls = {}

if issubclass(pattern.__class__, RegexURLPattern):
if settings.JS_URLS_UNNAMED:
mod_name, obj_name = pattern.callback.__module__, pattern.callback.__name__
try:
module = __import__(mod_name, fromlist=[obj_name])
obj = getattr(module, obj_name)
func_name = "{0}.{1}".format(mod_name, obj_name) if isinstance(obj, types.FunctionType) else None
pattern_name = pattern.name or func_name
except:
pattern_name = pattern.name
else:
pattern_name = pattern.name

if pattern_name:
if settings.JS_URLS and pattern_name not in settings.JS_URLS:
return {}
if settings.JS_URLS_EXCLUDE and pattern_name in settings.JS_URLS_EXCLUDE:
return {}
if namespace:
pattern_name = ':'.join((namespace, pattern_name))
full_url = prefix + pattern.regex.pattern
for char in ['^', '$']:
full_url = full_url.replace(char, '')
# remove optionnal non capturing groups
opt_grp_matches = RE_OPT_GRP.findall(full_url)
if opt_grp_matches:
for match in opt_grp_matches:
full_url = full_url.replace(match, '')
# remove optionnal characters
opt_matches = RE_OPT.findall(full_url)
if opt_matches:
for match in opt_matches:
full_url = full_url.replace(match, '')
# handle kwargs, args
kwarg_matches = RE_KWARG.findall(full_url)
if kwarg_matches:
for el in kwarg_matches:
# prepare the output for JS resolver
full_url = full_url.replace(el[0], "<%s>" % el[1])
# after processing all kwargs try args
args_matches = RE_ARG.findall(full_url)
if args_matches:
for el in args_matches:
full_url = full_url.replace(el, "<>") # replace by a empty parameter name
# Unescape charaters
full_url = RE_ESCAPE.sub(r'\1', full_url)
urls[pattern_name] = "/" + full_url
elif (CMS_APP_RESOLVER) and (issubclass(pattern.__class__, AppRegexURLResolver)): # hack for django-cms
for p in pattern.url_patterns:
urls.update(_get_urls_for_pattern(p, prefix=prefix, namespace=namespace))
elif issubclass(pattern.__class__, RegexURLResolver):
if pattern.urlconf_name:
if pattern.namespace and not pattern.app_name:
# Namespace without app_name
nss = [pattern.namespace]
else:
# Add urls twice: for app and instance namespace
nss = set((pattern.namespace, pattern.app_name))
for ns in nss:
namespaces = [nsp for nsp in (namespace, ns) if nsp]
namespaces = ':'.join(namespaces)
if settings.JS_URLS_NAMESPACES and namespaces and namespaces not in settings.JS_URLS_NAMESPACES:
continue
if settings.JS_URLS_NAMESPACES_EXCLUDE and namespaces in settings.JS_URLS_NAMESPACES_EXCLUDE:
continue
new_prefix = '%s%s' % (prefix, pattern.regex.pattern)
urls.update(_get_urls(pattern.urlconf_name, new_prefix, namespaces))

return urls

def _get_urls(module, prefix='', namespace=None):
urls = {}
Expand All @@ -51,7 +128,7 @@ def _get_urls(module, prefix='', namespace=None):
__import__(module)
root_urls = sys.modules[module]
patterns = root_urls.urlpatterns
except ImportError: # die silently
except ImportError: # die silently
patterns = tuple()
elif isinstance(module, (list, tuple)):
patterns = module
Expand All @@ -61,69 +138,6 @@ def _get_urls(module, prefix='', namespace=None):
raise TypeError('Unsupported type: %s' % type(module))

for pattern in patterns:
if issubclass(pattern.__class__, RegexURLPattern):
if settings.JS_URLS_UNNAMED:
mod_name, obj_name = pattern.callback.__module__, pattern.callback.__name__
try:
module = __import__(mod_name, fromlist=[obj_name])
obj = getattr(module, obj_name)
func_name = "{0}.{1}".format(mod_name, obj_name) if isinstance(obj, types.FunctionType) else None
pattern_name = pattern.name or func_name
except:
pattern_name = pattern.name
else:
pattern_name = pattern.name
urls.update(_get_urls_for_pattern(pattern, prefix=prefix, namespace=namespace))

if pattern_name:
if settings.JS_URLS and pattern_name not in settings.JS_URLS:
continue
if settings.JS_URLS_EXCLUDE and pattern_name in settings.JS_URLS_EXCLUDE:
continue
if namespace:
pattern_name = ':'.join((namespace, pattern_name))
full_url = prefix + pattern.regex.pattern
for char in ['^', '$']:
full_url = full_url.replace(char, '')
# remove optionnal non capturing groups
opt_grp_matches = RE_OPT_GRP.findall(full_url)
if opt_grp_matches:
for match in opt_grp_matches:
full_url = full_url.replace(match, '')
# remove optionnal characters
opt_matches = RE_OPT.findall(full_url)
if opt_matches:
for match in opt_matches:
full_url = full_url.replace(match, '')
# handle kwargs, args
kwarg_matches = RE_KWARG.findall(full_url)
if kwarg_matches:
for el in kwarg_matches:
# prepare the output for JS resolver
full_url = full_url.replace(el[0], "<%s>" % el[1])
# after processing all kwargs try args
args_matches = RE_ARG.findall(full_url)
if args_matches:
for el in args_matches:
full_url = full_url.replace(el, "<>") # replace by a empty parameter name
# Unescape charaters
full_url = RE_ESCAPE.sub(r'\1', full_url)

urls[pattern_name] = "/" + full_url
elif issubclass(pattern.__class__, RegexURLResolver):
if pattern.urlconf_name:
if pattern.namespace and not pattern.app_name:
# Namespace without app_name
nss = [pattern.namespace]
else:
# Add urls twice: for app and instance namespace
nss = set((pattern.namespace, pattern.app_name))
for ns in nss:
namespaces = [nsp for nsp in (namespace, ns) if nsp]
namespaces = ':'.join(namespaces)
if settings.JS_URLS_NAMESPACES and namespaces and namespaces not in settings.JS_URLS_NAMESPACES:
continue
if settings.JS_URLS_NAMESPACES_EXCLUDE and namespaces in settings.JS_URLS_NAMESPACES_EXCLUDE:
continue
new_prefix = '%s%s' % (prefix, pattern.regex.pattern)
urls.update(_get_urls(pattern.urlconf_name, new_prefix, namespaces))
return urls

0 comments on commit d342515

Please sign in to comment.