cms.utils.page_resolver: 92 total statements, 0.0% covered

Generated: Wed 2013-03-13 10:33 CET

Source file: /media/Envs/Envs/filer-gallery/lib/python2.7/site-packages/cms/utils/page_resolver.py

Stats: 0 executed, 79 missed, 13 excluded, 88 ignored

  1. # -*- coding: utf-8 -*-
  2. from cms.exceptions import NoHomeFound
  3. from cms.models.pagemodel import Page
  4. from django.utils.encoding import force_unicode
  5. from django.utils.safestring import mark_safe
  6. from django.utils.translation import ugettext_lazy as _, ungettext_lazy
  7. from django.conf import settings
  8. from django.contrib.sites.models import Site
  9. from django.core.exceptions import ValidationError
  10. from django.core.urlresolvers import reverse
  11. from django.db.models.query_utils import Q
  12. import urllib
  13. import re
  14. from cms.utils.urlutils import any_path_re
  15. ADMIN_PAGE_RE_PATTERN = ur'cms/page/(\d+)'
  16. ADMIN_PAGE_RE = re.compile(ADMIN_PAGE_RE_PATTERN)
  17. def get_page_queryset_from_path(path, preview=False, site=None):
  18. """ Returns a queryset of pages corresponding to the path given
  19. In may returns None or a single page is no page is present or root path is given
  20. """
  21. if 'django.contrib.admin' in settings.INSTALLED_APPS:
  22. admin_base = reverse('admin:index').lstrip('/')
  23. else:
  24. admin_base = None
  25. if not site:
  26. site = Site.objects.get_current()
  27. # Check if this is called from an admin request
  28. if admin_base and path.startswith(admin_base):
  29. # if so, get the page ID to query the page
  30. match = ADMIN_PAGE_RE.search(path)
  31. if not match:
  32. page = None
  33. else:
  34. try:
  35. page = Page.objects.get(pk=match.group(1))
  36. except Page.DoesNotExist:
  37. page = None
  38. return page
  39. if not settings.CMS_MODERATOR or preview:
  40. # We do not use moderator
  41. pages = Page.objects.drafts()
  42. else:
  43. pages = Page.objects.public()
  44. # PageQuerySet.published filter on page site.
  45. # We have to explicitly filter on site only in preview mode
  46. # we can skip pages.filter
  47. if not preview:
  48. pages = pages.published(site)
  49. else:
  50. pages = pages.filter(site=site)
  51. # Check if there are any pages
  52. if not pages.all_root().exists():
  53. return None
  54. # get the home page (needed to get the page)
  55. try:
  56. home = pages.get_home()
  57. except NoHomeFound:
  58. home = None
  59. # if there is no path (slashes stripped) and we found a home, this is the
  60. # home page.
  61. if not path and home:
  62. page = home
  63. return page
  64. # title_set__path=path should be clear, get the pages where the path of the
  65. # title object is equal to our path.
  66. if settings.CMS_FLAT_URLS:
  67. query = Q(title_set__slug=path)
  68. else:
  69. query = Q(title_set__path=path)
  70. return pages.filter(query).distinct()
  71. def get_page_from_path(path, preview=False):
  72. """ Resolves a url path to a single page object.
  73. Raises exceptions is page does not exist or multiple pages are found
  74. """
  75. page_qs = get_page_queryset_from_path(path,preview)
  76. if page_qs is not None:
  77. if isinstance(page_qs,Page):
  78. return page_qs
  79. try:
  80. page = page_qs.get()
  81. except Page.DoesNotExist:
  82. return None
  83. return page
  84. else:
  85. return None
  86. def get_page_from_request(request, use_path=None):
  87. """
  88. Gets the current page from a request object.
  89. URLs can be of the following form (this should help understand the code):
  90. http://server.whatever.com/<some_path>/"pages-root"/some/page/slug
  91. <some_path>: This can be anything, and should be stripped when resolving
  92. pages names. This means the CMS is not installed at the root of the
  93. server's URLs.
  94. "pages-root" This is the root of Django urls for the CMS. It is, in essence
  95. an empty page slug (slug == '')
  96. The page slug can then be resolved to a Page model object
  97. """
  98. pages_root = urllib.unquote(reverse("pages-root"))
  99. # The following is used by cms.middleware.page.CurrentPageMiddleware
  100. if hasattr(request, '_current_page_cache'):
  101. return request._current_page_cache
  102. # TODO: Isn't there a permission check needed here?
  103. preview = 'preview' in request.GET and request.user.is_staff
  104. # If use_path is given, someone already did the path cleaning
  105. if use_path:
  106. path = use_path
  107. else:
  108. # otherwise strip off the non-cms part of the URL
  109. path = request.path[len(pages_root):]
  110. # and strip any final slash
  111. if path.endswith("/"):
  112. path = path[:-1]
  113. page = get_page_from_path(path, preview)
  114. request._current_page_cache = page
  115. return page
  116. def is_valid_url(url,instance,create_links=True, site=None):
  117. """ Checks for conflicting urls
  118. """
  119. if url:
  120. # Url sanity check via regexp
  121. if not any_path_re.match(url):
  122. raise ValidationError(_('Invalid URL, use /my/url format.'))
  123. # We only check page FK to site object to allow is_valid_url check on
  124. # incomplete Page instances
  125. if not site and (instance.site_id):
  126. site = instance.site
  127. # Retrieve complete queryset of pages with corresponding URL
  128. # This uses the same resolving function as ``get_page_from_path``
  129. page_qs = get_page_queryset_from_path(url.strip('/'), site=site)
  130. url_clashes = []
  131. # If queryset has pages checks for conflicting urls
  132. if page_qs is not None:
  133. # If single page is returned create a list for interface compat
  134. if isinstance(page_qs,Page):
  135. page_qs = [page_qs]
  136. for page in page_qs:
  137. # Every page in the queryset except the current one is a conflicting page
  138. # When CMS_MODERATOR is active we have to exclude both copies of the page
  139. if page and ((not settings.CMS_MODERATOR and page.pk != instance.pk) or
  140. (settings.CMS_MODERATOR and page.publisher_public.pk != instance.pk)):
  141. if create_links:
  142. # Format return message with page url
  143. url_clashes.append('<a href="%(page_url)s%(pk)s" target="_blank">%(page_title)s</a>' %
  144. {'page_url':reverse('admin:cms_page_changelist'),'pk':page.pk,
  145. 'page_title': force_unicode(page)
  146. } )
  147. else:
  148. # Just return the page name
  149. url_clashes.append("'%s'" % page)
  150. if url_clashes:
  151. # If clashing pages exist raise the exception
  152. raise ValidationError(mark_safe(ungettext_lazy('Page %(pages)s has the same url \'%(url)s\' as current page "%(instance)s".',
  153. 'Pages %(pages)s have the same url \'%(url)s\' as current page "%(instance)s".',
  154. len(url_clashes)) %
  155. {'pages':", ".join(url_clashes),'url':url,'instance':instance}))
  156. return True