You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. from __future__ import absolute_import # for logging import below
  2. import logging
  3. import six
  4. from django.utils.timezone import get_current_timezone, is_naive, make_aware
  5. from django.conf import settings
  6. from django.template.defaultfilters import (date as date_filter,
  7. slugify as django_slugify)
  8. from unidecode import unidecode
  9. from oscar.core.loading import import_string
  10. def default_slugifier(value):
  11. """
  12. Oscar's default slugifier function.
  13. Uses Django's slugify function, but first applies unidecode() to convert
  14. non-ASCII strings to ASCII equivalents where possible.
  15. """
  16. return django_slugify(value)
  17. def slugify(value):
  18. """
  19. Slugify a string (even if it contains non-ASCII chars)
  20. """
  21. # Re-map some strings to avoid important characters being stripped. Eg
  22. # remap 'c++' to 'cpp' otherwise it will become 'c'.
  23. for k, v in settings.OSCAR_SLUG_MAP.items():
  24. value = value.replace(k, v)
  25. # Allow an alternative slugify function to be specified
  26. # Recommended way to specify a function is as a string
  27. slugifier = getattr(settings, 'OSCAR_SLUG_FUNCTION', default_slugifier)
  28. if isinstance(slugifier, six.string_types):
  29. slugifier = import_string(slugifier)
  30. # Use unidecode to convert non-ASCII strings to ASCII equivalents where
  31. # possible.
  32. value = slugifier(unidecode(six.text_type(value)))
  33. # Remove stopwords
  34. for word in settings.OSCAR_SLUG_BLACKLIST:
  35. value = value.replace(word + '-', '')
  36. value = value.replace('-' + word, '')
  37. return value
  38. def compose(*functions):
  39. """
  40. Compose functions
  41. This is useful for combining decorators.
  42. """
  43. def _composed(*args):
  44. for fn in functions:
  45. try:
  46. args = fn(*args)
  47. except TypeError:
  48. # args must be scalar so we don't try to expand it
  49. args = fn(args)
  50. return args
  51. return _composed
  52. def format_datetime(dt, format=None):
  53. """
  54. Takes an instance of datetime, converts it to the current timezone and
  55. formats it as a string. Use this instead of
  56. django.core.templatefilters.date, which expects localtime.
  57. :param format: Common will be settings.DATETIME_FORMAT or
  58. settings.DATE_FORMAT, or the resp. shorthands
  59. ('DATETIME_FORMAT', 'DATE_FORMAT')
  60. """
  61. if is_naive(dt):
  62. localtime = make_aware(dt, get_current_timezone())
  63. logging.warning(
  64. "oscar.core.utils.format_datetime received native datetime")
  65. else:
  66. localtime = dt.astimezone(get_current_timezone())
  67. return date_filter(localtime, format)