diff options
author | Evgeny Fadeev <evgeny.fadeev@gmail.com> | 2011-01-30 18:18:19 -0500 |
---|---|---|
committer | Evgeny Fadeev <evgeny.fadeev@gmail.com> | 2011-01-30 18:18:19 -0500 |
commit | ec15fc285f62f713e4ee3f16c489757d04e8a94d (patch) | |
tree | faccad159efabe26ca3ec1366d469c3f6d28b431 | |
parent | 507f6d32c6eec7114cf05e0ff9f5009aa9b0143d (diff) | |
download | askbot-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__.py | 2 | ||||
-rw-r--r-- | askbot/conf/forum_data_rules.py | 15 | ||||
-rw-r--r-- | askbot/forms.py | 27 | ||||
-rw-r--r-- | askbot/management/commands/fix_question_tags.py | 33 | ||||
-rw-r--r-- | askbot/skins/default/media/js/post.js | 2 | ||||
-rw-r--r-- | askbot/tests/__init__.py | 1 | ||||
-rw-r--r-- | askbot/tests/form_tests.py | 35 | ||||
-rw-r--r-- | askbot/views/writers.py | 5 |
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: |