From: Aaron Williamson Date: Fri, 13 May 2011 16:18:52 +0000 (-0400) Subject: Generate unique slugs for newly submitted images. X-Git-Url: https://vcs.fsf.org/?a=commitdiff_plain;h=0546833c6ea4dcaaa82861819916760dd62d8fa7;p=mediagoblin.git Generate unique slugs for newly submitted images. --- diff --git a/mediagoblin/models.py b/mediagoblin/models.py index 5b286038..1ecabe3e 100644 --- a/mediagoblin/models.py +++ b/mediagoblin/models.py @@ -18,8 +18,9 @@ import datetime, uuid from mongokit import Document, Set +from mediagoblin import util from mediagoblin.auth import lib as auth_lib - +from mediagoblin import globals as mediagoblin_globals ################### # Custom validators @@ -66,6 +67,7 @@ class MediaEntry(Document): structure = { 'uploader': User, 'title': unicode, + 'slug':unicode, 'created': datetime.datetime, 'description': unicode, 'media_type': unicode, @@ -98,6 +100,13 @@ class MediaEntry(Document): def main_mediafile(self): pass + def generate_slug(self): + self['slug'] = util.slugify(self['title']) + + duplicate = mediagoblin_globals.database.media_entries.find_one({'slug': self['slug']}) + + if duplicate: + self['slug'] = "%s-%s" % (self['_id'], self['slug']) REGISTER_MODELS = [MediaEntry, User] diff --git a/mediagoblin/submit/views.py b/mediagoblin/submit/views.py index 1b28e339..95a416e2 100644 --- a/mediagoblin/submit/views.py +++ b/mediagoblin/submit/views.py @@ -52,6 +52,9 @@ def submit_start(request): # it to generate the file path entry.save(validate=False) + # Generate a slug from the title + entry.generate_slug() + # Now store generate the queueing related filename queue_filepath = request.app.queue_store.get_unique_filepath( ['media_entries', diff --git a/mediagoblin/tests/test_util.py b/mediagoblin/tests/test_util.py index ff40a677..7b00a074 100644 --- a/mediagoblin/tests/test_util.py +++ b/mediagoblin/tests/test_util.py @@ -70,6 +70,14 @@ I hope you like unit tests JUST AS MUCH AS I DO!""" I hope you like unit tests JUST AS MUCH AS I DO!""" +def test_slugify(): + assert util.slugify('a walk in the park') == 'a-walk-in-the-park' + assert util.slugify('A Walk in the Park') == 'a-walk-in-the-park' + assert util.slugify('a walk in the park') == 'a-walk-in-the-park' + assert util.slugify('a walk in-the-park') == 'a-walk-in-the-park' + assert util.slugify('a w@lk in the park?') == 'a-w-lk-in-the-park' + assert util.slugify(u'a walk in the par\u0107') == 'a-walk-in-the-parc' + assert util.slugify(u'\u00E0\u0042\u00E7\u010F\u00EB\u0066') == 'abcdef' def test_locale_to_lower_upper(): """ diff --git a/mediagoblin/util.py b/mediagoblin/util.py index 1f568ed3..a66e2ba5 100644 --- a/mediagoblin/util.py +++ b/mediagoblin/util.py @@ -19,9 +19,10 @@ import gettext import pkg_resources import smtplib import sys - +import re import jinja2 import mongokit +import translitcodec from mediagoblin import globals as mgoblin_globals @@ -107,6 +108,18 @@ def import_component(import_string): func = getattr(module, func_name) return func +_punct_re = re.compile(r'[\t !"#$%&\'()*\-/<=>?@\[\\\]^_`{|},.]+') + +def slugify(text, delim=u'-'): + """ + Generates an ASCII-only slug. Taken from http://flask.pocoo.org/snippets/5/ + """ + result = [] + for word in _punct_re.split(text.lower()): + word = word.encode('translit/long') + if word: + result.append(word) + return unicode(delim.join(result)) ### ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ### Special email test stuff begins HERE diff --git a/mediagoblin/views.py b/mediagoblin/views.py index 95d0be7a..7f925bb7 100644 --- a/mediagoblin/views.py +++ b/mediagoblin/views.py @@ -20,6 +20,7 @@ from webob import Response, exc import wtforms from mongokit import ObjectId from mediagoblin import models +import gettext def root_view(request): media_entries = request.db.MediaEntry.find( diff --git a/setup.py b/setup.py index 7d38e526..08887dee 100644 --- a/setup.py +++ b/setup.py @@ -39,6 +39,7 @@ setup( 'sphinx', 'PIL', 'Babel', + 'translitcodec', ], test_suite='nose.collector',