diff options
-rw-r--r-- | askbot/doc/source/changelog.rst | 2 | ||||
-rw-r--r-- | askbot/doc/source/settings.rst | 14 | ||||
-rw-r--r-- | askbot/migrations/0124_auto__add_field_post_is_private__add_field_replyaddress_reply_action.py | 9 | ||||
-rw-r--r-- | askbot/models/post.py | 2 | ||||
-rw-r--r-- | askbot/models/question.py | 3 | ||||
-rw-r--r-- | askbot/skins/default/media/images/OpenSans-CondBold.ttf | bin | 0 -> 264372 bytes | |||
-rw-r--r-- | askbot/skins/default/media/images/OpenSans-CondLight.ttf | bin | 0 -> 221108 bytes | |||
-rw-r--r-- | askbot/skins/default/media/images/OpenSans-CondLightItalic.ttf | bin | 0 -> 210804 bytes | |||
-rw-r--r-- | askbot/skins/default/templates/django_error.html | 31 | ||||
-rw-r--r-- | askbot/skins/default/templates/meta/fonts.html | 16 | ||||
-rw-r--r-- | askbot/tests/db_api_tests.py | 7 | ||||
-rw-r--r-- | askbot/utils/forms.py | 2 | ||||
-rw-r--r-- | askbot/utils/slug.py | 71 | ||||
-rw-r--r-- | askbot/views/meta.py | 2 |
14 files changed, 123 insertions, 36 deletions
diff --git a/askbot/doc/source/changelog.rst b/askbot/doc/source/changelog.rst index e33f17e7..600c1cb4 100644 --- a/askbot/doc/source/changelog.rst +++ b/askbot/doc/source/changelog.rst @@ -3,11 +3,11 @@ Changes in Askbot Development version ------------------- -* Updated LDAP configuration: allow protocol change, master login and adding "extra options" to the ldap session (Evgeny) * Tag moderation (Evgeny) * Editable optional three level category selector for the tags (Evgeny) * Tag editor adding tags as they are typed (Evgeny) +* Added optional support for unicode slugs (Evgeny) * Optionally allow limiting one answer per question per person (Evgeny) * Added management command `build_livesettings_cache` (Adolfo) * Welcome email for the case when replying by email is enabled (Evgeny) diff --git a/askbot/doc/source/settings.rst b/askbot/doc/source/settings.rst new file mode 100644 index 00000000..d07e697b --- /dev/null +++ b/askbot/doc/source/settings.rst @@ -0,0 +1,14 @@ +================================= +Settings for ``settings.py`` file +================================= + +* ``ALLOW_UNICODE_SLUGS`` - if ``True``, slugs will use unicode, default - ``False`` + +There are more settings that are not documented yet, +but most are described in the ``settings.py`` template: + + askbot/setup_templates/settings.py.mustache + +TODO: describe all of them here. + + diff --git a/askbot/migrations/0124_auto__add_field_post_is_private__add_field_replyaddress_reply_action.py b/askbot/migrations/0124_auto__add_field_post_is_private__add_field_replyaddress_reply_action.py index 8ad83488..b5a1e0c9 100644 --- a/askbot/migrations/0124_auto__add_field_post_is_private__add_field_replyaddress_reply_action.py +++ b/askbot/migrations/0124_auto__add_field_post_is_private__add_field_replyaddress_reply_action.py @@ -9,6 +9,7 @@ class Migration(SchemaMigration): def forwards(self, orm): # Adding field 'Post.is_private' + db.start_transaction() db.add_column('askbot_post', 'is_private', self.gf('django.db.models.fields.BooleanField')(default=False), keep_default=False) @@ -20,7 +21,15 @@ class Migration(SchemaMigration): # Changing field 'ReplyAddress.post' db.alter_column('askbot_replyaddress', 'post_id', self.gf('django.db.models.fields.related.ForeignKey')(null=True, to=orm['askbot.Post'])) + db.commit_transaction() + try: + db.start_transaction() + # Adding field 'User.interesting_tags' + db.add_column(u'auth_user', 'email_signature', self.gf('django.db.models.fields.TextField')(blank=True, default = ''), keep_default=False) + db.commit_transaction() + except: + db.rollback_transaction() def backwards(self, orm): db.delete_column('askbot_post', 'is_private') diff --git a/askbot/models/post.py b/askbot/models/post.py index 5b3d6ba4..ed77d6d1 100644 --- a/askbot/models/post.py +++ b/askbot/models/post.py @@ -748,7 +748,7 @@ class Post(models.Model): does not talk to the actual cache system """ self._cached_comments = comments - + def get_cached_comments(self): try: return self._cached_comments diff --git a/askbot/models/question.py b/askbot/models/question.py index 3c4c7fe8..e87fcaa0 100644 --- a/askbot/models/question.py +++ b/askbot/models/question.py @@ -834,6 +834,9 @@ class Thread(models.Model): *IMPORTANT*: self._question_post() has to exist when update_tags() is called! """ + if tagnames.strip() == '': + return + previous_tags = list(self.tags.filter(status = Tag.STATUS_ACCEPTED)) ordered_updated_tagnames = [t for t in tagnames.strip().split(' ')] diff --git a/askbot/skins/default/media/images/OpenSans-CondBold.ttf b/askbot/skins/default/media/images/OpenSans-CondBold.ttf Binary files differnew file mode 100644 index 00000000..83966f21 --- /dev/null +++ b/askbot/skins/default/media/images/OpenSans-CondBold.ttf diff --git a/askbot/skins/default/media/images/OpenSans-CondLight.ttf b/askbot/skins/default/media/images/OpenSans-CondLight.ttf Binary files differnew file mode 100644 index 00000000..97c355b9 --- /dev/null +++ b/askbot/skins/default/media/images/OpenSans-CondLight.ttf diff --git a/askbot/skins/default/media/images/OpenSans-CondLightItalic.ttf b/askbot/skins/default/media/images/OpenSans-CondLightItalic.ttf Binary files differnew file mode 100644 index 00000000..0b45898d --- /dev/null +++ b/askbot/skins/default/media/images/OpenSans-CondLightItalic.ttf diff --git a/askbot/skins/default/templates/django_error.html b/askbot/skins/default/templates/django_error.html new file mode 100644 index 00000000..c1bfcc20 --- /dev/null +++ b/askbot/skins/default/templates/django_error.html @@ -0,0 +1,31 @@ +<html> + <head> + <title>Internal Server Error</title> + </head> + <body> + <h1>Internal Server Error</h1> + <p> + Most likely this is caused by an import error + within Django due to an incomplete setup of your + django project. + </p> + <p> + Please look into your error logs for more details. + </p> + <p> + Have you installed the database binding module? + </p> + <p> + If you made your own customizations - have you forgotten to + install some dependency module? Please note + that dependency modules may have their own dependencies, etc, + and they should also be satisfied. + </p> + <p> + If you need further assistance, please email at + <a href="mailto:support@askbot.com">support@askbot.com</a>, + post your question at <a href="http://askbot.org/en/questions/">AskBot Support Forum</a> + or call at +1-301-747-1533 (US). + <p> + </body> +</html> diff --git a/askbot/skins/default/templates/meta/fonts.html b/askbot/skins/default/templates/meta/fonts.html index f55d567c..e8e54a8f 100644 --- a/askbot/skins/default/templates/meta/fonts.html +++ b/askbot/skins/default/templates/meta/fonts.html @@ -1,20 +1,8 @@ <style type="text/css"> @font-face { - font-family: 'Yanone Kaffeesatz'; - font-style: normal; - font-weight: 400; - src: url('{{"/images/YanoneKaffeesatz-Regular.ttf"|media}}'); -} -@font-face { - font-family: 'Yanone Kaffeesatz'; + font-family: 'Open Sans Condensed'; font-style: normal; font-weight: 700; - src: url('{{"/images/YanoneKaffeesatz-Bold.ttf"|media}}'); -} -@font-face { - font-family: 'Yanone Kaffeesatz'; - font-style: normal; - font-weight: 300; - src: url('{{"/images/YanoneKaffeesatz-Light.ttf"|media}}'); + src: url('{{"/images/OpenSans-CondBold.ttf"|media}}'); } </style> diff --git a/askbot/tests/db_api_tests.py b/askbot/tests/db_api_tests.py index 3a0c9582..55cf0ef9 100644 --- a/askbot/tests/db_api_tests.py +++ b/askbot/tests/db_api_tests.py @@ -46,6 +46,13 @@ class DBApiTests(AskbotTestCase): self.assertTrue(post.deleted_by == None) self.assertTrue(post.deleted_at == None) + def test_blank_tags_impossible(self): + self.post_question(tags='') + self.assertEqual( + models.Tag.objects.filter(name='').count(), + 0 + ) + def test_flag_question(self): self.user.set_status('m') self.user.flag_post(self.question) diff --git a/askbot/utils/forms.py b/askbot/utils/forms.py index b8ed253b..ee7adf7e 100644 --- a/askbot/utils/forms.py +++ b/askbot/utils/forms.py @@ -108,7 +108,7 @@ class UserNameField(StrippedNonEmptyCharField): raise forms.ValidationError(self.error_messages['invalid']) if username in self.RESERVED_NAMES: raise forms.ValidationError(self.error_messages['forbidden']) - if slugify(username, force_unidecode = True) == '': + if slugify(username) == '': raise forms.ValidationError(self.error_messages['meaningless']) try: user = self.db_model.objects.get( diff --git a/askbot/utils/slug.py b/askbot/utils/slug.py index 58f228da..f9e30cbf 100644 --- a/askbot/utils/slug.py +++ b/askbot/utils/slug.py @@ -5,30 +5,63 @@ the setting was added just in case - if people actually want to see unicode characters in the slug. If this is the choice slug will be simply equal to the input text """ +import re +import unicodedata from unidecode import unidecode -from django.template import defaultfilters + from django.conf import settings -import re +from django.template import defaultfilters +from django.utils.encoding import smart_unicode + + +# Extra characters outside of alphanumerics that we'll allow. +SLUG_OK = '-_~' + -def slugify(input_text, max_length=50, force_unidecode = False): +def unicode_slugify(s, ok=SLUG_OK, lower=True, spaces=False): + """Function copied from https://github.com/mozilla/unicode-slugify + because the author of the package never published it on pypi. + + Copyright notice below applies just to this function + Copyright (c) 2011, Mozilla Foundation + All rights reserved. + + L and N signify letter/number. + http://www.unicode.org/reports/tr44/tr44-4.html#GC_Values_Table + """ + rv = [] + for c in unicodedata.normalize('NFKC', smart_unicode(s)): + cat = unicodedata.category(c)[0] + if cat in 'LN' or c in ok: + rv.append(c) + if cat == 'Z': # space + rv.append(' ') + new = ''.join(rv).strip() + if not spaces: + new = re.sub('[-\s]+', '-', new) + return new.lower() if lower else new + + +def slugify(input_text, max_length=150): """custom slugify function that removes diacritic modifiers from the characters """ + if input_text == '': + return input_text + allow_unicode_slugs = getattr(settings, 'ALLOW_UNICODE_SLUGS', False) - if allow_unicode_slugs == False or force_unidecode == True: - if input_text == '': - return input_text - slug = defaultfilters.slugify(unidecode(input_text)) - while len(slug) > max_length: - # try to shorten word by word until len(slug) <= max_length - temp = slug[:slug.rfind('-')] - if len(temp) > 0: - slug = temp - else: - #we have nothing left, do not apply the last crop, - #apply the cut-off directly - slug = slug[:max_length] - break - return slug + if allow_unicode_slugs: + slug = unicode_slugify(input_text) else: - return re.sub(r'\s+', '-', input_text.strip().lower()) + slug = defaultfilters.slugify(unidecode(input_text)) + while len(slug) > max_length: + # try to shorten word by word until len(slug) <= max_length + temp = slug[:slug.rfind('-')] + if len(temp) > 0: + slug = temp + else: + #we have nothing left, do not apply the last crop, + #apply the cut-off directly + slug = slug[:max_length] + break + return slug diff --git a/askbot/views/meta.py b/askbot/views/meta.py index a92aec2b..e4209185 100644 --- a/askbot/views/meta.py +++ b/askbot/views/meta.py @@ -26,6 +26,8 @@ from askbot.utils import functions def generic_view(request, template = None, page_class = None): """this may be not necessary, since it is just a rewrite of render_into_skin""" + if request is None: # a plug for strange import errors in django startup + return render_to_response('django_error.html') return render_into_skin(template, {'page_class': page_class}, request) def config_variable(request, variable_name = None, mimetype = None): |