text: # -*- coding: utf-8 -*-
  from django.conf import settings
  from django.db.models import Q
  import re
  
  APPEND_TO_SLUG = "-copy"
  COPY_SLUG_REGEX = re.compile(r'^.*-copy(?:-(\d+)*)?$')
  
  
  def is_valid_page_slug(page, parent, lang, slug, site, path=None):
      """Validates given slug depending on settings.
      """
      from cms.models import Title
      # Since 3.0 this must take into account unpublished pages as it's necessary
      # to be able to open every page to edit content.
      # If page is newly created (i.e. page.pk is None) we skip filtering out
      # titles attached to the same page
      if page.pk:
          qs = Title.objects.filter(page__site=site).exclude(page=page)
      else:
          qs = Title.objects.filter(page__site=site)
  
      if settings.USE_I18N:
          qs = qs.filter(language=lang)
  
      if parent:
          if parent.is_home:
              qs = qs.filter(Q(page__parent=parent) |
                             Q(page__parent__isnull=True))
          else:
              qs = qs.filter(page__parent=parent)
      else:
          qs = qs.filter(page__parent__isnull=True)
  
      if page.pk:
          qs = qs.exclude(Q(language=lang) & Q(page=page))
          qs = qs.exclude(page__publisher_public=page)
          # Check for slugs
      if qs.filter(slug=slug).count():
          return False
          # Check for path
      if path and qs.filter(path=path).count():
          return False
      return True
  
  
  def get_available_slug(title, new_slug=None):
      """Smart function generates slug for title if current title slug cannot be
      used. Appends APPEND_TO_SLUG to slug and checks it again.
  
      (Used in page copy function)
  
      Returns: slug
      """
      slug = new_slug or title.slug
      # We need the full path for the title to check for conflicting urls
      title.slug = slug
      title.update_path()
      path = title.path
      # This checks for conflicting slugs/overwrite_url, for both published and unpublished pages
      # This is a simpler check than in page_resolver.is_valid_url which
      # takes into account actually page URL
      if not is_valid_page_slug(title.page, title.page.parent, title.language, slug, title.page.site, path):
          # add nice copy attribute, first is -copy, then -copy-2, -copy-3, ....
          match = COPY_SLUG_REGEX.match(slug)
          if match:
              try:
                  next_id = int(match.groups()[0]) + 1
                  slug = "-".join(slug.split('-')[:-1]) + "-%d" % next_id
              except TypeError:
                  slug += "-2"
          else:
              slug += APPEND_TO_SLUG
          return get_available_slug(title, slug)
      else:
          return slug
  
  
  def check_title_slugs(page):
      """Checks page title slugs for duplicity if required, used after page move/
      cut/paste.
      """
      for title in page.title_set.all():
          old_slug, old_path = title.slug, title.path
          title.slug = get_available_slug(title)
          if title.slug != old_slug or title.path != old_path:
              title.save()
  