PageRenderTime 106ms CodeModel.GetById 4ms RepoModel.GetById 0ms app.codeStats 0ms

/cms/utils/urlutils.py

http://github.com/divio/django-cms
Python | 111 lines | 93 code | 8 blank | 10 comment | 0 complexity | c83eb00d7e4831030f7d6e9c12e39919 MD5 | raw file
Possible License(s): BSD-3-Clause, Apache-2.0
  1. # -*- coding: utf-8 -*-
  2. import re
  3. from django.conf import settings
  4. from django.urls import reverse
  5. from django.utils.encoding import force_text
  6. from django.utils.http import urlencode
  7. from urllib.parse import urlparse
  8. import cms
  9. from cms.utils.conf import get_cms_setting
  10. # checks validity of absolute / relative url
  11. any_path_re = re.compile('^/?[a-zA-Z0-9_.-]+(/[a-zA-Z0-9_.-]+)*/?$')
  12. # checks validity of relative url
  13. # matches the following:
  14. # /test
  15. # /test/
  16. # ./test/
  17. # ../test/
  18. relative_url_regex = re.compile(r'^[^/<>]+/[^/<>].*$|^/[^/<>]*.*$', re.IGNORECASE)
  19. def levelize_path(path):
  20. """Splits given path to list of paths removing latest level in each step.
  21. >>> path = '/application/item/new'
  22. >>> levelize_path(path)
  23. ['/application/item/new', '/application/item', '/application']
  24. """
  25. parts = tuple(filter(None, path.split('/')))
  26. return ['/' + '/'.join(parts[:n]) for n in range(len(parts), 0, -1)]
  27. def urljoin(*segments):
  28. """Joins url segments together and appends trailing slash if required.
  29. >>> urljoin('a', 'b', 'c')
  30. u'a/b/c/'
  31. >>> urljoin('a', '//b//', 'c')
  32. u'a/b/c/'
  33. >>> urljoin('/a', '/b/', '/c/')
  34. u'/a/b/c/'
  35. >>> urljoin('/a', '')
  36. u'/a/'
  37. """
  38. url = '/' if segments[0].startswith('/') else ''
  39. url += '/'.join(filter(None, (force_text(s).strip('/') for s in segments)))
  40. return url + '/' if settings.APPEND_SLASH else url
  41. def is_media_request(request):
  42. """
  43. Check if a request is a media request.
  44. """
  45. parsed_media_url = urlparse(settings.MEDIA_URL)
  46. if request.path_info.startswith(parsed_media_url.path):
  47. if parsed_media_url.netloc:
  48. if request.get_host() == parsed_media_url.netloc:
  49. return True
  50. else:
  51. return True
  52. return False
  53. def static_with_version(path):
  54. """
  55. Changes provided path from `path/to/filename.ext` to `path/to/$CMS_VERSION/filename.ext`
  56. """
  57. path_re = re.compile('(.*)/([^/]*$)')
  58. return re.sub(path_re, r'\1/%s/\2' % (cms.__version__), path)
  59. def add_url_parameters(url, *args, **params):
  60. """
  61. adds parameters to an url -> url?p1=v1&p2=v2...
  62. :param url: url without any parameters
  63. :param args: one or more dictionaries containing url parameters
  64. :param params: url parameters as keyword arguments
  65. :return: url with parameters if any
  66. """
  67. for arg in args:
  68. params.update(arg)
  69. if params:
  70. return '%s?%s' % (url, urlencode(params))
  71. return url
  72. def admin_reverse(viewname, urlconf=None, args=None, kwargs=None, prefix=None,
  73. current_app=None):
  74. admin_namespace = get_cms_setting('ADMIN_NAMESPACE')
  75. if ':' in viewname:
  76. raise ValueError(
  77. "viewname in admin_reverse may not already have a namespace "
  78. "defined: {0!r}".format(viewname)
  79. )
  80. viewname = "{0}:{1}".format(admin_namespace, viewname)
  81. return reverse(
  82. viewname,
  83. urlconf=urlconf,
  84. args=args,
  85. kwargs=kwargs,
  86. current_app=current_app
  87. )