summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--askbot/doc/source/changelog.rst2
-rw-r--r--askbot/doc/source/settings.rst14
-rw-r--r--askbot/migrations/0124_auto__add_field_post_is_private__add_field_replyaddress_reply_action.py9
-rw-r--r--askbot/models/post.py2
-rw-r--r--askbot/models/question.py3
-rw-r--r--askbot/skins/default/media/images/OpenSans-CondBold.ttfbin0 -> 264372 bytes
-rw-r--r--askbot/skins/default/media/images/OpenSans-CondLight.ttfbin0 -> 221108 bytes
-rw-r--r--askbot/skins/default/media/images/OpenSans-CondLightItalic.ttfbin0 -> 210804 bytes
-rw-r--r--askbot/skins/default/templates/django_error.html31
-rw-r--r--askbot/skins/default/templates/meta/fonts.html16
-rw-r--r--askbot/tests/db_api_tests.py7
-rw-r--r--askbot/utils/forms.py2
-rw-r--r--askbot/utils/slug.py71
-rw-r--r--askbot/views/meta.py2
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
new file mode 100644
index 00000000..83966f21
--- /dev/null
+++ b/askbot/skins/default/media/images/OpenSans-CondBold.ttf
Binary files differ
diff --git a/askbot/skins/default/media/images/OpenSans-CondLight.ttf b/askbot/skins/default/media/images/OpenSans-CondLight.ttf
new file mode 100644
index 00000000..97c355b9
--- /dev/null
+++ b/askbot/skins/default/media/images/OpenSans-CondLight.ttf
Binary files differ
diff --git a/askbot/skins/default/media/images/OpenSans-CondLightItalic.ttf b/askbot/skins/default/media/images/OpenSans-CondLightItalic.ttf
new file mode 100644
index 00000000..0b45898d
--- /dev/null
+++ b/askbot/skins/default/media/images/OpenSans-CondLightItalic.ttf
Binary files differ
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):