summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEvgeny Fadeev <evgeny.fadeev@gmail.com>2011-01-30 18:18:19 -0500
committerEvgeny Fadeev <evgeny.fadeev@gmail.com>2011-01-30 18:18:19 -0500
commitec15fc285f62f713e4ee3f16c489757d04e8a94d (patch)
treefaccad159efabe26ca3ec1366d469c3f6d28b431
parent507f6d32c6eec7114cf05e0ff9f5009aa9b0143d (diff)
downloadaskbot-ec15fc285f62f713e4ee3f16c489757d04e8a94d.tar.gz
askbot-ec15fc285f62f713e4ee3f16c489757d04e8a94d.tar.bz2
askbot-ec15fc285f62f713e4ee3f16c489757d04e8a94d.zip
it is now possible to either force lower-casing tags or allow freehand character case without a possibility to have duplicate tag names, and fixed the fix_question_tags management command
-rw-r--r--askbot/__init__.py2
-rw-r--r--askbot/conf/forum_data_rules.py15
-rw-r--r--askbot/forms.py27
-rw-r--r--askbot/management/commands/fix_question_tags.py33
-rw-r--r--askbot/skins/default/media/js/post.js2
-rw-r--r--askbot/tests/__init__.py1
-rw-r--r--askbot/tests/form_tests.py35
-rw-r--r--askbot/views/writers.py5
8 files changed, 109 insertions, 11 deletions
diff --git a/askbot/__init__.py b/askbot/__init__.py
index b084cb5b..4b161e23 100644
--- a/askbot/__init__.py
+++ b/askbot/__init__.py
@@ -19,4 +19,4 @@ def get_version():
"""returns version of the askbot app
this version is meaningful for pypi only
"""
- return '0.6.66'
+ return '0.6.67'
diff --git a/askbot/conf/forum_data_rules.py b/askbot/conf/forum_data_rules.py
index 972beff8..4ce3a239 100644
--- a/askbot/conf/forum_data_rules.py
+++ b/askbot/conf/forum_data_rules.py
@@ -30,6 +30,21 @@ settings.register(
)
settings.register(
+ livesettings.BooleanValue(
+ FORUM_DATA_RULES,
+ 'FORCE_LOWERCASE_TAGS',
+ default = False,
+ description = _('Force lowercase the tags'),
+ help_text = _(
+ 'Attention: after checking this, please back up the database, '
+ 'and run a management command: '
+ '<code>python manage.py fix_question_tags</code> to globally '
+ 'rename the tags'
+ )
+ )
+)
+
+settings.register(
livesettings.IntegerValue(
FORUM_DATA_RULES,
'MAX_COMMENTS_TO_SHOW',
diff --git a/askbot/forms.py b/askbot/forms.py
index fb9dcc73..ccb65ab5 100644
--- a/askbot/forms.py
+++ b/askbot/forms.py
@@ -94,7 +94,7 @@ class TagNamesField(forms.CharField):
split_re = re.compile(const.TAG_SPLIT_REGEX)
tag_strings = split_re.split(data)
- out_tag_list = []
+ entered_tags = []
tag_count = len(tag_strings)
if tag_count > askbot_settings.MAX_TAGS_PER_POST:
max_tags = askbot_settings.MAX_TAGS_PER_POST
@@ -118,9 +118,28 @@ class TagNamesField(forms.CharField):
if not tagname_re.search(tag):
raise forms.ValidationError(_('use-these-chars-in-tags'))
#only keep unique tags
- if tag not in out_tag_list:
- out_tag_list.append(tag)
- return u' '.join(out_tag_list)
+ if tag not in entered_tags:
+ entered_tags.append(tag)
+
+ #normalize character case of tags
+ if askbot_settings.FORCE_LOWERCASE_TAGS:
+ entered_tags = set([name.lower() for name in entered_tags])
+ else:
+ #make names of tags in the input to agree with the database
+
+ cleaned_entered_tags = set()
+ for entered_tag in entered_tags:
+ try:
+ #looks like we have to load tags one-by one
+ stored_tag = models.Tag.objects.get(
+ name__iexact = entered_tag
+ )
+ cleaned_entered_tags.add(stored_tag.name)
+ except models.Tag.DoesNotExist:
+ cleaned_entered_tags.add(entered_tag)
+ entered_tags = list(cleaned_entered_tags)
+
+ return u' '.join(entered_tags)
class WikiField(forms.BooleanField):
def __init__(self, *args, **kwargs):
diff --git a/askbot/management/commands/fix_question_tags.py b/askbot/management/commands/fix_question_tags.py
index 1d5cae7e..d036cfe6 100644
--- a/askbot/management/commands/fix_question_tags.py
+++ b/askbot/management/commands/fix_question_tags.py
@@ -2,8 +2,10 @@ import sys
from django.core.management.base import NoArgsCommand
from django.db import transaction
from askbot import models
+from askbot import forms
from askbot.utils import console
from askbot.models import signals
+from askbot.conf import settings as askbot_settings
FORMAT_STRING = '%6.2f%%'
@@ -16,14 +18,32 @@ class Command(NoArgsCommand):
@transaction.commit_manually
def run_command(self):
"""method that runs the actual command"""
+ #go through tags and find character case duplicates and eliminate them
+ tagnames = models.Tag.objects.values_list('name', flat = True)
+ for name in tagnames:
+ dupes = models.Tag.objects.filter(name__iexact = name)
+ first_tag = dupes[0]
+ if dupes.count() > 1:
+ line = 'Found duplicate tags for %s:' % first_tag.name
+ for idx in xrange(1, dupes.count()):
+ print dupes[idx].name + ' ',
+ dupes[idx].delete()
+ print ''
+ if askbot_settings.FORCE_LOWERCASE_TAGS:
+ lowercased_name = first_tag.name.lower()
+ if first_tag.name != lowercased_name:
+ print 'Converting tag %s to lower case' % first_tag.name
+ first_tag.name = lowercased_name
+ first_tag.save()
+ transaction.commit()
+ #go through questions and fix tag records on each
questions = models.Question.objects.all()
checked_count = 0
found_count = 0
total_count = questions.count()
- print "Searching for questions with incomplete tag records:",
+ print "Searching for questions with inconsistent tag records:",
for question in questions:
-
tags = question.tags.all()
denorm_tag_set = set(question.get_tag_names())
norm_tag_set = set(question.tags.values_list('name', flat=True))
@@ -36,12 +56,17 @@ class Command(NoArgsCommand):
user = question.author
timestamp = question.added_at
+ tagnames = forms.TagNamesField().clean(question.tagnames)
+
question.update_tags(
- tagnames = question.tagnames,
+ tagnames = tagnames,
user = user,
timestamp = timestamp
)
+ question.tagnames = tagnames
+ question.save()
found_count += 1
+
transaction.commit()
checked_count += 1
progress = 100*float(checked_count)/float(total_count)
@@ -50,4 +75,4 @@ class Command(NoArgsCommand):
if found_count:
print '%d problem questions found, tag records restored' % found_count
else:
- print 'Nothing found'
+ print 'Did not find any problems'
diff --git a/askbot/skins/default/media/js/post.js b/askbot/skins/default/media/js/post.js
index 12299a82..85600a22 100644
--- a/askbot/skins/default/media/js/post.js
+++ b/askbot/skins/default/media/js/post.js
@@ -662,7 +662,7 @@ var questionRetagger = function(){
data: { tags: getUniqueWords(tagInput.val()).join(' ') },
success: function(json) {
if (json['success'] === true){
- new_tags = getUniqueWords(tagInput.val());
+ new_tags = getUniqueWords(json['new_tags']);
oldTagsHtml = '';
cancelRetag();
drawNewTags(new_tags.join(' '));
diff --git a/askbot/tests/__init__.py b/askbot/tests/__init__.py
index d0e70240..1cb8d37b 100644
--- a/askbot/tests/__init__.py
+++ b/askbot/tests/__init__.py
@@ -7,3 +7,4 @@ from askbot.tests.skin_tests import *
from askbot.tests.badge_tests import *
from askbot.tests.management_command_tests import *
from askbot.tests.search_state_tests import *
+from askbot.tests.form_tests import *
diff --git a/askbot/tests/form_tests.py b/askbot/tests/form_tests.py
new file mode 100644
index 00000000..dfa2d628
--- /dev/null
+++ b/askbot/tests/form_tests.py
@@ -0,0 +1,35 @@
+from askbot.tests.utils import AskbotTestCase
+from askbot.conf import settings as askbot_settings
+from askbot import forms
+from askbot import models
+
+class TagNamesFieldTests(AskbotTestCase):
+
+ def setUp(self):
+ self.field = forms.TagNamesField()
+ self.user = self.create_user('user1')
+
+ def clean(self, value):
+ return self.field.clean(value).strip().split(' ')
+
+ def assert_tags_equal(self, tag_list1, tag_list2):
+ self.assertEqual(sorted(tag_list1), sorted(tag_list2))
+
+ def test_force_lowercase(self):
+ """FORCE_LOWERCASE setting is on
+ """
+ askbot_settings.update('FORCE_LOWERCASE_TAGS', True)
+ cleaned_tags = self.clean('Tag1 TAG5 tag1 tag5')
+ self.assert_tags_equal(cleaned_tags, ['tag1','tag5'])
+
+ def test_custom_case(self):
+ """FORCE_LOWERCASE setting is off
+ """
+ askbot_settings.update('FORCE_LOWERCASE_TAGS', False)
+ models.Tag(name = 'TAG1', created_by = self.user).save()
+ models.Tag(name = 'Tag2', created_by = self.user).save()
+ cleaned_tags = self.clean('tag1 taG2 TAG1 tag3 tag3')
+ self.assert_tags_equal(cleaned_tags, ['TAG1', 'Tag2', 'tag3'])
+
+
+
diff --git a/askbot/views/writers.py b/askbot/views/writers.py
index a1c2b512..2dc3f2c8 100644
--- a/askbot/views/writers.py
+++ b/askbot/views/writers.py
@@ -282,7 +282,10 @@ def retag_question(request, id):
tags = form.cleaned_data['tags']
)
if request.is_ajax():
- response_data = {'success': True}
+ response_data = {
+ 'success': True,
+ 'new_tags': question.tagnames
+ }
data = simplejson.dumps(response_data)
return HttpResponse(data, mimetype="application/json")
else: