Development of an internal social media platform with personalised dashboards for students
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.

utils.py 4.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. from __future__ import unicode_literals
  2. from django.conf import settings
  3. from django.utils import six
  4. from django.utils.encoding import force_text
  5. from django.utils.functional import wraps
  6. from django.utils.module_loading import import_string
  7. def _parse_tags(tagstring):
  8. """
  9. Parses tag input, with multiple word input being activated and
  10. delineated by commas and double quotes. Quotes take precedence, so
  11. they may contain commas.
  12. Returns a sorted list of unique tag names.
  13. Ported from Jonathan Buchanan's `django-tagging
  14. <http://django-tagging.googlecode.com/>`_
  15. """
  16. if not tagstring:
  17. return []
  18. tagstring = force_text(tagstring)
  19. # Special case - if there are no commas or double quotes in the
  20. # input, we don't *do* a recall... I mean, we know we only need to
  21. # split on spaces.
  22. if ',' not in tagstring and '"' not in tagstring:
  23. words = list(set(split_strip(tagstring, ' ')))
  24. words.sort()
  25. return words
  26. words = []
  27. buffer = []
  28. # Defer splitting of non-quoted sections until we know if there are
  29. # any unquoted commas.
  30. to_be_split = []
  31. saw_loose_comma = False
  32. open_quote = False
  33. i = iter(tagstring)
  34. try:
  35. while True:
  36. c = six.next(i)
  37. if c == '"':
  38. if buffer:
  39. to_be_split.append(''.join(buffer))
  40. buffer = []
  41. # Find the matching quote
  42. open_quote = True
  43. c = six.next(i)
  44. while c != '"':
  45. buffer.append(c)
  46. c = six.next(i)
  47. if buffer:
  48. word = ''.join(buffer).strip()
  49. if word:
  50. words.append(word)
  51. buffer = []
  52. open_quote = False
  53. else:
  54. if not saw_loose_comma and c == ',':
  55. saw_loose_comma = True
  56. buffer.append(c)
  57. except StopIteration:
  58. # If we were parsing an open quote which was never closed treat
  59. # the buffer as unquoted.
  60. if buffer:
  61. if open_quote and ',' in buffer:
  62. saw_loose_comma = True
  63. to_be_split.append(''.join(buffer))
  64. if to_be_split:
  65. if saw_loose_comma:
  66. delimiter = ','
  67. else:
  68. delimiter = ' '
  69. for chunk in to_be_split:
  70. words.extend(split_strip(chunk, delimiter))
  71. words = list(set(words))
  72. words.sort()
  73. return words
  74. def split_strip(string, delimiter=','):
  75. """
  76. Splits ``string`` on ``delimiter``, stripping each resulting string
  77. and returning a list of non-empty strings.
  78. Ported from Jonathan Buchanan's `django-tagging
  79. <http://django-tagging.googlecode.com/>`_
  80. """
  81. if not string:
  82. return []
  83. words = [w.strip() for w in string.split(delimiter)]
  84. return [w for w in words if w]
  85. def _edit_string_for_tags(tags):
  86. """
  87. Given list of ``Tag`` instances, creates a string representation of
  88. the list suitable for editing by the user, such that submitting the
  89. given string representation back without changing it will give the
  90. same list of tags.
  91. Tag names which contain commas will be double quoted.
  92. If any tag name which isn't being quoted contains whitespace, the
  93. resulting string of tag names will be comma-delimited, otherwise
  94. it will be space-delimited.
  95. Ported from Jonathan Buchanan's `django-tagging
  96. <http://django-tagging.googlecode.com/>`_
  97. """
  98. names = []
  99. for tag in tags:
  100. name = tag.name
  101. if ',' in name or ' ' in name:
  102. names.append('"%s"' % name)
  103. else:
  104. names.append(name)
  105. return ', '.join(sorted(names))
  106. def require_instance_manager(func):
  107. @wraps(func)
  108. def inner(self, *args, **kwargs):
  109. if self.instance is None:
  110. raise TypeError("Can't call %s with a non-instance manager" % func.__name__)
  111. return func(self, *args, **kwargs)
  112. return inner
  113. def get_func(key, default):
  114. func_path = getattr(settings, key, default)
  115. return import_string(func_path)
  116. def parse_tags(tagstring):
  117. func = get_func('TAGGIT_TAGS_FROM_STRING', 'taggit.utils._parse_tags')
  118. return func(tagstring)
  119. def edit_string_for_tags(tags):
  120. func = get_func('TAGGIT_STRING_FROM_TAGS',
  121. 'taggit.utils._edit_string_for_tags')
  122. return func(tags)