Skip to content

Commit

Permalink
slugify all tags, to avoid duplicate tags with different capitalisation
Browse files Browse the repository at this point in the history
  • Loading branch information
gasman committed Apr 17, 2014
1 parent 0ce72c5 commit 157c631
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 29 deletions.
37 changes: 10 additions & 27 deletions demoscene/forms/production.py
@@ -1,14 +1,17 @@
from django import forms
from demoscene.models import Production, ProductionType, Platform, ProductionBlurb, SoundtrackLink, ProductionLink, Edit
from fuzzy_date_field import FuzzyDateField
from django.forms.formsets import formset_factory
from django.forms.models import inlineformset_factory, BaseModelFormSet, ModelFormOptions

from demoscene.models import Production, ProductionType, Platform, ProductionBlurb, SoundtrackLink, ProductionLink, Edit
from demoscene.utils.party_field import PartyField
from demoscene.forms.common import ExternalLinkForm, BaseExternalLinkFormSet
from demoscene.utils.text import slugify_tag

from fuzzy_date_field import FuzzyDateField
from nick_field import NickField
from byline_field import BylineField
from production_field import ProductionField
from demoscene.utils.party_field import PartyField
from production_type_field import ProductionTypeChoiceField, ProductionTypeMultipleChoiceField
from demoscene.forms.common import ExternalLinkForm, BaseExternalLinkFormSet


def readable_list(list):
Expand Down Expand Up @@ -254,33 +257,13 @@ class Meta:
}


def edit_string_for_tags(tags):
"""
A version of taggit.utils.edit_string_for_tags that doesn't quote tags containing spaces,
to match the js tag-it library's behaviour
"""
names = []
for tag in tags:
name = tag.name
if ',' in name:
names.append('"%s"' % name)
else:
names.append(name)
return ', '.join(sorted(names))

class TagitTagWidget(forms.TextInput):
def render(self, name, value, attrs=None):
if value is not None and not isinstance(value, (str, unicode)):
value = edit_string_for_tags([o.tag for o in value.select_related("tag").order_by('tag__name')])
return super(TagitTagWidget, self).render(name, value, attrs)

class ProductionTagsForm(forms.ModelForm):
def clean_tags(self):
return [slugify_tag(name) for name in self.cleaned_data['tags']]

class Meta:
model = Production
fields = ['tags']
widgets = {
'tags': TagitTagWidget()
}


class ProductionDownloadLinkForm(ExternalLinkForm):
Expand Down
20 changes: 20 additions & 0 deletions demoscene/management/commands/slugify_tags.py
@@ -0,0 +1,20 @@
from django.core.management.base import NoArgsCommand

from taggit.models import Tag, TaggedItem

from demoscene.utils.text import slugify_tag

class Command(NoArgsCommand):
def handle_noargs(self, **options):
for tag in Tag.objects.all():
new_name = slugify_tag(tag.name)
try:
existing_tag = Tag.objects.exclude(id=tag.id).get(name=new_name)
# if tag with that name already exists, move all tagged items to existing_tag
# and delete this tag
TaggedItem.objects.filter(tag=tag).update(tag=existing_tag)
tag.delete()
except Tag.DoesNotExist:
# keep this tag, just rewrite the name
tag.name = new_name
tag.save()
12 changes: 12 additions & 0 deletions demoscene/utils/text.py
@@ -0,0 +1,12 @@
import re
import unicodedata

from django.utils.safestring import mark_safe

def slugify_tag(value):
"""
A version of django.utils.text.slugify that lets '.' characters through.
"""
value = unicodedata.normalize('NFKD', value).encode('ascii', 'ignore').decode('ascii')
value = re.sub('[^\w\s\.-]', '', value).strip().lower()
return mark_safe(re.sub('[-\s]+', '-', value))
5 changes: 3 additions & 2 deletions demoscene/views/productions.py
Expand Up @@ -16,6 +16,7 @@
from demoscene.models import Production, Byline, Credit, Nick, Screenshot, ProductionBlurb, Edit
from demoscene.forms.production import *
from demoscene.forms.common import CreditFormSet
from demoscene.utils.text import slugify_tag

from screenshots.tasks import capture_upload_for_processing
from comments.models import ProductionComment
Expand Down Expand Up @@ -646,7 +647,7 @@ def add_tag(request, production_id):

production = get_object_or_404(Production, id=production_id)
if request.method == 'POST':
tag_name = request.POST.get('tag_name')
tag_name = slugify_tag(request.POST.get('tag_name'))
# check whether it's already present
existing_tag = production.tags.filter(name=tag_name)
if not existing_tag:
Expand All @@ -667,7 +668,7 @@ def remove_tag(request, production_id):

production = get_object_or_404(Production, id=production_id)
if request.method == 'POST':
tag_name = request.POST.get('tag_name')
tag_name = slugify_tag(request.POST.get('tag_name'))
existing_tag = production.tags.filter(name=tag_name)
if existing_tag:
production.tags.remove(tag_name)
Expand Down

0 comments on commit 157c631

Please sign in to comment.