aboutsummaryrefslogtreecommitdiff
path: root/tagging/utils.py
diff options
context:
space:
mode:
Diffstat (limited to 'tagging/utils.py')
-rw-r--r--tagging/utils.py92
1 files changed, 48 insertions, 44 deletions
diff --git a/tagging/utils.py b/tagging/utils.py
index e89bab0..6c1492f 100644
--- a/tagging/utils.py
+++ b/tagging/utils.py
@@ -3,17 +3,15 @@ Tagging utilities - from user tag input parsing to tag cloud
calculation.
"""
import math
-import types
+from django.utils import six
from django.db.models.query import QuerySet
-from django.utils.encoding import force_unicode
+from django.utils.encoding import force_text
from django.utils.translation import ugettext as _
-# Python 2.3 compatibility
-try:
- set
-except NameError:
- from sets import Set as set
+# Font size distribution algorithms
+LOGARITHMIC, LINEAR = 1, 2
+
def parse_tag_input(input):
"""
@@ -26,13 +24,13 @@ def parse_tag_input(input):
if not input:
return []
- input = force_unicode(input)
+ input = force_text(input)
# Special case - if there are no commas or double quotes in the
# input, we don't *do* a recall... I mean, we know we only need to
# split on spaces.
- if u',' not in input and u'"' not in input:
- words = list(set(split_strip(input, u' ')))
+ if ',' not in input and '"' not in input:
+ words = list(set(split_strip(input, ' ')))
words.sort()
return words
@@ -46,56 +44,55 @@ def parse_tag_input(input):
i = iter(input)
try:
while 1:
- c = i.next()
- if c == u'"':
+ c = next(i)
+ if c == '"':
if buffer:
- to_be_split.append(u''.join(buffer))
+ to_be_split.append(''.join(buffer))
buffer = []
# Find the matching quote
open_quote = True
- c = i.next()
- while c != u'"':
+ c = next(i)
+ while c != '"':
buffer.append(c)
- c = i.next()
+ c = next(i)
if buffer:
- word = u''.join(buffer).strip()
+ word = ''.join(buffer).strip()
if word:
words.append(word)
buffer = []
open_quote = False
else:
- if not saw_loose_comma and c == u',':
+ if not saw_loose_comma and c == ',':
saw_loose_comma = True
buffer.append(c)
except StopIteration:
# If we were parsing an open quote which was never closed treat
# the buffer as unquoted.
if buffer:
- if open_quote and u',' in buffer:
+ if open_quote and ',' in buffer:
saw_loose_comma = True
- to_be_split.append(u''.join(buffer))
+ to_be_split.append(''.join(buffer))
if to_be_split:
if saw_loose_comma:
- delimiter = u','
+ delimiter = ','
else:
- delimiter = u' '
+ delimiter = ' '
for chunk in to_be_split:
words.extend(split_strip(chunk, delimiter))
words = list(set(words))
words.sort()
return words
-def split_strip(input, delimiter=u','):
+
+def split_strip(input, delimiter=','):
"""
Splits ``input`` on ``delimiter``, stripping each resulting string
and returning a list of non-empty strings.
"""
- if not input:
- return []
-
words = [w.strip() for w in input.split(delimiter)]
return [w for w in words if w]
+
def edit_string_for_tags(tags):
"""
Given list of ``Tag`` instances, creates a string representation of
@@ -113,19 +110,20 @@ def edit_string_for_tags(tags):
use_commas = False
for tag in tags:
name = tag.name
- if u',' in name:
+ if ',' in name:
names.append('"%s"' % name)
continue
- elif u' ' in name:
+ elif ' ' in name:
if not use_commas:
use_commas = True
names.append(name)
if use_commas:
- glue = u', '
+ glue = ', '
else:
- glue = u' '
+ glue = ' '
return glue.join(names)
+
def get_queryset_and_model(queryset_or_model):
"""
Given a ``QuerySet`` or a ``Model``, returns a two-tuple of
@@ -139,6 +137,7 @@ def get_queryset_and_model(queryset_or_model):
except AttributeError:
return queryset_or_model._default_manager.all(), queryset_or_model
+
def get_tag_list(tags):
"""
Utility function for accepting tag input in a flexible manner.
@@ -164,32 +163,35 @@ def get_tag_list(tags):
return [tags]
elif isinstance(tags, QuerySet) and tags.model is Tag:
return tags
- elif isinstance(tags, types.StringTypes):
+ elif isinstance(tags, six.string_types):
return Tag.objects.filter(name__in=parse_tag_input(tags))
- elif isinstance(tags, (types.ListType, types.TupleType)):
+ elif isinstance(tags, (list, tuple)):
if len(tags) == 0:
return tags
contents = set()
for item in tags:
- if isinstance(item, types.StringTypes):
+ if isinstance(item, six.string_types):
contents.add('string')
elif isinstance(item, Tag):
contents.add('tag')
- elif isinstance(item, (types.IntType, types.LongType)):
+ elif isinstance(item, six.integer_types):
contents.add('int')
if len(contents) == 1:
if 'string' in contents:
- return Tag.objects.filter(name__in=[force_unicode(tag) \
+ return Tag.objects.filter(name__in=[force_text(tag)
for tag in tags])
elif 'tag' in contents:
return tags
elif 'int' in contents:
return Tag.objects.filter(id__in=tags)
else:
- raise ValueError(_('If a list or tuple of tags is provided, they must all be tag names, Tag objects or Tag ids.'))
+ raise ValueError(
+ _('If a list or tuple of tags is provided, '
+ 'they must all be tag names, Tag objects or Tag ids.'))
else:
raise ValueError(_('The tag input given was invalid.'))
+
def get_tag(tag):
"""
Utility function for accepting single tag input in a flexible
@@ -206,34 +208,35 @@ def get_tag(tag):
return tag
try:
- if isinstance(tag, types.StringTypes):
+ if isinstance(tag, six.string_types):
return Tag.objects.get(name=tag)
- elif isinstance(tag, (types.IntType, types.LongType)):
+ elif isinstance(tag, six.integer_types):
return Tag.objects.get(id=tag)
except Tag.DoesNotExist:
pass
return None
-# Font size distribution algorithms
-LOGARITHMIC, LINEAR = 1, 2
def _calculate_thresholds(min_weight, max_weight, steps):
delta = (max_weight - min_weight) / float(steps)
return [min_weight + i * delta for i in range(1, steps + 1)]
+
def _calculate_tag_weight(weight, max_weight, distribution):
"""
Logarithmic tag weight calculation is based on code from the
- `Tag Cloud`_ plugin for Mephisto, by Sven Fuchs.
+ *Tag Cloud* plugin for Mephisto, by Sven Fuchs.
- .. _`Tag Cloud`: http://www.artweb-design.de/projects/mephisto-plugin-tag-cloud
+ http://www.artweb-design.de/projects/mephisto-plugin-tag-cloud
"""
if distribution == LINEAR or max_weight == 1:
return weight
elif distribution == LOGARITHMIC:
return math.log(weight) * max_weight / math.log(max_weight)
- raise ValueError(_('Invalid distribution algorithm specified: %s.') % distribution)
+ raise ValueError(
+ _('Invalid distribution algorithm specified: %s.') % distribution)
+
def calculate_cloud(tags, steps=4, distribution=LOGARITHMIC):
"""
@@ -255,7 +258,8 @@ def calculate_cloud(tags, steps=4, distribution=LOGARITHMIC):
thresholds = _calculate_thresholds(min_weight, max_weight, steps)
for tag in tags:
font_set = False
- tag_weight = _calculate_tag_weight(tag.count, max_weight, distribution)
+ tag_weight = _calculate_tag_weight(
+ tag.count, max_weight, distribution)
for i in range(steps):
if not font_set and tag_weight <= thresholds[i]:
tag.font_size = i + 1